pulumi-aws icon indicating copy to clipboard operation
pulumi-aws copied to clipboard

Pulumi replaces appconfig HostedConfigurationVersion and Deployment every time

Open karthik-rangarajan opened this issue 3 years ago • 3 comments
trafficstars

What happened?

We have an appconfig.HostedConfiguration and appconfig.Deployment that is used in our infrastructure, and every time we run pulumi up, it assumes there is new content, replaces that content, bumps the configuration version, and updates the resources.

Steps to reproduce

We have the following code:

    const application = new aws.appconfig.Application('companyAppServerConfig', {
        description: 'AppConfig Application',
        tags: {
            Name: 'AppConfig Application',
        },
    });

    const applicationIdParam = new aws.ssm.Parameter('appconfigApplicationIdParam', {
        name: 'FEATUREFLAG_APP_ID',
        tier: 'Standard',
        type: 'String',
        value: application.id,
    });

    const environment = new aws.appconfig.Environment('companyAppServerEnv', {
        description: 'AppConfig Environment',
        applicationId: application.id,
        tags: {
            Name: 'AppConfig Environment',
        },
    });

    // used for the app server to access the environment id
    const environmentIdParam = new aws.ssm.Parameter('appconfigEnvironmentIdParam', {
        name: 'FEATUREFLAG_ENV_ID',
        tier: 'Standard',
        type: 'String',
        value: environment.environmentId,
    });

    const featureFlagConfigurationProfile = new aws.appconfig.ConfigurationProfile('featureFlagConfigProfile', {
        description: 'Basic Feature Flag Configuration Profile',
        applicationId: application.id,
        locationUri: 'hosted',
        type: 'AWS.AppConfig.FeatureFlags',
        validators: [
            {
                content: JSON.stringify(validatorJson),
                type: 'JSON_SCHEMA',
            },
        ],
        tags: {
            Type: 'AppConfig Configuration Profile',
        },
    });

    // used for the app server to access the configuration profile id
    const profileIdParam = new aws.ssm.Parameter('appconfigProfileIdParam', {
        name: 'FEATUREFLAG_PROFILE_ID',
        tier: 'Standard',
        type: 'String',
        value: featureFlagConfigurationProfile.configurationProfileId,
    });

    const featureFlagsJson: Input<string> = JSON.stringify(featureFlagJson);

    const featureFlagsConfiguration = new aws.appconfig.HostedConfigurationVersion('featureFlagsConfiguration', {
        applicationId: application.id,
        configurationProfileId: featureFlagConfigurationProfile.configurationProfileId,
        description: 'Feature Flags Hosted Configuration',
        contentType: 'application/json',
        content: featureFlagsJson,
    });

    const featureFlagsDeployment = new aws.appconfig.Deployment('featureFlagsDeployment', {
        applicationId: application.id,
        configurationProfileId: featureFlagsConfiguration.configurationProfileId,
        configurationVersion: pulumi.interpolate`${featureFlagsConfiguration.versionNumber}`,
        deploymentStrategyId: 'AppConfig.AllAtOnce',
        description: 'Demo feature flag deployment',
        environmentId: environment.environmentId,
        tags: {
            Type: 'AppConfig Deployment',
        },
    });

and some other code to modify IAM policy and attach this to ECS.

Expected Behavior

There are no changes unless the feature flags defined in featureFlagsJson actually change.

Actual Behavior

Whenever we run pulumi up the following happens:

