Совместное использование ресурсов между рабочими пространствами Terraform
У меня есть инфраструктура, которую я развертываю, используя Terraform в AWS. Эту инфраструктуру можно развернуть в разных средах, для которых я использую рабочие пространства.
Большинство компонентов в развертывании должны создаваться отдельно для каждой рабочей области, но у меня есть несколько ключевых компонентов, которыми я хочу поделиться между ними, в первую очередь:
- Роли и разрешения IAM
- Они должны использовать один и тот же API-шлюз, но каждое рабочее пространство должно развертываться по разным путям и методам
Например:
resource "aws_iam_role" "lambda_iam_role" {
name = "LambdaGeneralRole"
policy = <...>
}
resource "aws_lambda_function" "my_lambda" {
function_name = "lambda-${terraform.workspace}"
role = "${aws_iam_role.lambda_iam_role.arn}"
}
Первый ресурс - это роль IAM, которая должна использоваться всеми экземплярами этой лямбды и не должна создаваться повторно более одного раза.
Второй ресурс - это лямбда-функция, имя которой зависит от текущего рабочего пространства, поэтому каждое рабочее пространство будет развертываться и отслеживать состояние другой лямбды.
Как я могу поделиться ресурсами и их состоянием между различными рабочими пространствами Terraform?
Ответы
Ответ 1
Для общих ресурсов я создаю их в отдельном шаблоне и затем обращаюсь к ним, используя terraform_remote_state
в шаблоне, где мне нужна информация о них.
Далее следует, как я это реализую, возможно, есть и другие способы реализовать это. YMMV
В шаблоне общих сервисов (куда вы бы поместили свою роль IAM) я использую бэкэнд Terraform для хранения выходных данных для шаблона общих сервисов в Консуле. Вам также необходимо output
любую информацию, которую вы хотите использовать в других шаблонах.
шаблон share_services
terraform {
backend "consul" {
address = "consul.aa.example.com:8500"
path = "terraform/shared_services"
}
}
resource "aws_iam_role" "lambda_iam_role" {
name = "LambdaGeneralRole"
policy = <...>
}
output "lambda_iam_role_arn" {
value = "${aws_iam_role.lambda_iam_role.arn}"
}
"Бэкэнд" в Terraform определяет, как загружается состояние и как выполняется такая операция, как apply. Эта абстракция позволяет хранить нелокальное состояние файла, выполнять удаленное выполнение и т.д.
В отдельном шаблоне вы вызываете серверную часть как источник данных, используя terraform_remote_state
, и можете использовать данные в этом шаблоне.
terraform_remote_state
:
Извлекает метаданные состояния из удаленного бэкэнда
индивидуальный шаблон
data "terraform_remote_state" "shared_services" {
backend = "consul"
config {
address = "consul.aa.example.com:8500"
path = "terraform/shared_services"
}
}
# This is where you use the terraform_remote_state data source
resource "aws_lambda_function" "my_lambda" {
function_name = "lambda-${terraform.workspace}"
role = "${data.terraform_remote_state.shared_services.lambda_iam_role_arn}"
}
Ссылки:
https://www.terraform.io/docs/state/remote.html
https://www.terraform.io/docs/backends/
https://www.terraform.io/docs/providers/terraform/d/remote_state.html
Ответ 2
Ресурсы, такие как aws_iam_role
, имеющие атрибут name
, не будут создавать новый экземпляр, если значение name
соответствует уже подготовленному ресурсу.
Итак, следующее создаст один aws_iam_role
с именем LambdaGeneralRole
.
resource "aws_iam_role" "lambda_iam_role" {
name = "LambdaGeneralRole"
policy = <...>
}
...
resource "aws_iam_role" "lambda_iam_role_reuse_existing_if_name_is_LambdaGeneralRole" {
name = "LambdaGeneralRole"
policy = <...>
}
Аналогично, провайдер aws
создаст одно имя S3 bucket
my-store
с указанием следующего:
resource "aws_s3_bucket" "store-1" {
bucket = "my-store"
acl = "public-read"
force_destroy = true
}
...
resource "aws_s3_bucket" "store-2" {
bucket = "my-store"
acl = "public-read"
force_destroy = true
}
Такое поведение сохраняется, даже если для ресурсов были определены разные рабочие пространства с соответствующим им отдельным состоянием Terraform.
Чтобы получить максимальную отдачу от этого подхода, определите общие ресурсы как отдельную конфигурацию. Таким образом, вы не рискуете уничтожить общий ресурс после запуска terraform destroy
.