在 Terraform 工作区之间共享资源
Sharing resources between Terraform workspaces
我在 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 工作区之间共享资源及其状态?
对于共享资源,我在单独的模板中创建它们,然后在需要有关它们的信息的模板中使用 terraform_remote_state
引用它们。
下面是我的实现方式,可能还有其他实现方式。 YMMV
在共享服务模板(您将放置 IAM 角色的位置)中,我使用 Terraform 后端在 Consul 中存储共享服务模板的输出数据。您还需要 output
要在其他模板中使用的任何信息。
shared_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}"
}
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.
在单独的模板中,您可以使用 terraform_remote_state
调用后端作为数据源,并可以使用该模板中的数据。
terraform_remote_state
:
Retrieves state meta data from a remote backend
个人模板
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
如果 name
值与已配置的资源匹配,则具有 name
属性的 aws_iam_role
等资源将不会创建新实例。
因此,下面将创建一个名为 LambdaGeneralRole
.
的单个 aws_iam_role
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
.
之后冒险破坏共享资源
我在 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 工作区之间共享资源及其状态?
对于共享资源,我在单独的模板中创建它们,然后在需要有关它们的信息的模板中使用 terraform_remote_state
引用它们。
下面是我的实现方式,可能还有其他实现方式。 YMMV
在共享服务模板(您将放置 IAM 角色的位置)中,我使用 Terraform 后端在 Consul 中存储共享服务模板的输出数据。您还需要 output
要在其他模板中使用的任何信息。
shared_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}"
}
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.
在单独的模板中,您可以使用 terraform_remote_state
调用后端作为数据源,并可以使用该模板中的数据。
terraform_remote_state
:
Retrieves state meta data from a remote backend
个人模板
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
如果 name
值与已配置的资源匹配,则具有 name
属性的 aws_iam_role
等资源将不会创建新实例。
因此,下面将创建一个名为 LambdaGeneralRole
.
aws_iam_role
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
.