Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(appconfig-alpha): add deploy method to configuration constructs #28269

Merged
merged 8 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-appconfig-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,20 @@ new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', {
});
```

To deploy a configuration to an environment after initialization use the `deploy` method:

```ts
declare const application: appconfig.Application;
declare const env: appconfig.Environment;

const config = new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', {
application,
content: appconfig.ConfigurationContent.fromInlineText('This is my configuration content.'),
});

config.deploy(env);
```

### SourcedConfiguration

A sourced configuration represents configuration stored in an Amazon S3 bucket, AWS Secrets Manager secret, Systems Manager
Expand Down
29 changes: 19 additions & 10 deletions packages/@aws-cdk/aws-appconfig-alpha/lib/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,24 @@ abstract class ConfigurationBase extends Construct implements IConfiguration, IE
this.extensible.addExtension(extension);
}

/**
* Deploys the configuration to the specified environment.
*
* @param environment The environment to deploy the configuration to
*/
public deploy(environment: IEnvironment) {
const logicalId = `Deployment${this.getDeploymentHash(environment)}`;
new CfnDeployment(this, logicalId, {
applicationId: this.application.applicationId,
configurationProfileId: this.configurationProfileId,
deploymentStrategyId: this.deploymentStrategy!.deploymentStrategyId,
environmentId: environment.environmentId,
configurationVersion: this.versionNumber!,
description: this.description,
kmsKeyIdentifier: this.deploymentKey?.keyArn,
});
}

protected addExistingEnvironmentsToApplication() {
this.deployTo?.forEach((environment) => {
if (!this.application.environments.includes(environment)) {
Expand All @@ -320,16 +338,7 @@ abstract class ConfigurationBase extends Construct implements IConfiguration, IE
if ((this.deployTo && !this.deployTo.includes(environment))) {
return;
}
const logicalId = `Deployment${this.getDeploymentHash(environment)}`;
new CfnDeployment(this, logicalId, {
applicationId: this.application.applicationId,
configurationProfileId: this.configurationProfileId,
deploymentStrategyId: this.deploymentStrategy!.deploymentStrategyId,
environmentId: environment.environmentId,
configurationVersion: this.versionNumber!,
description: this.description,
kmsKeyIdentifier: this.deploymentKey?.keyArn,
});
this.deploy(environment);
});
}
}
Expand Down
115 changes: 115 additions & 0 deletions packages/@aws-cdk/aws-appconfig-alpha/test/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,121 @@ describe('configuration', () => {
Template.fromStack(stack).resourceCountIs('AWS::AppConfig::Deployment', 1);
});

test('configuration using deploy method and no environment associated', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig', {
name: 'MyApplication',
});
app.addEnvironment('MyEnv1');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
app.addEnvironment('MyEnv1');

no environment associated

Shouldn't this be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are being attached to the application and not the configuration :)

const env = app.addEnvironment('MyEnv2');
const config = new HostedConfiguration(stack, 'MyHostedConfig', {
content: ConfigurationContent.fromInlineText('This is my content'),
application: app,
deploymentStrategy: new DeploymentStrategy(stack, 'MyDeploymentStrategy', {
rolloutStrategy: RolloutStrategy.linear({
growthFactor: 15,
deploymentDuration: cdk.Duration.minutes(30),
}),
}),
});
config.deploy(env);

Template.fromStack(stack).hasResourceProperties('AWS::AppConfig::Deployment', {
ApplicationId: {
Ref: 'MyAppConfigB4B63E75',
},
EnvironmentId: {
Ref: 'MyAppConfigMyEnv2350437D6',
},
ConfigurationVersion: {
Ref: 'MyHostedConfig51D3877D',
},
ConfigurationProfileId: {
Ref: 'MyHostedConfigConfigurationProfile2E1A2BBC',
},
DeploymentStrategyId: {
Ref: 'MyDeploymentStrategy60D31FB0',
},
});
Template.fromStack(stack).resourceCountIs('AWS::AppConfig::Deployment', 1);
});

test('configuration using deploy method with environment associated', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig', {
name: 'MyApplication',
});
const env1 = app.addEnvironment('MyEnv1');
const env2 = app.addEnvironment('MyEnv2');
const config = new HostedConfiguration(stack, 'MyHostedConfig', {
content: ConfigurationContent.fromInlineText('This is my content'),
application: app,
deploymentStrategy: new DeploymentStrategy(stack, 'MyDeploymentStrategy', {
rolloutStrategy: RolloutStrategy.linear({
growthFactor: 15,
deploymentDuration: cdk.Duration.minutes(30),
}),
}),
deployTo: [env1],
});
config.deploy(env2);

Template.fromStack(stack).hasResourceProperties('AWS::AppConfig::Deployment', {
ApplicationId: {
Ref: 'MyAppConfigB4B63E75',
},
EnvironmentId: {
Ref: 'MyAppConfigMyEnv1B9120FA1',
},
ConfigurationVersion: {
Ref: 'MyHostedConfig51D3877D',
},
ConfigurationProfileId: {
Ref: 'MyHostedConfigConfigurationProfile2E1A2BBC',
},
DeploymentStrategyId: {
Ref: 'MyDeploymentStrategy60D31FB0',
},
});
Template.fromStack(stack).hasResourceProperties('AWS::AppConfig::Deployment', {
ApplicationId: {
Ref: 'MyAppConfigB4B63E75',
},
EnvironmentId: {
Ref: 'MyAppConfigMyEnv2350437D6',
},
ConfigurationVersion: {
Ref: 'MyHostedConfig51D3877D',
},
ConfigurationProfileId: {
Ref: 'MyHostedConfigConfigurationProfile2E1A2BBC',
},
DeploymentStrategyId: {
Ref: 'MyDeploymentStrategy60D31FB0',
},
});
Template.fromStack(stack).resourceCountIs('AWS::AppConfig::Deployment', 2);
});

test('configuration with no environment associated and no deploy method used', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig', {
name: 'MyApplication',
});
new HostedConfiguration(stack, 'MyHostedConfig', {
content: ConfigurationContent.fromInlineText('This is my content'),
application: app,
deploymentStrategy: new DeploymentStrategy(stack, 'MyDeploymentStrategy', {
rolloutStrategy: RolloutStrategy.linear({
growthFactor: 15,
deploymentDuration: cdk.Duration.minutes(30),
}),
}),
});

Template.fromStack(stack).resourceCountIs('AWS::AppConfig::Deployment', 0);
});

test('configuration with two configurations specified', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig', {
Expand Down
Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@
"Name": "awsappconfigconfiguration-MyAppConfig-HostedEnvFromYaml-BB2C802A"
}
},
"MyAppConfigEnvDeployLater26FA1032": {
"Type": "AWS::AppConfig::Environment",
"Properties": {
"ApplicationId": {
"Ref": "MyAppConfigB4B63E75"
},
"Name": "awsappconfigconfiguration-MyAppConfig-EnvDeployLater-91038922"
}
},
"MyAppConfigParameterEnvD769FB19": {
"Type": "AWS::AppConfig::Environment",
"Properties": {
Expand Down Expand Up @@ -224,6 +233,26 @@
}
}
},
"MyHostedConfigFromJsonDeploymentEFECDBC4087F1": {
"Type": "AWS::AppConfig::Deployment",
"Properties": {
"ApplicationId": {
"Ref": "MyAppConfigB4B63E75"
},
"ConfigurationProfileId": {
"Ref": "MyHostedConfigFromJsonConfigurationProfile863E1E42"
},
"ConfigurationVersion": {
"Ref": "MyHostedConfigFromJsonD8CF9BE4"
},
"DeploymentStrategyId": {
"Ref": "MyDeployStrategy062CAEA2"
},
"EnvironmentId": {
"Ref": "MyAppConfigEnvDeployLater26FA1032"
}
}
},
"MyHostedConfigFromYamlConfigurationProfile7C77A435": {
"Type": "AWS::AppConfig::ConfigurationProfile",
"Properties": {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ new HostedConfiguration(stack, 'MyHostedConfig', {

// create basic config profile from add config version from file
const hostedEnvFromJson = appConfigApp.addEnvironment('HostedEnvFromJson');
new HostedConfiguration(stack, 'MyHostedConfigFromJson', {
const config = new HostedConfiguration(stack, 'MyHostedConfigFromJson', {
application: appConfigApp,
content: ConfigurationContent.fromInlineText('This is the configuration content'),
deployTo: [hostedEnvFromJson],
Expand All @@ -84,6 +84,10 @@ new HostedConfiguration(stack, 'MyHostedConfigFromYaml', {
deploymentStrategy,
});

// verify a configuration can be deployed through the deploy method
const envToDeployLater = appConfigApp.addEnvironment('EnvDeployLater');
config.deploy(envToDeployLater);

// ssm paramter as configuration source
const func = new Function(stack, 'MyValidatorFunction', {
runtime: Runtime.PYTHON_3_8,
Expand Down