++aws:appconfig/hostedConfigurationVersion:HostedConfigurationVersion: (create-replacement)
        [id=bw9uhy5/pqvw63r/12]
        [urn=urn:pulumi:prod::company::aws:appconfig/hostedConfigurationVersion:HostedConfigurationVersion::featureFlagsConfiguration]
        [provider=urn:pulumi:prod::company::pulumi:providers:aws::default_5_11_0::683dfff3-88e1-4c79-bc9f-9818f6e62c98]
      ~ content: [secret] => (json) {
          + flags  : {
              + demoDisabled: {
                  + attributes: {
                      + user_ids: {
                          + constraints: {
                              + type: "array"
                            }
                        }
                      + value      : {
                          + constraints: {
                              + type: "boolean"
                            }
                        }
                    }
                  + name      : "demoDisabled"
                }
            + version: "1"
         }

    +-aws:appconfig/hostedConfigurationVersion:HostedConfigurationVersion: (replace)
        [id=bw9uhy5/pqvw63r/12]
        [urn=urn:pulumi:prod::company::aws:appconfig/hostedConfigurationVersion:HostedConfigurationVersion::featureFlagsConfiguration]
        [provider=urn:pulumi:prod::company::pulumi:providers:aws::default_5_11_0::683dfff3-88e1-4c79-bc9f-9818f6e62c98]
      ~ content: [secret] => (json) {
          + flags  : {
              + demoDisabled: {
                  + attributes: {
                      + user_ids: {
                          + constraints: {
                              + type: "array"
                            }
                        }
                      + value      : {
                          + constraints: {
                              + type: "boolean"
                            }
                        }
                    }
                  + name      : "demoDisabled"
                }
          + version: "1"
        }

    ++aws:appconfig/deployment:Deployment: (create-replacement)
        [id=bw9uhy5/89x86oq/8]
        [urn=urn:pulumi:prod::company::aws:appconfig/deployment:Deployment::featureFlagsDeployment]
        [provider=urn:pulumi:prod::company::pulumi:providers:aws::default_5_11_0::683dfff3-88e1-4c79-bc9f-9818f6e62c98]
      ~ configurationVersion: "12" => output<string>
    +-aws:appconfig/deployment:Deployment: (replace)
        [id=bw9uhy5/89x86oq/8]
        [urn=urn:pulumi:prod::company::aws:appconfig/deployment:Deployment::featureFlagsDeployment]
        [provider=urn:pulumi:prod::company::pulumi:providers:aws::default_5_11_0::683dfff3-88e1-4c79-bc9f-9818f6e62c98]
      ~ configurationVersion: "12" => output<string>

Output of pulumi about

Version      3.42.0
Go Version   go1.19.1
Go Compiler  gc

Plugins
NAME    VERSION
aws     5.11.0
docker  3.4.1
nodejs  unknown

Host
OS       darwin
Version  12.6
Arch     arm64

This project is written in nodejs: executable='/Users/karthik/.nvm/versions/node/v16.15.1/bin/node' version='v16.15.1'

Current Stack: company/prod

TYPE                                                                 URN
pulumi:pulumi:Stack                                                  urn:pulumi:prod::company::pulumi:pulumi:Stack::company-prod
pulumi:providers:aws                                                 urn:pulumi:prod::company::pulumi:providers:aws::default_5_11_0
aws:ssm/parameter:Parameter                                          urn:pulumi:prod::company::aws:ssm/parameter:Parameter::metabasePostgresUser
aws:kms/key:Key                                                      urn:pulumi:prod::company::aws:kms/key:Key::s3EncryptionKey
aws:iam/role:Role                                                    urn:pulumi:prod::company::aws:iam/role:Role::ecsTaskExecutionRole
aws:iam/role:Role                                                    urn:pulumi:prod::company::aws:iam/role:Role::ecsInstanceRole
aws:ecs/cluster:Cluster                                              urn:pulumi:prod::company::aws:ecs/cluster:Cluster::prod
aws:ec2/launchTemplate:LaunchTemplate                                urn:pulumi:prod::company::aws:ec2/launchTemplate:LaunchTemplate::ecs-instances-reserved
aws:ec2/vpc:Vpc                                                      urn:pulumi:prod::company::aws:ec2/vpc:Vpc::prod
aws:appconfig/application:Application                                urn:pulumi:prod::company::aws:appconfig/application:Application::companyAppServerConfig
aws:ssm/parameter:Parameter                                          urn:pulumi:prod::company::aws:ssm/parameter:Parameter::metabasePostgresPassword
aws:iam/policy:Policy                                                urn:pulumi:prod::company::aws:iam/policy:Policy::appConfigDataPolicy
aws:s3/bucket:Bucket                                                 urn:pulumi:prod::company::aws:s3/bucket:Bucket::userUploadedFiles
aws:s3/bucket:Bucket                                                 urn:pulumi:prod::company::aws:s3/bucket:Bucket::migrationSnapshots
aws:ecs/taskDefinition:TaskDefinition                                urn:pulumi:prod::company::aws:ecs/taskDefinition:TaskDefinition::metabase
aws:iam/rolePolicyAttachment:RolePolicyAttachment                    urn:pulumi:prod::company::aws:iam/rolePolicyAttachment:RolePolicyAttachment::ecsInstanceRole-AmazonECSTaskExecutionRolePolicy
aws:iam/rolePolicy:RolePolicy                                        urn:pulumi:prod::company::aws:iam/rolePolicy:RolePolicy::retrieveFromSSM
aws:iam/rolePolicyAttachment:RolePolicyAttachment                    urn:pulumi:prod::company::aws:iam/rolePolicyAttachment:RolePolicyAttachment::ecsInstanceRole
aws:iam/instanceProfile:InstanceProfile                              urn:pulumi:prod::company::aws:iam/instanceProfile:InstanceProfile::ecsInstanceProfile
aws:alb/targetGroup:TargetGroup                                      urn:pulumi:prod::company::aws:alb/targetGroup:TargetGroup::main
aws:ec2/subnet:Subnet                                                urn:pulumi:prod::company::aws:ec2/subnet:Subnet::private_us_west_2a
aws:ec2/routeTable:RouteTable                                        urn:pulumi:prod::company::aws:ec2/routeTable:RouteTable::privateRouteTable
aws:ec2/internetGateway:InternetGateway                              urn:pulumi:prod::company::aws:ec2/internetGateway:InternetGateway::igw
aws:ec2/subnet:Subnet                                                urn:pulumi:prod::company::aws:ec2/subnet:Subnet::private_us_west_2b
aws:ec2/subnet:Subnet                                                urn:pulumi:prod::company::aws:ec2/subnet:Subnet::public_us_west_2c
aws:ec2/securityGroup:SecurityGroup                                  urn:pulumi:prod::company::aws:ec2/securityGroup:SecurityGroup::alb
aws:ec2/subnet:Subnet                                                urn:pulumi:prod::company::aws:ec2/subnet:Subnet::public_us_west_2a
aws:ec2/subnet:Subnet                                                urn:pulumi:prod::company::aws:ec2/subnet:Subnet::public_us_west_2b
aws:ec2/subnet:Subnet                                                urn:pulumi:prod::company::aws:ec2/subnet:Subnet::private_us_west_2c
aws:alb/targetGroup:TargetGroup                                      urn:pulumi:prod::company::aws:alb/targetGroup:TargetGroup::metabase-tg
aws:appconfig/environment:Environment                                urn:pulumi:prod::company::aws:appconfig/environment:Environment::companyAppServerEnv
aws:ssm/parameter:Parameter                                          urn:pulumi:prod::company::aws:ssm/parameter:Parameter::appconfigApplicationIdParam
aws:iam/rolePolicyAttachment:RolePolicyAttachment                    urn:pulumi:prod::company::aws:iam/rolePolicyAttachment:RolePolicyAttachment::attachAppConfigPolicyToEcsInstance
aws:iam/policy:Policy                                                urn:pulumi:prod::company::aws:iam/policy:Policy::userUploadedFilesBucketPolicy
aws:iam/policy:Policy                                                urn:pulumi:prod::company::aws:iam/policy:Policy::migrationBucketPolicy
aws:ec2/routeTableAssociation:RouteTableAssociation                  urn:pulumi:prod::company::aws:ec2/routeTableAssociation:RouteTableAssociation::privateRouteTableAssociation0
aws:ec2/routeTable:RouteTable                                        urn:pulumi:prod::company::aws:ec2/routeTable:RouteTable::publicRouteTable
aws:ec2/routeTableAssociation:RouteTableAssociation                  urn:pulumi:prod::company::aws:ec2/routeTableAssociation:RouteTableAssociation::privateRouteTableAssociation1
aws:ec2/securityGroup:SecurityGroup                                  urn:pulumi:prod::company::aws:ec2/securityGroup:SecurityGroup::ecs-instances
aws:autoscaling/group:Group                                          urn:pulumi:prod::company::aws:autoscaling/group:Group::ecs-instances-asg
aws:alb/loadBalancer:LoadBalancer                                    urn:pulumi:prod::company::aws:alb/loadBalancer:LoadBalancer::main
aws:ec2/routeTableAssociation:RouteTableAssociation                  urn:pulumi:prod::company::aws:ec2/routeTableAssociation:RouteTableAssociation::privateRouteTableAssociation2
aws:rds/subnetGroup:SubnetGroup                                      urn:pulumi:prod::company::aws:rds/subnetGroup:SubnetGroup::rds-private-subnet-group
aws:ecs/service:Service                                              urn:pulumi:prod::company::aws:ecs/service:Service::metabase
aws:ssm/parameter:Parameter                                          urn:pulumi:prod::company::aws:ssm/parameter:Parameter::appconfigEnvironmentIdParam
aws:iam/rolePolicyAttachment:RolePolicyAttachment                    urn:pulumi:prod::company::aws:iam/rolePolicyAttachment:RolePolicyAttachment::attachS3UserFileUploadsPolicyToEcsInstance
aws:iam/rolePolicyAttachment:RolePolicyAttachment                    urn:pulumi:prod::company::aws:iam/rolePolicyAttachment:RolePolicyAttachment::attachS3PolicyToEcsInstance
aws:ec2/routeTableAssociation:RouteTableAssociation                  urn:pulumi:prod::company::aws:ec2/routeTableAssociation:RouteTableAssociation::publicRouteTableAssociation0
aws:ec2/routeTableAssociation:RouteTableAssociation                  urn:pulumi:prod::company::aws:ec2/routeTableAssociation:RouteTableAssociation::publicRouteTableAssociation1
aws:ec2/routeTableAssociation:RouteTableAssociation                  urn:pulumi:prod::company::aws:ec2/routeTableAssociation:RouteTableAssociation::publicRouteTableAssociation2
aws:ec2/securityGroup:SecurityGroup                                  urn:pulumi:prod::company::aws:ec2/securityGroup:SecurityGroup::rds
aws:ec2/launchTemplate:LaunchTemplate                                urn:pulumi:prod::company::aws:ec2/launchTemplate:LaunchTemplate::ecs-instances
aws:alb/listener:Listener                                            urn:pulumi:prod::company::aws:alb/listener:Listener::http
aws:rds/instance:Instance                                            urn:pulumi:prod::company::aws:rds/instance:Instance::main
aws:alb/listenerRule:ListenerRule                                    urn:pulumi:prod::company::aws:alb/listenerRule:ListenerRule::metabaseListenerRule
aws:appconfig/configurationProfile:ConfigurationProfile              urn:pulumi:prod::company::aws:appconfig/configurationProfile:ConfigurationProfile::featureFlagConfigProfile
aws:ssm/parameter:Parameter                                          urn:pulumi:prod::company::aws:ssm/parameter:Parameter::appconfigProfileIdParam
aws:appconfig/hostedConfigurationVersion:HostedConfigurationVersion  urn:pulumi:prod::company::aws:appconfig/hostedConfigurationVersion:HostedConfigurationVersion::featureFlagsConfiguration
aws:appconfig/deployment:Deployment                                  urn:pulumi:prod::company::aws:appconfig/deployment:Deployment::featureFlagsDeployment


Found no pending operations associated with company/prod

Backend
Name           pulumi.com
URL            https://app.pulumi.com/karthik-rangarajan
User           karthik-rangarajan
Organizations  karthik-rangarajan, company

Pulumi locates its logs in /var/folders/t0/gshbmh7x3xs2t2wkqwg_j1b40000gn/T/ by default
warning: Failed to get information about the Pulumi program's dependencies: Failed to run "/Users/karthik/.nvm/versions/node/v16.15.1/bin/npm ls --json --depth=0": exit status 1

Additional context

No response

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

karthik-rangarajan avatar Oct 07 '22 22:10 karthik-rangarajan

Looks like a provider diff issue, moving to pulumi-aws.

Frassle avatar Oct 07 '22 22:10 Frassle

@karthik-rangarajan does the replacement only show during the preview, or does it actually attempt to re-create the resource at the point of deployment?

Also, from the preview, it appears that the previous configuration value was a secret. Do you know why this might have been flagged as a secret? I'm wondering if the secret value could be causing an issue during the diff.

danielrbradley avatar Oct 10 '22 10:10 danielrbradley

It actually recreates the resource to the point where our configuration version is all the way up to 20 now, even though the JSON itself hasn't changed.

I have been trying to debug why the value shows up as a secret - it wasn't ever a secret, as far as I can tell. The secret value is definitely what is causing an issue during the diff however, at least from my read of pulumi's diffing algorithm.

karthik-rangarajan avatar Oct 10 '22 17:10 karthik-rangarajan