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.86k stars 9.21k forks source link

[Bug]: Terraform showing changes in second terraform apply for administration_role_arn in aws_cloudformation_stack_set #27125

Open ccsandhanshive opened 2 years ago

ccsandhanshive commented 2 years ago

Terraform Core Version

v0.12.31

AWS Provider Version

v4.33.0, v3.70.0

Affected Resource(s)

Expected Behavior

Actual Behavior

Relevant Error/Panic Output Snippet

> terraform apply
aws_cloudformation_stack_set.this: Refreshing state... [id=test]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_cloudformation_stack_set.this will be updated in-place
  ~ resource "aws_cloudformation_stack_set" "this" {
      - administration_role_arn = "arn:aws:iam::*****:role/AWSCloudFormationStackSetAdministrationRole" -> null
        arn                     = "arn:aws:cloudformation:ap-northeast-1:*****:stackset/test:b49eab24-5351-4128-88da-60d926148388"
        call_as                 = "SELF"
        capabilities            = []
        execution_role_name     = "AWSCloudFormationStackSetExecutionRole"
        id                      = "test"
        name                    = "test"
        parameters              = {}
        permission_model        = "SELF_MANAGED"
        stack_set_id            = "test:b49eab24-5351-4128-88da-60d926148388"
        tags                    = {}
        tags_all                = {}
        template_body           = jsonencode(
            {
                Resources = {
                    MyS3Bucket = {
                        Properties = {}
                        Type       = "AWS::S3::Bucket"
                    }
                }
            }
        )
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_cloudformation_stack_set.this: Modifying... [id=test]
aws_cloudformation_stack_set.this: Modifications complete after 8s [id=test]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Outputs:

aws_cloudformation_stack_set = {
  "administration_role_arn" = "arn:aws:iam::******:role/AWSCloudFormationStackSetAdministrationRole"
  "arn" = "arn:aws:cloudformation:ap-northeast-1:*******:stackset/test:b49eab24-5351-4128-88da-60d926148388"
  "auto_deployment" = []
  "call_as" = "SELF"
  "capabilities" = []
  "description" = ""
  "execution_role_name" = "AWSCloudFormationStackSetExecutionRole"
  "id" = "test"
  "name" = "test"
  "operation_preferences" = []
  "parameters" = {}
  "permission_model" = "SELF_MANAGED"
  "stack_set_id" = "test:b49eab24-5351-4128-88da-60d926148388"
  "tags" = {}
  "tags_all" = {}
  "template_body" = "{\r\n  \"Resources\": {\r\n    \"MyS3Bucket\": {\r\n      \"Type\": \"AWS::S3::Bucket\",\r\n      \"Properties\": 
{}\r\n \r\n    }\r\n  }\r\n}\r\n\r\n"
}
>

Terraform Configuration Files

resource "aws_cloudformation_stack_set" "this" {
  name                    = "test"
  template_body = <<TEMPLATE
{
  "Resources": {
    "MyS3Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {}
    }
  }
}

TEMPLATE
 lifecycle {
    ignore_changes = [
      parameters["Password"]
    ]
  }
}

output "aws_cloudformation_stack_set" {
  value = aws_cloudformation_stack_set.this
}

Steps to Reproduce

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

No response

github-actions[bot] commented 2 years ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

theonlysinjin commented 2 years ago

I ran into this too and ended up ignoring it as it must be set by cloudformation after terraform knows about it,

  lifecycle {
    ignore_changes = [
      administration_role_arn
    ]
  }

But then now I found this note in the resource docs,

NOTE:
All template parameters, including those with a Default, must be configured or ignored with the lifecycle configuration block ignore_changes argument.
justinretzolk commented 2 years ago

Hey @ccsandhanshive 👋 Thank you for taking the time to raise this! In this case, I believe that you're seeing this behavior because you've not set the administration_role_arn, but you have the permission_model set to SELF_MANAGED. From the resource documentation:

administration_role_arn - (Optional) Amazon Resource Number (ARN) of the IAM Role in the administrator account. This must be defined when using the SELF_MANAGED permission model.

geof2001 commented 2 years ago

