Amazon web services 地形远程状态

Amazon web services 地形远程状态,amazon-web-services,terraform,Amazon Web Services,Terraform,我们正在尝试使用terraform,远程状态存储在S3中 这些项目正在被打破,例如“主”VPC项目,它只创建网络基础设施(VPC、子网、IGW、NAT、路由等),以及子项目,在主VPC(子网)之上创建特定资源,即ec2节点 项目文件夹/文件: . ├── modules/ │ └── mod-vpc/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── projects/ │ └── top-le

我们正在尝试使用terraform,远程状态存储在S3中

这些项目正在被打破,例如“主”VPC项目,它只创建网络基础设施(VPC、子网、IGW、NAT、路由等),以及子项目,在主VPC(子网)之上创建特定资源,即ec2节点

项目文件夹/文件:

.
├── modules/
│   └── mod-vpc/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── projects/
│   └── top-level-project-name-goes-here/
│       ├── env-dev/
│       │   ├── globals.tf
│       │   ├── test/
│       │   │   ├── main.tf
│       │   │   └── variables.tf
│       │   └── vpc/
│       │       ├── main.tf
│       │       └── variables.tf
│       └── env-prod/
└── terraform.tfvars
除专有网络项目外,所有其他项目均使用专有网络远程状态的专有网络id、CIDR等。 以下是如何定义我们的流程:

步骤1:创建专有网络。

此处无问题,创建专有网络,打印输出并存储到S3存储桶:

$ terraform init -backend=s3 -backend-config="region= us-west-2" -backend-config="bucket=xxx"  -backend-config="key=xxx" -backend-config="acl=bucket-owner-full-control" $project_path
$ terraform remote pull
$ terraform get $project_path
$ terraform apply

步骤2:创建其他资源组: 使用VPC远程状态的输出值,尝试将ec2节点部署到已配置的公共子网(上述步骤1中的VPC项目输出)。以下是脚本运行的步骤/命令(首先,我们将所有文件复制到/tmp/project/working文件夹,并在此文件夹中执行脚本):

/tmp/项目/文件夹内容:

以下是项目文件结构的外观(在/tmp/project/folder中):

以下是此项目的main.tf文件的外观:

resource "aws_instance" "test" {
  instance_type = "${var.instance_type}"
  ami = "${var.ami}"
  subnet_id = "${data.terraform_remote_state.vpc_main.public_subnet_ids}" 
  vpc_security_group_ids = ["${aws_security_group.http_ext.id}"]    
}
以下是上述data.terraform_remote_状态资源的定义:

data "terraform_remote_state" "vpc_main" {
  backend = "s3"
  config {
    region = "us-west-2"
    bucket = "xxx"
    key    = "xxx/vpc.json"
  }
}
根据我们声明“data.terraform\u remote\u state.vpc\u main”资源的位置(哪个文件),我们得到了不同的结果:

选项1。 如果我们在“test”项目(=main.tf)的同一个文件中声明了“data.terraform\u remote\u state”,那么一切都会成功执行

选项2。 如果我们将data.terraform_remote_state.vpc_main移动到一个单独的文件(=“globals.tf”),则在执行[terraform get$project_path]步骤时会出现此错误:

指出Terraform由于某种原因无法解析此数据。Terraform_remote_state.vpc_主要资源

选项3。 但出于测试目的,当我们同时启用这两个声明(在“globals.tf”和“main.tf”中)时,我们在执行[terraform apply]步骤时会出现以下错误:

这是一个有效的错误,因为我们现在在两个地方定义了相同的资源

但是为什么Terraform不能正确地解析这个资源,当我们试图把它放到上面选项2下的一个单独的文件中时

根据terraform文档,所有*.tf文件都按字母顺序加载和附加,资源声明顺序无关紧要,因为terraform配置是声明性的:

但上述情况似乎并非如此


我们可以在这里使用“硬编码”方法,但Terraform中是否有一种“合法”的方法来实现这一点?

尝试使用该命令来设置远程状态:

terraform_bucket_region='eu-west-1'
terraform_bucket_name='xxx'
terraform_file_name="terraform.tfstate"

export AWS_ACCESS_KEY_ID="xxx"
export AWS_SECRET_ACCESS_KEY="xxx"

[ -d .terraform ] && rm -rf .terraform
[ -f terraform.tfstate.backup ] && rm terraform.tfstate.backup
terraform remote config -backend=S3 -backend-config="region=${terraform_bucket_region}" -backend-config="bucket=${terraform_bucket_name}" -backend-config="key=${terraform_file_name}"
terraform get

我已经将它设置为一个shell脚本,名为
setremotetf.sh

我已经使用TerraformRemoteState一段时间了。 我认为您的问题是组织对地形状态依赖性的问题

您应该为每个文件夹运行terraform。并且每个都有一个config.tf

