0
votes

I am trying to use Terraform to set up a Snowflake "Storage Integration" object that links to an AWS S3 bucket. I'm using the "chanzuckerberg" Snowflake provider from the Terraform registry in addition to the standard AWS provider.

The issue I have is that part of the process to create the integration requires the following sequence of actions:

  1. Create an IAM Role with S3 access policy
  2. Create a Snowflake Storage Integration object, specifying the IAM Role created in step 1
  3. Modify the IAM Role access policy using values from the Storage Integration object

(complete list of steps here)

Hence there is a circular dependency between the IAM Role and Storage Integration. Steps 1 and 2 are straightforward but I'm not sure how to implement step 3 with Terraform as in involves modifying an object's state after it has been created.

Unfortunately it looks like the IAM Role access policy cannot be modified separate from the role itself.

Is such a thing possible or does the circular relationship between the resources mean this can't be handled by Terraform?

1
The AWS API would need to be updated to differentiate endpoints for the IAM Role versus its associated access policy. Otherwise yes: you have a circular dependency in your use case.Matt Schuchard

1 Answers

0
votes

Terraform dependency cycles with IAM roles have a straightforward workaround. The role ARN can be precalculated, and the integration resource then has no dependency on the role. The role can then use the integration outputs freely.

Sample code:

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
          }
        }
      }
    ]
  })
}