Terraform official best pratice with modules and for_each?

172 Views Asked by At

I need to create about 150 AWS ECR repositories via Terraform (which I'm quite new to). I've created a little module which will make the repo and assign the policy i want to it.

My question is whether it's best practice to have the module accept a name as a variable and creates a single repo, and have code outside the module that has a for_each over an array of repo names, or have the module take in a list of repo names, and have the for_each loop itself.

1

There are 1 best solutions below

1
On BEST ANSWER

I would recommend your first option: "have the module accept a name as a variable and creates a single repo." You mentioned your module will create a repo and assign a policy to it. So you will likely have, at least, an aws_ecr_repository resource and an aws_ecr_repository_policy resource managed by your module. If you use your second option, and instead pass in a list of repo names to your module, then you will need to loop over your list of module names twice: once to make all of the aws_ecr_repository resources and once to make all of the aws_ecr_repository_policy resources. Now suppose you later realize you need to output something about each aws_ecr_repository from your module - yet again, you need to loop over your list of repo names to create the output. You can avoid all of those loops and keep your code DRY by keeping the list of repo names external to the module.

With your second option you could also run into future issues with targeting one repo by name. Suppose you want to do a terraform apply and change one repo's policy. If you instantiate your module once for each repo name, and your module is called my_repo, and the repo name is frontend, then you might do:

terraform apply -target module.my_repo["frontend"]

If, however, you pass the repo names in to your module, then depending on the situation, you might have to do something like this:

terraform apply -target module.my_repo.aws_ecr_repository["frontend"] -target module.my_repo.aws_ecr_repository_policy["frontend"]

Things get more complicated if you pass in the repo names as a variable, instead of instantiating your module once for each repo name.