.
├── modules/
│   └── mod-vpc/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── projects/
│   └── top-level-project-name-goes-here/
│       ├── env-dev/
│       │   ├── globals.tf
│       │   ├── test/
|       |   |   |-- config.tf
│       │   │   ├── main.tf
│       │   │   └── variables.tf
|       |   |   |-- terraform.tfvars
│       │   └── vpc/
|       |       |-- config.tf
│       │       ├── main.tf
│       │       └── variables.tf
|       |       |-- terraform.tfvars
│       └── env-prod/


您可以在这里查看“步骤1:创建专有网络”中的GCP示例

。您在哪个目录中?是
项目/顶级项目名称在这里/env dev/vpc/
projects/顶级项目名称中的模块“cassandra”是否在这里/env dev/test
?在任何步骤中,我们的包装外壳脚本都会将当前“目标”项目(无论是VPC还是cassandra或其他)的内容复制到tmp/项目文件夹中,并成为工作目录,对于VPC,它类似于:步骤1:a)
cp projects/../VPC/*./tmp/project/
,然后b)
cd/tmp/projects
,之后我们首先获得地形远程状态,然后执行相应的
地形计划|应用|销毁
。所以我们从顶部开始,但工作文件夹是
/tmp/project
。我会检查terraform\u remote\u state数据源中的bucket密钥。至少对于我们的东西来说,文件名是“terraform.tfstate”,而不是类似于“.json”的东西。当然,钥匙和桶是不同的东西,我猜你只是把“xxx”放在里面,不给我们钥匙和桶的名字。
data "terraform_remote_state" "vpc_main" {
  backend = "s3"
  config {
    region = "us-west-2"
    bucket = "xxx"
    key    = "xxx/vpc.json"
  }
}
$ terraform init -backend=s3 -backend-config="region= us-west-2" -backend-config="bucket=xxx"  -backend-config="key=xxx" -backend-config="acl=bucket-owner-full-control" $project_path
$ terraform remote pull
$ terraform get $project_path

Error loading Terraform: module root: 4 error(s) occurred:

* module 'cassandra': unknown resource 'data.terraform_remote_state.vpc_main' referenced in variable data.terraform_remote_state.vpc_main.cidr_block
* module 'cassandra': unknown resource 'data.terraform_remote_state.vpc_main' referenced in variable data.terraform_remote_state.vpc_main.region
* module 'cassandra': unknown resource 'data.terraform_remote_state.vpc_main' referenced in variable data.terraform_remote_state.vpc_main.vpc_id
* module 'cassandra': unknown resource 'data.terraform_remote_state.vpc_main' referenced in variable data.terraform_remote_state.vpc_main.public_subnet_ids
$ terraform init -backend=s3 -backend-config="region= us-west-2" -backend-config="bucket=xxx"  -backend-config="key=xxx" -backend-config="acl=bucket-owner-full-control" $project_path
$ terraform remote pull
$ terraform get $project_path
$ terraform apply

module root: 1 error(s) occurred:
2017/01/14 14:02:50 [DEBUG] plugin: waiting for all plugin processes to complete...

•   data.terraform_remote_state.vpc_main: resource repeated multiple times
terraform_bucket_region='eu-west-1'
terraform_bucket_name='xxx'
terraform_file_name="terraform.tfstate"

export AWS_ACCESS_KEY_ID="xxx"
export AWS_SECRET_ACCESS_KEY="xxx"

[ -d .terraform ] && rm -rf .terraform
[ -f terraform.tfstate.backup ] && rm terraform.tfstate.backup
terraform remote config -backend=S3 -backend-config="region=${terraform_bucket_region}" -backend-config="bucket=${terraform_bucket_name}" -backend-config="key=${terraform_file_name}"
terraform get
.
├── modules/
│   └── mod-vpc/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── projects/
│   └── top-level-project-name-goes-here/
│       ├── env-dev/
│       │   ├── globals.tf
│       │   ├── test/
|       |   |   |-- config.tf
│       │   │   ├── main.tf
│       │   │   └── variables.tf
|       |   |   |-- terraform.tfvars
│       │   └── vpc/
|       |       |-- config.tf
│       │       ├── main.tf
│       │       └── variables.tf
|       |       |-- terraform.tfvars
│       └── env-prod/

# ../vpc/config.tf
terraform {
  backend "s3" {
    bucket = "my-infrastructure"
    prefix = "vpc"
  }
}
# ../test
terraform {
  backend "s3" {
    bucket = "my-infrastructure"
    prefix = "test"
  }
}

data "terraform_remote_state" "vpc_main" {
  backend   = "s3"
  # workspace = "${terraform.workspace}" // optional

  config {
    bucket = "my-infrastructure"
    prefix = "vpc"
  }
}

data "terraform_remote_state" "other_terraform_state" {
  backend   = "s3"
  workspace = "${terraform.workspace}"

  config {
    bucket = "my-infrastructure"
    prefix = "other_terraform_state"
  }
}