Terraform: инфраструктура на уровне кода | страница 114
resource "aws_iam_policy" "cloudwatch_full_access" {
name = "cloudwatch-full-access"
policy = data.aws_iam_policy_document.cloudwatch_full_access.json
}
data "aws_iam_policy_document" "cloudwatch_full_access" {
statement {
effect = "Allow"
actions = ["cloudwatch:*"]
resources = ["*"]
}
}
Наша цель — назначить одно из этих правил IAM пользователю neo с учетом значения новой входной переменной под названием give_neo_cloudwatch_full_access:
variable "give_neo_cloudwatch_full_access" {
description = "If true, neo gets full access to CloudWatch"
type = bool
}
Если бы вы использовали язык программирования общего назначения, выражение if-else можно было бы написать в таком виде:
# Это просто псевдокод. Он не будет работать в Terraform.
if var.give_neo_cloudwatch_full_access {
resource "aws_iam_user_policy_attachment" "neo_cloudwatch_full_access" {
user = aws_iam_user.example[0].name
policy_arn = aws_iam_policy.cloudwatch_full_access.arn
}
} else {
resource "aws_iam_user_policy_attachment" "neo_cloudwatch_read_only" {
user = aws_iam_user.example[0].name
policy_arn = aws_iam_policy.cloudwatch_read_only.arn
}
}
В Terraform для этого можно воспользоваться параметром count и условным выражением для каждого из ресурсов:
resource "aws_iam_user_policy_attachment" "neo_cloudwatch_full_access" {
count = var.give_neo_cloudwatch_full_access ? 1 : 0
user = aws_iam_user.example[0].name
policy_arn = aws_iam_policy.cloudwatch_full_access.arn
}
resource "aws_iam_user_policy_attachment" "neo_cloudwatch_read_only" {
count = var.give_neo_cloudwatch_full_access ? 0 : 1
user = aws_iam_user.example[0].name
policy_arn = aws_iam_policy.cloudwatch_read_only.arn
}
Этот код содержит два ресурса aws_iam_user_policy_attachment. У первого, который выдает полный доступ к CloudWatch, есть условное выражение. Если var.give_neo_cloudwatch_full_access равно true, оно возвращает 1, если нет — 0 (это частица if). Условное выражение второго ресурса, который выдает доступ на чтение, делает все наоборот: если var.give_neo_cloudwatch_full_access равно true, оно возвращает 0, если нет — 1 (это частица else).
Этот подход хорошо работает в ситуациях, когда вашему коду Terraform не нужно знать о том, какая из веток (if или else) на самом деле выполняется. Но если нужно обратиться к какому-нибудь выходному атрибуту ресурса, который возвращается из if или else? Представьте, к примеру, что вы хотите предложить пользователю на выбор два разных скрипта в разделе user_data модуля webserver-cluster. В настоящее время модуль webserver-cluster загружает скрипт user-data.sh из источника данных template_file: