如果愿意,如何将 Terraform 脚本用作 "common" 脚本、库或子例程?
How to use a Terraform script as a "common" script, a library or subroutine, if you will?
我看到了 ,但我有一个不同的场景(尽管 post 也很棒)。
在我的例子中,我有一个创建现货车队请求的脚本。我想使用这个通用脚本来创建多个现货车队请求。
provider "aws" {
region = var.region
}
terraform {
required_version = ">= 0.12.17, < 0.13.10"
}
resource "aws_spot_fleet_request" "jenkins_build_fleet" {
...
launch_specification {
...
}
}
我想要一个脚本有
terraform {
backend "s3" {
bucket = "my-terraform-remote-states"
key = "jenkins-qa/terraform.tfstate"
region = "us-east-1"
}
}
...另一个要有
terraform {
backend "s3" {
bucket = "my-terraform-remote-states"
key = "jenkins-slaves/terraform.tfstate"
region = "us-east-1"
}
}
IOW,每个脚本仅在其远程状态密钥上有所不同,因此当我 apply/destroy 他们各自的计划时,他们将创建自己的现货车队请求,而不会影响任何其他现货车队请求。我希望能够 运行 每个具体脚本而不必指定 -target
参数,这意味着我不想将所有 3 个脚本都放在同一目录中。理想情况下,我希望文件结构为
/path/common_script.tf
/path/script1/script1.tf
/path/script2/script2.tf
有办法吗?
IOW, each script only differs in its remote state key
那么这两个文件中到底是什么?
/path/script1/script1.tf
/path/script2/script2.tf
如果它们只包含您所展示的后端配置,那么它们就是多余的。在 Terraform 中,目录是一个可以重复使用的 'module',所以如果你愿意,你可以将 'common script' 放在一个模块中,但我不建议在这种简单的情况下使用它。
无论如何,要回答您的问题,您可以使用 partial backend configuration to support multiple backends. Just pass -backend-config <backend-config-file>
to your terraform init
command. For setting up the backend config file see these docs。
对于这类事情,我建议使用 Terraform Workspaces。 S3 后端提供程序支持工作区,并将在 S3 中创建一个单独的“文件夹”来存储每个工作区的状态文件。
我已经成功地使用它来部署具有相同 Terraform 文件的 dev/test/prod 环境。你只需要 运行 terraform workspace select
before 运行ning terraform apply
我还要说,Terraform 中“公共”库的概念更符合 Terraform Modules 解决的问题。虽然您的问题更多是关于如何让 Terraform 托管资源的多个实例具有多个状态文件,这是 Workspaces 解决的问题。
编辑更多详细信息:
您可以像这样拥有一个 Terraform 模板文件:
provider "aws" {
region = var.region
}
terraform {
required_version = ">= 0.12.17, < 0.13.10"
}
resource "aws_spot_fleet_request" "jenkins_build_fleet" {
...
launch_specification {
...
}
}
terraform {
backend "s3" {
bucket = "my-terraform-remote-states"
key = "jenkins/terraform.tfstate"
region = "us-east-1"
}
}
然后像这样应用一次:
terraform workspace select jenkins_qa
terraform apply
然后像这样再次应用它:
terraform workspace select jenkins_slaves
terraform apply
这将导致两组单独的资源部署到 AWS,在您的 S3 存储桶中有两个单独的状态文件,以工作区名称为前缀,根本不需要求助于任何重复代码。
或者,如果您想保持当前的文件和文件夹分隔:
您可以在 /common
文件夹中有一个 Terraform 模块,如下所示:
provider "aws" {
region = var.region
}
terraform {
required_version = ">= 0.12.17, < 0.13.10"
}
resource "aws_spot_fleet_request" "jenkins_build_fleet" {
...
launch_specification {
...
}
}
然后您的 /script1
文件夹中可以有一个 Terraform 模板,如下所示:
terraform {
backend "s3" {
bucket = "my-terraform-remote-states"
key = "jenkins-qa/terraform.tfstate"
region = "us-east-1"
}
}
module "common" {
source = "../common"
}
并在不同的工作区多次应用此 /script1
模板,或将其复制到指向不同状态文件的单独模板中。如果重复代码的唯一区别是状态文件的名称,那么您绝对可以通过使用工作区来消除重复。
您提到您认为输出是模块的要求,但事实并非如此。但是,您可以从模块输出类似于 spot_bid_status
值的内容,然后从主模板再次输出它,例如在 apply
之后将其打印到屏幕上。
我看到了
在我的例子中,我有一个创建现货车队请求的脚本。我想使用这个通用脚本来创建多个现货车队请求。
provider "aws" {
region = var.region
}
terraform {
required_version = ">= 0.12.17, < 0.13.10"
}
resource "aws_spot_fleet_request" "jenkins_build_fleet" {
...
launch_specification {
...
}
}
我想要一个脚本有
terraform {
backend "s3" {
bucket = "my-terraform-remote-states"
key = "jenkins-qa/terraform.tfstate"
region = "us-east-1"
}
}
...另一个要有
terraform {
backend "s3" {
bucket = "my-terraform-remote-states"
key = "jenkins-slaves/terraform.tfstate"
region = "us-east-1"
}
}
IOW,每个脚本仅在其远程状态密钥上有所不同,因此当我 apply/destroy 他们各自的计划时,他们将创建自己的现货车队请求,而不会影响任何其他现货车队请求。我希望能够 运行 每个具体脚本而不必指定 -target
参数,这意味着我不想将所有 3 个脚本都放在同一目录中。理想情况下,我希望文件结构为
/path/common_script.tf
/path/script1/script1.tf
/path/script2/script2.tf
有办法吗?
IOW, each script only differs in its remote state key
那么这两个文件中到底是什么?
/path/script1/script1.tf
/path/script2/script2.tf
如果它们只包含您所展示的后端配置,那么它们就是多余的。在 Terraform 中,目录是一个可以重复使用的 'module',所以如果你愿意,你可以将 'common script' 放在一个模块中,但我不建议在这种简单的情况下使用它。
无论如何,要回答您的问题,您可以使用 partial backend configuration to support multiple backends. Just pass -backend-config <backend-config-file>
to your terraform init
command. For setting up the backend config file see these docs。
对于这类事情,我建议使用 Terraform Workspaces。 S3 后端提供程序支持工作区,并将在 S3 中创建一个单独的“文件夹”来存储每个工作区的状态文件。
我已经成功地使用它来部署具有相同 Terraform 文件的 dev/test/prod 环境。你只需要 运行 terraform workspace select
before 运行ning terraform apply
我还要说,Terraform 中“公共”库的概念更符合 Terraform Modules 解决的问题。虽然您的问题更多是关于如何让 Terraform 托管资源的多个实例具有多个状态文件,这是 Workspaces 解决的问题。
编辑更多详细信息:
您可以像这样拥有一个 Terraform 模板文件:
provider "aws" {
region = var.region
}
terraform {
required_version = ">= 0.12.17, < 0.13.10"
}
resource "aws_spot_fleet_request" "jenkins_build_fleet" {
...
launch_specification {
...
}
}
terraform {
backend "s3" {
bucket = "my-terraform-remote-states"
key = "jenkins/terraform.tfstate"
region = "us-east-1"
}
}
然后像这样应用一次:
terraform workspace select jenkins_qa
terraform apply
然后像这样再次应用它:
terraform workspace select jenkins_slaves
terraform apply
这将导致两组单独的资源部署到 AWS,在您的 S3 存储桶中有两个单独的状态文件,以工作区名称为前缀,根本不需要求助于任何重复代码。
或者,如果您想保持当前的文件和文件夹分隔:
您可以在 /common
文件夹中有一个 Terraform 模块,如下所示:
provider "aws" {
region = var.region
}
terraform {
required_version = ">= 0.12.17, < 0.13.10"
}
resource "aws_spot_fleet_request" "jenkins_build_fleet" {
...
launch_specification {
...
}
}
然后您的 /script1
文件夹中可以有一个 Terraform 模板,如下所示:
terraform {
backend "s3" {
bucket = "my-terraform-remote-states"
key = "jenkins-qa/terraform.tfstate"
region = "us-east-1"
}
}
module "common" {
source = "../common"
}
并在不同的工作区多次应用此 /script1
模板,或将其复制到指向不同状态文件的单独模板中。如果重复代码的唯一区别是状态文件的名称,那么您绝对可以通过使用工作区来消除重复。
您提到您认为输出是模块的要求,但事实并非如此。但是,您可以从模块输出类似于 spot_bid_status
值的内容,然后从主模板再次输出它,例如在 apply
之后将其打印到屏幕上。