首页 文章

地形远程状态

提问于
浏览
5

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

项目正在被打破,例如有“主”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

除了VPC项目之外,所有其他项目都使用来自远程VPC状态的vpc_id,CIDR等 . 以下是我们的流程定义方式:

Step 1: Create VPC.

这里没有问题,VPC被创建,输出打印出来并存储到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

...

Outputs:

cidr_block = 10.198.0.0/16
private_subnet_ids = subnet-d3f5029a,subnet-fbeb369c,subnet-7ad88622
public_subnet_ids = subnet-54f5021d
region = us-west-2
vpc_id = vpc-b31ca3d4
vpc_name = main_vpc

Step 2: Create other resource groups :使用VPC远程状态的输出值,尝试将ec2节点部署到已配置的公共子网(上面步骤1中的VPC项目输出) . 以下是我们的脚本运行的步骤/命令(首先我们将所有文件复制到/ tmp / project / working文件夹,脚本在此文件夹中执行):

$ 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

/ tmp / project /文件夹内容:

以下是项目文件结构的样子(在/ tmp / project /文件夹中):

├── .terraform
│   ├── modules
│   │   ├── 7d29d4ce6c4f98d8bcaa8b3c0ca4f8f1 -> /pathto/modules/mod-cassandra
│   │   └── aa8ffe05b5d08913f821fdb23ccdfd95
│   └── terraform.tfstate
├── globals.tf
├── main.tf
├── terraform.tfvars
└── variables.tf

以下是此项目的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_state资源的定义:

data "terraform_remote_state" "vpc_main" {
  backend = "s3"
  config {
    region = "us-west-2"
    bucket = "xxx"
    key    = "xxx/vpc.json"
  }
}

根据我们声明“data.terraform_remote_state.vpc_main”资源的位置(哪个文件),我们得到的结果不同:

Option 1. 如果我们在“test”项目(= main.tf)中的同一文件中声明了“data.terraform_remote_state”,则所有内容都会成功执行 .

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

$ 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无法解析此data.terraform_remote_state.vpc_main资源 .

Option 3. 但是出于测试目的,我们启用两个声明(在“globals.tf”和“main.tf”中),我们在执行[terraform apply]步骤时遇到此错误:

$ 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

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

但是,当我们尝试将其放入上面选项2下的单独文件时,为什么Terraform无法正确解析此资源?

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

https://www.terraform.io/docs/configuration/load.html

这似乎不是上面的情况 .

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

1 回答

  • 1

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

    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
    

    我把它设置为一个名为 set-remote-tf.sh 的shell脚本 .

相关问题