在Terraform工作空间之间共享资源

时间:2018-10-02 09:55:16

标签: amazon-web-services terraform devops terraform-provider-aws

我拥有要在AWS中使用Terraform部署的基础架构。该基础架构可以部署到我正在使用工作空间的不同环境中。

部署中的大多数组件应为每个工作区分别创建,但我希望在它们之间共享几个关键组件,主要是:

  • IAM角色和权限
  • 它们应使用相同的API网关,但每个工作区应部署到不同的路径和方法

例如:

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}"
}

第一个资源是IAM角色,应在该Lambda的所有实例之间共享,并且不应重复创建一次。

第二个资源是Lambda函数,其名称取决于当前的工作空间,因此每个工作空间将进行部署并跟踪不同Lambda的状态。

如何在不同的Terraform工作空间之间共享资源及其状态?

2 个答案:

答案 0 :(得分:5)

对于共享资源,我在单独的模板中创建它们,然后在需要有关它们的信息的模板中使用terraform_remote_state对其进行引用。

接下来是我如何实现它,可能还有其他方法可以实现它。 YMMV

在共享服务模板(您将在其中放置IAM角色)中,我使用Terraform后端将共享服务模板的输出数据存储在Consul中。您还需要output要在其他模板中使用的任何信息。

share_services模板

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}"
}
  

Terraform中的“后端”确定如何加载状态以及如何执行诸如apply之类的操作。这种抽象可以实现非本地文件状态存储,远程执行等。

在单个模板中,您可以使用terraform_remote_state将后端作为数据源调用,并可以使用该模板中的数据。

terraform_remote_state

  

从远程后端检索状态元数据

个人模板

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}"
}

参考

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

答案 1 :(得分:0)

如果aws_iam_role值与已配置的资源匹配,则具有name属性的资源name不会创建新实例。

因此,以下内容将创建一个名为 aws_iam_role LambdaGeneralRole

resource "aws_iam_role" "lambda_iam_role" {
  name = "LambdaGeneralRole"
  policy = <...>
}

...

resource "aws_iam_role" "lambda_iam_role_reuse_existing_if_name_is_LambdaGeneralRole" {
  name = "LambdaGeneralRole"
  policy = <...>
}

类似地,在以下情况下,aws提供者将有效地创建一个S3 bucket名称​​ my-store

resource "aws_s3_bucket" "store-1" {
  bucket        = "my-store"
  acl           = "public-read"
  force_destroy = true
}

...

resource "aws_s3_bucket" "store-2" {
  bucket        = "my-store"
  acl           = "public-read"
  force_destroy = true
}

即使资源被定义为具有各自独立的Terraform状态的不同工作空间,此行为仍然成立。


要充分利用此方法,请将共享资源定义为单独的配置。这样一来,您运行terraform destroy后就不会有破坏共享资源的风险。