首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >terraform远程状态

terraform远程状态
EN

Stack Overflow用户
提问于 2017-01-15 07:18:15
回答 2查看 4.4K关注 0票数 7

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

项目正在被拆分,例如有VPC主项目,它只创建网络基础设施(vpc、子网、IGW、NAT、路由等),以及子项目,在主vpc(子网)之上创建特定资源,即ec2节点。

项目文件夹/文件:

代码语言:javascript
运行
复制
.
├── 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等。下面是我们的流程的定义:

VPC第一步:创建.

这里没有问题,VPC创建完成,输出打印出来,并存储到S3存储桶中:

代码语言:javascript
运行
复制
$ 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

代码语言:javascript
运行
复制
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

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

代码语言:javascript
运行
复制
$ 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 /文件夹中):

代码语言:javascript
运行
复制
├── .terraform
│   ├── modules
│   │   ├── 7d29d4ce6c4f98d8bcaa8b3c0ca4f8f1 -> /pathto/modules/mod-cassandra
│   │   └── aa8ffe05b5d08913f821fdb23ccdfd95
│   └── terraform.tfstate
├── globals.tf
├── main.tf
├── terraform.tfvars
└── variables.tf

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

代码语言:javascript
运行
复制
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资源的定义:

代码语言:javascript
运行
复制
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”资源的位置(哪个文件),我们会得到不同的结果:

测试选项1.如果我们在“”项目(=main.tf)的同一文件中声明了“data.terraform_remote_state”,那么一切都会成功执行。

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

代码语言:javascript
运行
复制
$ 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资源。

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

代码语言:javascript
运行
复制
$ 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不能正确地解析这个资源,当我们试图在上面的选项2下将其放入一个单独的文件中时?

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

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

但上面的情况似乎并非如此。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-07 00:41:05

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

代码语言:javascript
运行
复制
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脚本。

票数 1
EN

Stack Overflow用户

发布于 2019-05-20 01:45:08

我使用terraform远程状态有一段时间了。我认为您的问题是terraform状态的依赖关系的组织问题。

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

代码语言:javascript
运行
复制
.
├── 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/
代码语言:javascript
运行
复制
# ../vpc/config.tf
terraform {
  backend "s3" {
    bucket = "my-infrastructure"
    prefix = "vpc"
  }
}
代码语言:javascript
运行
复制
# ../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"
  }
}

您可以在这里查看GCP示例https://github.com/abgm/gcp-terraform-example/tree/first-example

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41656058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档