Как создать интеграцию хранилища Snowflake с AWS S3 с Terraform?

#amazon-web-services #terraform #snowflake-cloud-data-platform #amazon-iam

Вопрос:

Я пытаюсь использовать Terraform для настройки объекта «Интеграция хранилища снежинок», который ссылается на корзину AWS S3. Я использую поставщик снежинок» Чанцукерберг » из реестра Terraform в дополнение к стандартному поставщику AWS.

Проблема, с которой я сталкиваюсь, заключается в том, что часть процесса создания интеграции требует следующей последовательности действий:

  1. Создайте роль IAM с помощью политики доступа S3
  2. Создайте объект интеграции хранилища снежинок, указав Роль IAM, созданную на шаге 1
  3. Измените политику доступа к роли IAM, используя значения из объекта интеграции хранилища

(полный список шагов здесь)

Следовательно, существует циклическая зависимость между ролью IAM и интеграцией хранилища. Шаги 1 и 2 просты, но я не уверен, как реализовать шаг 3 с помощью Terraform, поскольку он включает изменение состояния объекта после его создания.

К сожалению, похоже, что политика доступа к роли IAM не может быть изменена отдельно от самой роли.

Возможно ли такое, или циклические отношения между ресурсами означают, что это не может быть обработано Terraform?

Комментарии:

1. API AWS потребуется обновить, чтобы отличать конечные точки для роли IAM от связанной с ней политики доступа. В противном случае да: в вашем случае использования у вас есть циклическая зависимость.

2. github.com/hashicorp/terraform/issues/27188

Ответ №1:

Циклы зависимостей Terraform с ролями IAM имеют простой обходной путь. Значение ARN роли может быть предварительно рассчитано, и тогда ресурс интеграции не зависит от роли. Затем роль может свободно использовать результаты интеграции.

Пример кода:

 locals {
  role_name = "my_role"
  role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${local.role_name}"
}

resource "snowflake_storage_integration" "int" {
  storage_aws_role_arn = local.role_arn
  ...
}

resource "aws_iam_role" "role" {
  name = local.role_name
  assume_role_policy = jsonencode({
    "Version" : "2012-10-17"
    "Statement" : [
      {
        "Action" : "sts:AssumeRole"
        "Effect" : "Allow"
        "Principal" : {
          "AWS" : snowflake_storage_integration.int.storage_aws_iam_user_arn
        }
        "Condition" : {
          "StringEquals" : {
            "sts:ExternalId" : snowflake_storage_integration.int.storage_aws_external_id
          }
        }
      }
    ]
  })
}
 

Комментарии:

1. Это очень похоже на то, что мы в конечном итоге сделали, чтобы разорвать циклическую зависимость, т. Е. Вычислить роль arn вместо того, чтобы считывать ее из состояния терраформирования. Это не идеально, так как существует небольшая вероятность того, что структура arn может измениться (это несколько раз случалось с AWS) и, следовательно, нарушить код, но мы решили, что риск был достаточно низким, и это действительно был единственный доступный обходной путь.