2017-01-14 2 views
4

Мы пытаемся использовать терраформу с удаленным состоянием, хранящимся в S3.terraform remote state

Проекты разрушаются, так как существует «основной» проект 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_id, CIDR и т.д. от удаленного состояния VPC. Вот как наш процесс определяется:

Шаг 1: Создать 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 

Шаг 2: Создание других групп ресурсов : Использование выходных значений из удаленного состояния VPC, попытка развертывания узлов ec2 в уже подготовленных общедоступных подсетях (выход проекта VPC с шага 1 выше). Вот шаги/команды наш скрипт работает (сначала скопировать все файлы в// рабочая папка, и скрипт выполняется в этой папке TMP/проекта):

$ 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/проекта/папки:

Вот как файловая структура проекта выглядит (в/TMP/проекта/папки):

├── .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» ресурс мы получаем разные результаты:

Вариант 1. Если у нас есть «data.terraform_remote_state», объявленный в том же файле в проекте «test» (= main.tf), все выполняется успешно.

Вариант 2. Если мы перемещаем data.terraform_remote_state.vpc_main в отдельный файл (=»globals.tf»), мы получаем эту ошибку во время выполнения [Terraform получить $ 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 ресурс.

Вариант 3. Но когда для целей тестирования мы включаем оба заявления (в «globals.tf» и в «main.tf») мы получаем эту ошибку во время выполнения [Terraform применять] Этап:

$ 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 выше?

Per терраформировать документации загружаются все * .tf файлов и добавляются в алфавитном порядке, а порядок декларации ресурса не имеет значения, поскольку конфигурация терраформировать являются декларативной:

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

Который, кажется, не быть случай выше.

Мы можем пойти с «жестко запрограммированным» подходом здесь, но есть ли «законный» способ в Terraform, чтобы сделать эту работу?

+0

В «** Шаг 1: Создать VPC. **», в какой каталог вы находитесь? Это «проекты/top-level-project-name-go-here/env-dev/vpc /'? и является модулем «cassandra» в «проектах/top-level-project-name-go-here/env-dev/test»? –

+0

На любом этапе наш скрипт оболочки оболочки копирует содержимое текущего проекта «цели» (будь то VPC или Cassandra или другое) в папку tmp/project, и это становится рабочим каталогом, для VPC это что-то вроде: step1: a) 'cp projects /.../ vpc /*.*/tmp/project /', а затем b) 'cd/tmp/projects', после чего мы сначала получаем состояние (-ы) террапоформ, а затем выполняем соответствующий «план террарирования» применяется | destroy'. Итак, мы начинаем вверху, но рабочая папка - это '/ tmp/project'. – gevgev

+0

Я проверил бы ключ для вашего ведра в источнике данных terraform_remote_state. По крайней мере, для нашего материала имя файла - «terraform.tfstate», а не что-то вроде « .json». Кроме того, чтобы быть уверенным, что ключ и ведро - это разные вещи, я предполагаю, что вы просто помещаете «xxx» туда, чтобы не давать нам имена клавиш и ковша. – jpancoast

ответ

0

Использование Try, что команды для набора удаленного состояния:

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.

Смежные вопросы