Terraform 如何使用地形脚本作为;普通的;脚本、库或子例程,如果愿意的话?

Terraform 如何使用地形脚本作为;普通的;脚本、库或子例程,如果愿意的话?,terraform,terraform-provider-aws,Terraform,Terraform Provider Aws,我明白了,但我有一个不同的场景(尽管那篇文章也很棒) 在我的例子中,我有一个脚本,它创建了一个spot车队请求。我想使用这个通用脚本来创建多个spot fleet请求 provider "aws" { region = var.region } terraform { required_version = ">= 0.12.17, < 0.13.10" } resource "aws_spot_fleet_request&

我明白了,但我有一个不同的场景(尽管那篇文章也很棒)

在我的例子中,我有一个脚本,它创建了一个spot车队请求。我想使用这个通用脚本来创建多个spot fleet请求

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-slaves/terraform.tfstate"
    region = "us-east-1"
  }
}
注意,每个脚本的远程状态密钥不同,因此当我应用/销毁它们各自的计划时,它们将创建自己的spot fleet请求,而不会影响任何其他spot fleet请求。我希望能够运行每个具体脚本,而不必指定
-target
参数,这意味着我不希望所有3个脚本都在同一个目录中。理想情况下,我希望文件结构是

/path/common_script.tf
/path/script1/script1.tf
/path/script2/script2.tf
有办法做到这一点吗

照此,每个脚本只在其远程状态键上有所不同

那么这两个文件中到底是什么呢

/path/script1/script1.tf
/path/script2/script2.tf
如果它们包含的只是像您所示的后端配置,那么它们是冗余的。在Terraform中,目录是一个可以重用的“模块”,因此如果您愿意,可以将您的“公共脚本”放在一个模块中,但对于这种简单的情况,我不推荐使用它

无论如何,要回答您的问题,您可以使用来支持多个后端。只需将
-backend config
传递给您的
terraform init
命令。有关设置后端配置文件的信息,请参阅。

我建议使用。S3后端提供程序支持工作区,并将在S3中创建一个单独的“文件夹”,以存储每个工作区的状态文件

我用它成功地部署了具有相同地形文件的dev/test/prod环境。在运行
terraform apply


我还想说,在地形中建立一个“公共”库的概念更符合解决问题的思路。而您的问题更多的是关于如何使用多个状态文件创建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
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"
  }
}

module "common" {
  source = "../common"
}
然后像这样再次应用它:

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

module "common" {
  source = "../common"
}
这将导致两组独立的资源部署到AWS,在S3存储桶中有两个独立的状态文件,以工作区名称为前缀,而不必求助于任何重复的代码

或者,如果您希望保持当前的文件和文件夹分离:

您可以在
/common
文件夹中创建一个地形模块,如下所示:

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

module "common" {
  source = "../common"
}
并在不同的工作空间中多次应用此
/script1
模板,或者将其复制到指向不同状态文件的单独模板中。如果复制代码的唯一区别是状态文件的名称,那么您完全可以通过使用工作区来消除这种重复


您提到您认为输出是模块的一项要求,但事实并非如此。但是,您可以从模块中输出类似于
spot\u bid\u status
的值,然后从主模板中再次输出,以便在应用
后将其打印到屏幕上。

因为克隆总是不好的!这就是我现在拥有的。如果我需要改变,我必须在两个地方做。虽然我喜欢
--backend config
技巧,但这意味着我和其他用户必须记住配置文件的名称,并且很容易键入错误的名称。那么Terraform工作区如何解决没有克隆代码的问题呢?请更新您关于使用工作区时目录树的外观的答案。谢谢另外,如果我理解正确,模块实际上有其他脚本可以使用的输出。例如,我可能有一个“专有网络”模块创建我的专有网络,然后其他模块可以使用。在我的例子中,“公共”代码不会产生输出。谢谢我指出了模块,因为这就是terraform“公共库”通常是什么。我想说的是,您正在尝试应用“公共库”概念,但您的用例听起来更像是一个需要运行两次的Terraform配置,使用两个单独的状态文件。这并不是一个真正的“公共库”,而是一个由Terraform模板描述的单一基础设施配置,它被两次应用于您的AWS帐户。这听起来很像Terraform工作区。@ChrisF我在回答中添加了其他示例。谢谢!这就是我需要的答案。我可能会得到两个单独的脚本,只在状态文件中有所不同,因此包括我在内的任何人都不必记住它们的名称。terraform不支持
后端
配置中的变量。否则,使用指向每个环境的公共模块&tfvars就可以轻松地完成。