I have an infrastructure I'm deploying using Terraform in AWS. This infrastructure can be deployed to different environments, for which I'm using workspaces.
Most of the components in the deployment should be created separately for each workspace, but I have several key components that I wish to be shared between them, primarily:
For example:
resource "aws_iam_role" "lambda_iam_role" { name = "LambdaGeneralRole" policy = <...> } resource "aws_lambda_function" "my_lambda" { function_name = "lambda-${terraform.workspace}" role = "${aws_iam_role.lambda_iam_role.arn}" }
The first resource is a IAM role that should be shared across all instances of that Lambda, and shouldn't be recreated more than once.
The second resource is a Lambda function whose name depends on the current workspace, so each workspace will deploy and keep track of the state of a different Lambda.
How can I share resources, and their state, between different Terraform workspaces?
For the shared resources, I create them in a separate template and then refer to them using terraform_remote_state
in the template where I need information about them.
What follows is how I implement this, there are probably other ways to implement it. YMMV
In the shared services template (where you would put your IAM role) I use Terraform backend to store the output data for the shared services template in Consul. You also need to output
any information you want to use in other templates.
shared_services template
terraform { backend "consul" { address = "consul.aa.example.com:8500" path = "terraform/shared_services" } } resource "aws_iam_role" "lambda_iam_role" { name = "LambdaGeneralRole" policy = <...> } output "lambda_iam_role_arn" { value = "${aws_iam_role.lambda_iam_role.arn}" }
A "backend" in Terraform determines how state is loaded and how an operation such as apply is executed. This abstraction enables non-local file state storage, remote execution, etc.
In the individual template you invoke the backend as a data source using terraform_remote_state
and can use the data in that template.
terraform_remote_state
:
Retrieves state meta data from a remote backend
individual template
data "terraform_remote_state" "shared_services" { backend = "consul" config { address = "consul.aa.example.com:8500" path = "terraform/shared_services" } } # This is where you use the terraform_remote_state data source resource "aws_lambda_function" "my_lambda" { function_name = "lambda-${terraform.workspace}" role = "${data.terraform_remote_state.shared_services.lambda_iam_role_arn}" }
References:
https://www.terraform.io/docs/state/remote.html
https://www.terraform.io/docs/backends/
https://www.terraform.io/docs/providers/terraform/d/remote_state.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With