За допомогою
data "terraform_remote_state"
ми можемо отримати outputs
одного проекту, щоб використати в іншому.
Наприклад, у нас AWS VPC створюється окремо від AWS EKS (хоча в серії Terraform: створення EKS, частина 1 – VPC, Subnets та Endpoints VPC створювалась як частина кластеру, але потім я їх розділив).
Для створення EKS – йому треба передати VPC ID, щоб потім з data "aws_subnets"
отримати список сабнетів, в яких буде створено кластер Kubernetes.
Можна захаркодити значення VPC – просто задати змінну string
, в якій зберігати значення, і в данному випадку це більш-менш робоче рішення, бо VPC ID навряд чи буде часто змінюватись. Проте якщо у вас досить багато значень, або вони динамічні – то є сенс використати terraform_remote_state
, який зможе “сходити” в AWS S3 бакет іншого проекту, і отримати актуальні значення прямо зі стейт-файлу.
Отже, що маємо: проект з VPC модулем, який має output
:
output "vpc_id" { value = module.vpc.vpc_id }
Він вже задеплоїний, і ми можемо отримати цей ID зі стейту за допомогою terraform output
:
$ terraform output vpc_id "vpc-0958e335e1c910ece"
Сам стейт проекту з VPC зберігається в AWS S3:
$ aws --profile tf-admin s3 ls tf-state-backend-atlas-vpc/dev/ 2023-09-22 15:14:43 81292 atlas-vpc-dev.tfstate
Далі, в проекті з модулем EKS додаємо data "terraform_remote_state"
:
data "terraform_remote_state" "vpc" { backend = "s3" config = { bucket = "tf-state-backend-atlas-vpc" key = "${var.environment}/atlas-vpc-${var.environment}.tfstate" region = "${var.aws_region}" dynamodb_table = "tf-state-lock-atlas-vpc-${var.environment}" } }
При чому тут, на відміну від звичайної конфіграції terraform.backend{}
ми можемо використовувати variables.
Створюємо локальну змінну, щоб потім не міняти по всьому коду EKS при якихось змінах в outputs
VPC:
locals { vpc_out = data.terraform_remote_state.vpc.outputs }
І використовуємо цей vpc_out
:
... data "aws_subnets" "private" { filter { name = "vpc-id" values = [local.vpc_out.vpc_id] } tags = { subnet-type = "private" } } data "aws_subnets" "intra" { filter { name = "vpc-id" values = [local.vpc_out.vpc_id] } tags = { subnet-type = "intra" } } ... module "eks" { source = "terraform-aws-modules/eks/aws" version = "~> 19.0" ... vpc_id = local.vpc_out.vpc_id subnet_ids = data.aws_subnets.private.ids control_plane_subnet_ids = data.aws_subnets.intra.ids ...
Готово.