hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.61k stars 8.99k forks source link

[Bug]: creating S3 backed aws_appconfig_configuration_profile hits IAM trying to assume role error #38206

Open reikje opened 2 days ago

reikje commented 2 days ago

Terraform Core Version

1.6.1

AWS Provider Version

5.52.0

Affected Resource(s)

Expected Behavior

When creating the aws_appconfig_configuration_profile, the IAM role specified via the retrieval_role_arn can be assumed properly for creating the resource.

Actual Behavior

A permission error happens occasionally.

As a workaround, I added a time_sleep dependency of 10 seconds to the aws_appconfig_configuration_profile which seem to improve things, but still fails for the same reason from time to time.

Relevant Error/Panic Output Snippet

╷
│ Error: creating AppConfig Configuration Profile (s3) for Application (3atugpj): operation error AppConfig: CreateConfigurationProfile, https response error StatusCode: 400, RequestID: f77a17f6-b682-49f1-b93e-a59d26d3aca8, BadRequestException: Error trying to assume role arn:aws:iam::<account>:role/<resource>
│ 
│   with module.infrastructure.aws_appconfig_configuration_profile.default,
│   on ../common/integration/app_config.tf line 13, in resource "aws_appconfig_configuration_profile" "default":
│   13: resource "aws_appconfig_configuration_profile" "default" {
│ 
╵
Error: Terraform exited with code 1.
Error: Process completed with exit code 1.

Terraform Configuration Files

locals {
  resource_prefix = "namespace-project"
  tags = {
    CreatedBy = "Terraform"
  }
}

resource "aws_s3_bucket" "config" {
  bucket          = "${local.resource_prefix}-config"
  force_destroy   = true
  tags            = local.tags
}

resource "aws_s3_bucket_versioning" "config" {
  bucket = aws_s3_bucket.config.id

  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_iam_role" "config" {
  name = "${local.resource_prefix}-config"
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Effect = "Allow",
        Principal = {
          Service = "appconfig.amazonaws.com"
        }
      }
    ]
  })
  tags = local.tags
}

resource "aws_iam_policy" "config" {
  name   = "${local.resource_prefix}-config"

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Action = [
          "s3:*"
        ],
        Resource = [
          "${aws_s3_bucket.config.arn}",
          "${aws_s3_bucket.config.arn}/*"
        ]
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "config" {
  policy_arn = aws_iam_policy.config.arn
  role       = aws_iam_role.config.name
}

resource "aws_appconfig_application" "default" {
  name        = local.resource_prefix
  depends_on  = [aws_iam_role.config]
  tags        = local.tags
}

resource "aws_s3_object" "peers_config" {
  bucket      = aws_s3_bucket_versioning.config.id
  key         = "peers.json"
  content     = jsonencode([{id = "foo", name = "Bar"}])
  depends_on  = [aws_s3_bucket_versioning.config]
}

resource "aws_appconfig_configuration_profile" "default" {
  application_id      = aws_appconfig_application.default.id
  name                = "s3"
  location_uri        = "s3://${local.resource_prefix}-config/${local.peers_json}"
  retrieval_role_arn  = aws_iam_role.config.arn
  tags                = local.tags
}

resource "aws_appconfig_environment" "default" {
  name            = "dev"
  description     = "AppConfig Environment (dev)"
  application_id  = aws_appconfig_application.default.id
  tags            = local.tags
}

resource "aws_appconfig_deployment" "default" {
  application_id            = aws_appconfig_application.default.id
  environment_id            = aws_appconfig_environment.default.environment_id
  configuration_profile_id  = aws_appconfig_configuration_profile.default.configuration_profile_id
  configuration_version     = aws_s3_object.peers_config.version_id
  deployment_strategy_id    = "AppConfig.AllAtOnce"

  tags = local.tags
}

Steps to Reproduce

Use the given snippet to create an AppConfig having a configuration profile that is backed by an object inside an S3 bucket.

Debug Output

No response

Panic Output

No response

Important Factoids

This error doesn't happen all the time. There must be some sort of race condition that occasionally makes this fail. Expecting the IAM role to be not fully propagated and ready when AppConfig already tries to use it for creating the configuration profile.

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 2 days ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue