One of the big challenges is how to organize your cloud account setup.
In one account, you can have a couple of application stacks. The challenge is to able fast to apply/plan/destroy them without any burden.
What works for me is to use one application-terraform-bulk.sh script which will know which modules to which stacks belong. And if I have a couple of modules to apply in the application stack I use terraform-bulk.sh script which just applies all modules in the current folder.
Here is an example.
Those are the ECR modules which must be presented in this account. I do not care about which stack will own them, so I will use the general terraform_bulk.sh script
The commands which I can do are:
./terraform_bulk.sh init
# ...It will go in each folder and do terraform init
./terraform_bulk.sh plan
# ...It will go in each folder and do terraform plan
./terraform_bulk.sh apply
./terraform_bulk.sh destroy
Here is how it looks the script
#!/bin/bash
trap "exit" INT
modules=(
anaconda
essential
essential-anaconda-environment
)
terraform_plan() {
local project="$1"
pushd .
cd $project
terraform plan
popd
}
terraform_init() {
local project="$1"
pushd .
cd $project
terraform init
popd
}
terraform_apply() {
local project="$1"
pushd .
cd $project
terraform apply -auto-approve
popd
}
terraform_destroy() {
local project="$1"
pushd .
cd $project
terraform destroy -auto-approve
popd
}
terraform_show() {
local project="$1"
pushd .
cd $project
terraform show
popd
}
# array=(1 2 3 4)
# reverse array foo
# echo "${foo[@]}"
reverse() {
# first argument is the array to reverse
# second is the output array
declare -n arr="$1" rev="$2"
for project in "${arr[@]}"
do
rev=("$project" "${rev[@]}")
done
}
case "$1" in
init)
for project in "${modules[@]}"
do
echo ""
echo ""
echo $project
terraform_init $project
done
;;
show)
for project in "${modules[@]}"
do
echo ""
echo ""
echo $project
terraform_show $project
done
;;
apply)
for project in "${modules[@]}"
do
echo ""
echo ""
echo $project
terraform_apply $project
done
;;
destroy)
reverse modules reversed_modules
for project in "${reversed_modules[@]}"
do
echo ""
echo ""
echo $project
terraform_destroy $project
done
;;
plan)
reverse modules reversed_modules
for project in "${reversed_modules[@]}"
do
echo ""
echo ""
echo $project
terraform_plan $project
done
;;
*)
echo $"Usage: $0 {init|apply|destroy}"
exit 1
esac
In my case in the development cloud account, I have to host two applications. Then I just create two versions of the script like this.
wxr-xr-x 13 guda guda 4096 Nov 15 13:20 .
drwxr-xr-x 6 guda guda 4096 Nov 5 11:20 ..
drwxr-xr-x 3 guda guda 4096 Oct 28 18:14 athena
drwxr-xr-x 3 guda guda 4096 Jul 10 15:17 cm
drwxr-xr-x 5 guda guda 4096 Dec 5 22:42 ecr
drwxr-xr-x 11 guda guda 4096 Oct 28 18:39 endpoints
-rwxr-xr-x 1 guda guda 2345 Oct 28 18:38 essential-terraform_bulk.sh <<<<<
-rwxr-xr-x 1 guda guda 2190 Oct 28 18:14 etl_monitoring-terraform_bulk.sh <<<<<
drwxr-xr-x 3 guda guda 4096 Nov 5 11:24 fargate_essential
drwxr-xr-x 3 guda guda 4096 Oct 28 18:47 rds
drwxrwxr-x 3 guda guda 4096 Sep 3 19:48 s3
drwxr-xr-x 5 guda guda 4096 Oct 28 18:47 secret_manager
drwxr-xr-x 3 guda guda 4096 Aug 15 17:02 vpc
drwxr-xr-x 4 guda guda 4096 Nov 15 13:20 vpc_peering
drwxr-xr-x 3 guda guda 4096 Aug 19 14:51 zone_security_groups
So when I want to provision:
- essential app – use essential-terraform_bulk.sh
- etl monitoring app – use etl_monitoring-terraform_bulk.sh
Be aware when you have to share the resources – for example vpc, you do not want the first terraform-bulk.sh to drop a resource which is needed by the second application terraform bulk.