We run into this same issue but we're using the auto_deployment block which conflicts with administrative_role_arn.
auto_deployment { enabled = true retain_stacks_on_account_removal = false } We'd already just added it to the ignore_changes block but I still feel this behavior is incorrect if you're using incompatible fields. What interesting though is in the state it does show the administrative_role_arn being set to the AWSServiceRoleForCloudFormationStackSetsOrgAdmin role. So should these two fields just be allowed to co-exist then since even an auto_deployment stackset still has this field configured and is modifiable?

tf state show aws_cloudformation_stack_set.managed_iam_roles          
# aws_cloudformation_stack_set.managed_iam_roles:
resource "aws_cloudformation_stack_set" "managed_iam_roles" {
    administration_role_arn = "arn:aws:iam::123456789012:role/aws-service-role/stacksets.cloudformation.amazonaws.com/AWSServiceRoleForCloudFormationStackSetsOrgAdmin"
    arn                     = "arn:aws:cloudformation:us-east-1:123456789012:stackset/Managed-IAM-Roles:c7c7d7a1-1b02-419b-af48-e82d9c53119d"
    call_as                 = "SELF"
    .
    .
    .
    auto_deployment {
        enabled                          = true
        retain_stacks_on_account_removal = false
    }
}
yafanasiev commented 1 year ago

Same behaviour here when importing existing StackSet into state, subsequent applies show this diff:

  # aws_cloudformation_stack_set.iam_password_policy_organization will be updated in-place
  ~ resource "aws_cloudformation_stack_set" "iam_password_policy_organization" {
      - administration_role_arn = "arn:aws:iam::<redacted>:role/aws-service-role/stacksets.cloudformation.amazonaws.com/AWSServiceRoleForCloudFormationStackSetsOrgAdmin" -> null
        id                      = "<redacted>"
        name                    = "<redacted>"
        # (10 unchanged attributes hidden)

        # (3 unchanged blocks hidden)
    }
iniinikoski commented 10 months ago

We run into this same issue but we're using the auto_deployment block which conflicts with administrative_role_arn. auto_deployment { enabled = true retain_stacks_on_account_removal = false } We'd already just added it to the ignore_changes block but I still feel this behavior is incorrect if you're using incompatible fields. What interesting though is in the state it does show the administrative_role_arn being set to the AWSServiceRoleForCloudFormationStackSetsOrgAdmin role. So should these two fields just be allowed to co-exist then since even an auto_deployment stackset still has this field configured and is modifiable?

tf state show aws_cloudformation_stack_set.managed_iam_roles          
# aws_cloudformation_stack_set.managed_iam_roles:
resource "aws_cloudformation_stack_set" "managed_iam_roles" {
    administration_role_arn = "arn:aws:iam::123456789012:role/aws-service-role/stacksets.cloudformation.amazonaws.com/AWSServiceRoleForCloudFormationStackSetsOrgAdmin"
    arn                     = "arn:aws:cloudformation:us-east-1:123456789012:stackset/Managed-IAM-Roles:c7c7d7a1-1b02-419b-af48-e82d9c53119d"
    call_as                 = "SELF"
    .
    .
    .
    auto_deployment {
        enabled                          = true
        retain_stacks_on_account_removal = false
    }
}

Same here, using AWS provider version 5.32.1. Yep, maybe they would need to co-exist as you mention...

lusitania commented 2 months ago

Hey @ccsandhanshive 👋 Thank you for taking the time to raise this! In this case, I believe that you're seeing this behavior because you've not set the administration_role_arn, but you have the permission_model set to SELF_MANAGED. From the resource documentation:

administration_role_arn - (Optional) Amazon Resource Number (ARN) of the IAM Role in the administrator account. This must be defined when using the SELF_MANAGED permission model.

Same for permission_model = "SERVICE_MANAGED"

Terraform will perform the following actions:

  # aws_cloudformation_stack_set.this will be updated in-place
  ~ resource "aws_cloudformation_stack_set" "this" {
      - administration_role_arn = "arn:aws:iam::<>:role/aws-service-role/stacksets.cloudformation.amazonaws.com/AWSServiceRoleForCloudFormationStackSetsOrgAdmin" -> null
        ...
    }

Plan: 0 to add, 1 to change, 0 to destroy.