Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use dynamic resource names in Terraform?

Tags:

I would like to use the same terraform template for several dev and production environments.

My approach: As I understand it, the resource name needs to be unique, and terraform stores the state of the resource internally. I therefore tried to use variables for the resource names - but it seems to be not supported. I get an error message:

$ terraform plan var.env1   Enter a value: abc  Error asking for user input: Error parsing address 'aws_sqs_queue.SqsIntegrationOrderIn${var.env1}': invalid resource address "aws_sqs_queue.SqsIntegrationOrderIn${var.env1}" 

My terraform template:

variable "env1" {}  provider "aws" {         region = "ap-southeast-2" }  resource "aws_sqs_queue" "SqsIntegrationOrderIn${var.env1}" {         name = "Integration_Order_In__${var.env1}"         message_retention_seconds = 86400         receive_wait_time_seconds = 5 } 

I think, either my approach is wrong, or the syntax. Any ideas?

like image 752
hey Avatar asked Sep 21 '17 21:09

hey


People also ask

How do you name resources in Terraform?

Resource names are nouns, since resource blocks each represent a single object Terraform is managing. Resource names must always start with their containing provider's name followed by an underscore, so a resource from the provider postgresql might be named postgresql_database .

What is one disadvantage of using dynamic blocks in Terraform?

Overuse of dynamic blocks can make configuration hard to read and maintain, so we recommend using them only when you need to hide details in order to build a clean user interface for a re-usable module. Always write nested blocks out literally where possible.


2 Answers

You can't interpolate inside the resource name. Instead what you should do is as @BMW have mentioned in the comments, you should make a terraform module that contains that SqsIntegrationOrderIn inside and takes env variable. Then you can use the module twice, and they simply won't clash. You can also have a look at a similar question I answered.

like image 170
Farid Nouri Neshat Avatar answered Sep 29 '22 13:09

Farid Nouri Neshat


I recommend using a different workspace for each environment. This allows you to specify your configuration like this:

variable "env1" {}  provider "aws" {         region = "ap-southeast-2" }  resource "aws_sqs_queue" "SqsIntegrationOrderIn" {         name = "Integration_Order_In__${var.env1}"         message_retention_seconds = 86400         receive_wait_time_seconds = 5 } 

Make sure to make the name of the "aws_sqs_queue" resource depending on the environment (e.g. by including it in the name) to avoid name conflicts in AWS.

like image 42
bitbrain Avatar answered Sep 29 '22 14:09

bitbrain