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.gi­ve_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-da­ta.sh из источника данных template_file: