aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.58k stars 3.88k forks source link

aws-appconfig-alpha: SQS Extension association always creates cdk diff #27676

Closed fredricbillow-axis closed 10 months ago

fredricbillow-axis commented 11 months ago

Describe the bug

When using the onDeploymentComplete function on an Environment to create an Extension Association using SqsDestination, CDK will always show a diff. Deploying the stack does not resolve the issue and instead a new diff will be shown.

Expected Behavior

When running cdk diff which shows a diff, then running cdk deploy to deploy the diff, there shouldn't be a new diff corresponding to the same resources. Running cdk diff again should show no diff.

Current Behavior

You end up in an endless loop of diffs even when deploying every diff. The diff looks like:

IAM Statement

│ + │ ${ExampleAppConfigStack/ExampleQueue.Arn} │ Allow │ sqs:SendMessage │ AWS:${ExampleAppConfigStack/ExtensionE0E43/RoleECABE}
│ + │ ${ExampleAppConfigStack/ExtensionE0E43/RoleECABE.Arn} │ Allow │ sts:AssumeRole │ Service:appconfig.amazonaws.com    

Resources

[-] AWS::IAM::Role ExampleAppConfigStack/Extension2618C/RoleB5F1F Extension2618CRoleB5F1F9C6EF666 destroy
[-] AWS::AppConfig::Extension ExampleAppConfigStack/Extension2618C Extension2618C89E0498C destroy
[-] AWS::AppConfig::ExtensionAssociation ExampleAppConfigStack/AssociationResource92794 AssociationResource92794 destroy
[+] AWS::IAM::Role ExampleAppConfigStack/ExtensionE0E43/RoleECABE ExtensionE0E43RoleECABEABE1C8C2 
[+] AWS::AppConfig::Extension ExampleAppConfigStack/ExtensionE0E43 ExtensionE0E436C18B05C 
[+] AWS::AppConfig::ExtensionAssociation ExampleAppConfigStack/AssociationResourceB7E32 AssociationResourceB7E32 

Reproduction Steps

Create a stack like so

import * as appConfig from "@aws-cdk/aws-appconfig-alpha";
import { Stack, StackProps } from "aws-cdk-lib";
import { Queue } from "aws-cdk-lib/aws-sqs";
import { Construct } from "constructs";

export class ExampleAppConfigStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const application = new appConfig.Application(this, "ExampleAppConfigApp", {
      name: "ExampleApplication",
    });

    const appConfigEnvironment = new appConfig.Environment(
      this,
      "ExampleAppConfigEnvironment",
      {
        application,
        name: "ExampleEnvironment",
      }
    );

    // Queue for AppConfig SQS Extension events
    const appConfigExtensionSqs = new Queue(this, "ExampleQueue", {
      queueName: "ExampleSQSExtensionQueue",
    });

    // Associate the environment resource to the ON_DEPLOYMENT_COMPLETE extension
    appConfigEnvironment.onDeploymentComplete(
      new appConfig.SqsDestination(appConfigExtensionSqs)
    );
  }
}

Deploy the stack. The stack should deploy without any issues.

Run cdk diff The diff shows both IAM statement changes and resource changes:

IAM Statement

│ + │ ${ExampleAppConfigStack/ExampleQueue.Arn} │ Allow │ sqs:SendMessage │ AWS:${ExampleAppConfigStack/Extension308F5/Role13E8F}
│ + │ ${ExampleAppConfigStack/Extension308F5/Role13E8F.Arn} │ Allow │ sts:AssumeRole │ Service:appconfig.amazonaws.com 

Resources

[-] AWS::IAM::Role ExampleAppConfigStack/Extension7192E/Role034E5 Extension7192ERole034E52732B92F destroy
[-] AWS::AppConfig::Extension ExampleAppConfigStack/Extension7192E Extension7192EFCCE5705 destroy
[-] AWS::AppConfig::ExtensionAssociation ExampleAppConfigStack/AssociationResource6DC52 AssociationResource6DC52 destroy
[+] AWS::IAM::Role ExampleAppConfigStack/Extension308F5/Role13E8F Extension308F5Role13E8F2DC1482B 
[+] AWS::AppConfig::Extension ExampleAppConfigStack/Extension308F5 Extension308F554A0B6CA 
[+] AWS::AppConfig::ExtensionAssociation ExampleAppConfigStack/AssociationResourceBAD5E AssociationResourceBAD5E 

Deploy the stack again. The stack should deploy without any issues.

Run cdk diff again Again, the diff shows IAM and resource changes.

IAM Statement

│ + │ ${ExampleAppConfigStack/ExampleQueue.Arn} │ Allow │ sqs:SendMessage │ AWS:${ExampleAppConfigStack/ExtensionE0E43/RoleECABE}
│ + │ ${ExampleAppConfigStack/ExtensionE0E43/RoleECABE.Arn} │ Allow │ sts:AssumeRole │ Service:appconfig.amazonaws.com    

Resources

[-] AWS::IAM::Role ExampleAppConfigStack/Extension2618C/RoleB5F1F Extension2618CRoleB5F1F9C6EF666 destroy
[-] AWS::AppConfig::Extension ExampleAppConfigStack/Extension2618C Extension2618C89E0498C destroy
[-] AWS::AppConfig::ExtensionAssociation ExampleAppConfigStack/AssociationResource92794 AssociationResource92794 destroy
[+] AWS::IAM::Role ExampleAppConfigStack/ExtensionE0E43/RoleECABE ExtensionE0E43RoleECABEABE1C8C2 
[+] AWS::AppConfig::Extension ExampleAppConfigStack/ExtensionE0E43 ExtensionE0E436C18B05C 
[+] AWS::AppConfig::ExtensionAssociation ExampleAppConfigStack/AssociationResourceB7E32 AssociationResourceB7E32 

Possible Solution

Most likely, the reason for the bug is located at https://github.com/aws/aws-cdk/blob/de7fb043c37569d39776623fe137860e279b9fbf/packages/%40aws-cdk/aws-appconfig-alpha/lib/extension.ts#L521

The statement eventDestination.extensionUri results in using the Queue.queueArn value in the case of the event destination being an SqsDestination:

https://github.com/aws/aws-cdk/blob/de7fb043c37569d39776623fe137860e279b9fbf/packages/%40aws-cdk/aws-appconfig-alpha/lib/extension.ts#L87

This results in a new ID being generated for the Role every time, ultimately replacing the current one as CDK treats it as a new Role.

A solution would be to use something else than the queueArnto create the ID of the Role.

Additional Information/Context

No response

CDK CLI Version

2.102.0 (build 2abc59a)

Framework Version

2.102.0-alpha.0

Node.js Version

18.18.2

OS

macOS

Language

TypeScript

Language Version

No response

Other information

No response

khushail commented 11 months ago

@fredricbillow-axis thanks for reporting this and sharing the link to the code as well. I am able to repro this.

github-actions[bot] commented 10 months ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.