Skip to content
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
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 @@ -105,6 +105,7 @@
"ApplicationId": {
"Ref": "MyAppConfigB4B63E75"
},
"DeletionProtectionCheck": "BYPASS",
"LocationUri": "hosted",
"Name": "awsappconfigconfiguration-MyHostedConfigFromFile-8ED1123C"
}
Expand Down Expand Up @@ -399,6 +400,7 @@
"ApplicationId": {
"Ref": "MyAppConfigB4B63E75"
},
"DeletionProtectionCheck": "BYPASS",
"Description": "This is a configuration profile used for integ testing",
"LocationUri": {
"Fn::Join": [
Expand Down

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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Application,
ConfigurationContent,
ConfigurationSource,
DeletionProtectionCheck,
DeploymentStrategy,
HostedConfiguration,
JsonSchemaValidator,
Expand Down Expand Up @@ -57,6 +58,7 @@ const deploymentStrategy = new DeploymentStrategy(stack, 'MyDeployStrategy', {
new HostedConfiguration(stack, 'MyHostedConfigFromFile', {
application: appConfigApp,
content: ConfigurationContent.fromFile('config.json'),
deletionProtectionCheck: DeletionProtectionCheck.BYPASS,
});

// create basic config profile and add config version
Expand Down Expand Up @@ -110,6 +112,7 @@ new SourcedConfiguration(stack, 'MyConfigFromParameter', {
LambdaValidator.fromFunction(func),
],
deploymentStrategy,
deletionProtectionCheck: DeletionProtectionCheck.BYPASS,
});

// ssm document as configuration source
Expand Down
53 changes: 34 additions & 19 deletions packages/aws-cdk-lib/aws-appconfig/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,25 +96,6 @@ const user = new iam.User(this, 'MyUser');
env.grantReadConfig(user);
```

### Deletion Protection Check

You can enable [deletion protection](https://docs.aws.amazon.com/appconfig/latest/userguide/deletion-protection.html) on the environment by setting the `deletionProtectionCheck` property.

- ACCOUNT_DEFAULT: The default setting, which uses account-level deletion protection. To configure account-level deletion protection, use the UpdateAccountSettings API.
- APPLY: Instructs the deletion protection check to run, even if deletion protection is disabled at the account level. APPLY also forces the deletion protection check to run against resources created in the past hour, which are normally excluded from deletion protection checks.
- BYPASS: Instructs AWS AppConfig to bypass the deletion protection check and delete an environment even if deletion protection would have otherwise prevented it.

```ts
declare const application: appconfig.Application;
declare const alarm: cloudwatch.Alarm;
declare const compositeAlarm: cloudwatch.CompositeAlarm;

new appconfig.Environment(this, 'MyEnvironment', {
application,
deletionProtectionCheck: appconfig.DeletionProtectionCheck.APPLY,
});
```

## Deployment Strategy

[AWS AppConfig Deployment Strategy Documentation](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-deployment-strategy.html)
Expand Down Expand Up @@ -551,6 +532,40 @@ new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', {
});
```

## Deletion Protection Check

You can enable [deletion protection](https://docs.aws.amazon.com/appconfig/latest/userguide/deletion-protection.html) on the environment and configuration profile by setting the `deletionProtectionCheck` property.

- ACCOUNT_DEFAULT: The default setting, which uses account-level deletion protection. To configure account-level deletion protection, use the UpdateAccountSettings API.
- APPLY: Instructs the deletion protection check to run, even if deletion protection is disabled at the account level. APPLY also forces the deletion protection check to run against resources created in the past hour, which are normally excluded from deletion protection checks.
- BYPASS: Instructs AWS AppConfig to bypass the deletion protection check and delete an environment even if deletion protection would have otherwise prevented it.

```ts
declare const application: appconfig.Application;
declare const alarm: cloudwatch.Alarm;
declare const compositeAlarm: cloudwatch.CompositeAlarm;
declare const bucket: s3.Bucket;

// Environment deletion protection check
new appconfig.Environment(this, 'MyEnvironment', {
application,
deletionProtectionCheck: appconfig.DeletionProtectionCheck.APPLY,
});

// configuration profile with deletion protection check
new appconfig.HostedConfiguration(this, 'MyHostedConfigFromFile', {
application,
content: appconfig.ConfigurationContent.fromFile('config.json'),
deletionProtectionCheck: appconfig.DeletionProtectionCheck.BYPASS,
});

new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', {
application,
location: appconfig.ConfigurationSource.fromBucket(bucket, 'path/to/file.json'),
deletionProtectionCheck: appconfig.DeletionProtectionCheck.ACCOUNT_DEFAULT,
});
```

## Extension

An extension augments your ability to inject logic or behavior at different points during the AWS AppConfig workflow of
Expand Down
16 changes: 16 additions & 0 deletions packages/aws-cdk-lib/aws-appconfig/lib/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import * as sm from '../../aws-secretsmanager';
import * as ssm from '../../aws-ssm';
import { PhysicalName, Stack, ArnFormat, Names, RemovalPolicy } from '../../core';
import * as mimeTypes from 'mime-types';
import { DeletionProtectionCheck } from './util';

/**
* Options for the Configuration construct
Expand Down Expand Up @@ -76,6 +77,17 @@ export interface ConfigurationOptions {
* @default - None.
*/
readonly deploymentKey?: kms.IKey;

/**
* A parameter to configure deletion protection.
* Deletion protection prevents a user from deleting a configuration profile if your application has called
* either `GetLatestConfiguration` or `GetConfiguration` for the configuration profile during the specified interval.
*
* @see https://docs.aws.amazon.com/appconfig/latest/userguide/deletion-protection.html
*
* @default DeletionProtectionCheck.ACCOUNT_DEFAULT
*/
readonly deletionProtectionCheck?: DeletionProtectionCheck;
}

/**
Expand Down Expand Up @@ -186,6 +198,7 @@ abstract class ConfigurationBase extends Construct implements IConfiguration, IE

protected applicationId: string;
protected extensible!: ExtensibleBase;
protected deletionProtectionCheck?: DeletionProtectionCheck;

constructor(scope: Construct, id: string, props: ConfigurationProps) {
super(scope, id);
Expand All @@ -201,6 +214,7 @@ abstract class ConfigurationBase extends Construct implements IConfiguration, IE
this.description = props.description;
this.deployTo = props.deployTo;
this.deploymentKey = props.deploymentKey;
this.deletionProtectionCheck = props.deletionProtectionCheck;
this.deploymentStrategy = props.deploymentStrategy || new DeploymentStrategy(this, 'DeploymentStrategy', {
rolloutStrategy: RolloutStrategy.CANARY_10_PERCENT_20_MINUTES,
});
Expand Down Expand Up @@ -442,6 +456,7 @@ export class HostedConfiguration extends ConfigurationBase {
description: this.description,
type: this.type,
validators: this.validators,
deletionProtectionCheck: this.deletionProtectionCheck,
});
this.configurationProfileId = this._cfnConfigurationProfile.ref;
this.configurationProfileArn = Stack.of(this).formatArn({
Expand Down Expand Up @@ -584,6 +599,7 @@ export class SourcedConfiguration extends ConfigurationBase {
retrievalRoleArn: this.retrievalRole?.roleArn,
type: this.type,
validators: this.validators,
deletionProtectionCheck: this.deletionProtectionCheck,
});

this.configurationProfileId = this._cfnConfigurationProfile.ref;
Expand Down
56 changes: 56 additions & 0 deletions packages/aws-cdk-lib/aws-appconfig/test/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
JsonSchemaValidator,
ConfigurationContent,
RolloutStrategy,
DeletionProtectionCheck,
} from '../lib';

describe('configuration', () => {
Expand Down Expand Up @@ -789,6 +790,61 @@ describe('configuration', () => {
Template.fromStack(stack).resourceCountIs('AWS::AppConfig::Deployment', 0);
});

test.each([
DeletionProtectionCheck.ACCOUNT_DEFAULT,
DeletionProtectionCheck.APPLY,
DeletionProtectionCheck.BYPASS,
])('hosted configuration profile with deletion protection check', (deletionProtectionCheck) => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig');
new HostedConfiguration(stack, 'MyConfigurationProfile', {
name: 'TestConfigProfile',
application: app,
content: ConfigurationContent.fromInlineText('This is my content'),
deletionProtectionCheck,
deploymentStrategy: new DeploymentStrategy(stack, 'MyDeploymentStrategy', {
rolloutStrategy: RolloutStrategy.linear({
growthFactor: 15,
deploymentDuration: cdk.Duration.minutes(30),
}),
}),
});

Template.fromStack(stack).hasResourceProperties('AWS::AppConfig::ConfigurationProfile', {
Name: 'TestConfigProfile',
ApplicationId: {
Ref: 'MyAppConfigB4B63E75',
},
DeletionProtectionCheck: deletionProtectionCheck,
});
});

test.each([
DeletionProtectionCheck.ACCOUNT_DEFAULT,
DeletionProtectionCheck.APPLY,
DeletionProtectionCheck.BYPASS,
])('sourced configuration profile with deletion protection check', (deletionProtectionCheck) => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig');
const bucket = new Bucket(stack, 'MyBucket');

new SourcedConfiguration(stack, 'MySourcedConfig', {
name: 'TestConfigProfile',
versionNumber: '1',
location: ConfigurationSource.fromBucket(bucket, 'path/to/object'),
application: app,
deletionProtectionCheck,
});

Template.fromStack(stack).hasResourceProperties('AWS::AppConfig::ConfigurationProfile', {
Name: 'TestConfigProfile',
ApplicationId: {
Ref: 'MyAppConfigB4B63E75',
},
DeletionProtectionCheck: deletionProtectionCheck,
});
});

test('configuration profile with inline json schema validator', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig');
Expand Down
Loading