I have three different provider which represent dev, stage & production.
I would like to specify the one I want by changing my workspace name to dev, stage or production.
like: terraform workspace new stage.
provider.tf file
provider “aws” {
profile = “ancestry-productiondata-prod”
region = “us-east-1”
alias = “production”
}
provider “aws” {
profile = “ancestry-l2-applications”
region = “us-east-1”
alias = “stage”
}
provider “aws” {
profile = “ancestry-l3-applications”
region = “us-east-1”
alias = “dev”
}
I can’t seem to get the provider part to work in my main.tf file
resource “aws_instance” “ec2_data_node” {
provider = aws.[terraform.workspace]
ami = “${data.aws_ami.latest-amazon-linux-arm.id}”
instance_type = var.instance_type_arm64[terraform.workspace]
count = var.instance_count[terraform.workspace]
key_name = var.key_name[terraform.workspace]
How can I accomplish this?
Hi @creynolds,
I would recommend to instead have only a single provider configuration and then change the details of that configuration based on workspace. Since only one of these configurations will be used in each workspace, it is inefficient to instantiate all three and then always ignore two of them.
Since it seems like only the profile varies, one way to do this would be to write out a map from workspace name to profile name, like this:
locals {
aws_profiles = tomap({
production = "ancestry-productiondata-prod"
stage = "ancestry-l2-applications"
dev = "ancestry-l3-applications"
})
}
Then you can set profile
in your provider block by accessing the appropriate element of this map:
provider "aws" {
profile = local.aws_profiles[terraform.workspace]
region = "us-east-1"
}
Notice that there’s no alias
in this block because this is declaring the default configuration for the provider. You will then not need to write explicit provider
arguments in your resource
blocks, because this detail of varying the profile by workspace is now encapsulated into the provider configuration itself.
OK, question. Is locals in my provider.tf or main.tf or is it in it’s own file?
I was able to get it to work by doing the following.
provider.tf
locals {
aws_profiles = tomap({
L1 = “ancestry-productiondata-prod”
L2 = “ancestry-l2-applications”
L3 = “ancestry-l3-applications”
})
}
provider “aws” {
profile = local.aws_profiles[terraform.workspace]
region = “us-east-1”
alias = “provider”
}
main.tf
resource “aws_instance” “ec2_data_node” {
provider = aws.provider
ami = “${data.aws_ami.latest-amazon-linux-arm.id}”
instance_type = var.instance_type_arm64[terraform.workspace]
count = var.instance_count[terraform.workspace]
key_name = var.key_name[terraform.workspace]
Terraform does not ascribe any meaning to your filenames; the filename conventions are there to make it easier for humans to find things. So the true answer is that you can place that locals
block in whatever file is most intuitive to you.
I personally would place it in the same file as the provider "aws"
block so that someone who is reading that provider configuration in future can easily find the table of profiles. That map presumably won’t be used in any other part of your configuration, so I can’t think of an advantage to placing it in a different file.
Thanks again.
I’m new to terraform. Our company has been using it for a long time in a pipline but I’m running it locally.
Can you point me to any really good terraform reference for learning the ins and outs of terraform?