UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

644 lines (478 loc) 20.9 kB
# AWS AppConfig Construct Library This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. For a high level overview of what AWS AppConfig is and how it works, please take a look here: [What is AWS AppConfig?](https://docs.aws.amazon.com/appconfig/latest/userguide/what-is-appconfig.html) ## Basic Hosted Configuration Use Case > The main way most AWS AppConfig users utilize the service is through hosted configuration, which involves storing > configuration data directly within AWS AppConfig. An example use case: ```ts const app = new appconfig.Application(this, 'MyApp'); const env = new appconfig.Environment(this, 'MyEnv', { application: app, }); new appconfig.HostedConfiguration(this, 'MyHostedConfig', { application: app, deployTo: [env], content: appconfig.ConfigurationContent.fromInlineText('This is my configuration content.'), }); ``` This will create the application and environment for your configuration and then deploy your configuration to the specified environment. For more information about what these resources are: [Creating feature flags and free form configuration data in AWS AppConfig](https://docs.aws.amazon.com/appconfig/latest/userguide/creating-feature-flags-and-configuration-data.html). For more information about deploying configuration: [Deploying feature flags and configuration data in AWS AppConfig](https://docs.aws.amazon.com/appconfig/latest/userguide/deploying-feature-flags.html) ____ For an in-depth walkthrough of specific resources and how to use them, please take a look at the following sections. ## Application [AWS AppConfig Application Documentation](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-namespace.html) In AWS AppConfig, an application is simply an organizational construct like a folder. Configurations and environments are associated with the application. When creating an application through CDK, the name and description of an application are optional. Create a simple application: ```ts new appconfig.Application(this, 'MyApplication'); ``` ## Environment [AWS AppConfig Environment Documentation](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-environment.html) Basic environment with monitors: ```ts declare const application: appconfig.Application; declare const alarm: cloudwatch.Alarm; declare const compositeAlarm: cloudwatch.CompositeAlarm; new appconfig.Environment(this, 'MyEnvironment', { application, monitors: [ appconfig.Monitor.fromCloudWatchAlarm(alarm), appconfig.Monitor.fromCloudWatchAlarm(compositeAlarm), ], }); ``` Environment monitors also support L1 `CfnEnvironment.MonitorsProperty` constructs through the `fromCfnMonitorsProperty` method. However, this is not the recommended approach for CloudWatch alarms because a role will not be auto-generated if not provided. See [About the AWS AppConfig data plane service](https://docs.aws.amazon.com/appconfig/latest/userguide/about-data-plane.html) for more information. ### Permissions You can grant read permission on the environment's configurations with the grantReadConfig method as follows: ```ts import * as iam from 'aws-cdk-lib/aws-iam'; const app = new appconfig.Application(this, 'MyAppConfig'); const env = new appconfig.Environment(this, 'MyEnvironment', { application: app, }); const user = new iam.User(this, 'MyUser'); env.grantReadConfig(user); ``` ## Deployment Strategy [AWS AppConfig Deployment Strategy Documentation](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-deployment-strategy.html) A deployment strategy defines how a configuration will roll out. The roll out is defined by four parameters: deployment type, growth factor, deployment duration, and final bake time. Deployment strategy with predefined values: ```ts new appconfig.DeploymentStrategy(this, 'MyDeploymentStrategy', { rolloutStrategy: appconfig.RolloutStrategy.CANARY_10_PERCENT_20_MINUTES, }); ``` Deployment strategy with custom values: ```ts new appconfig.DeploymentStrategy(this, 'MyDeploymentStrategy', { rolloutStrategy: appconfig.RolloutStrategy.linear({ growthFactor: 20, deploymentDuration: Duration.minutes(30), finalBakeTime: Duration.minutes(30), }), }); ``` Referencing a deployment strategy by ID: ```ts appconfig.DeploymentStrategy.fromDeploymentStrategyId(this, 'MyImportedDeploymentStrategy', appconfig.DeploymentStrategyId.fromString('abc123')); ``` Referencing an AWS AppConfig predefined deployment strategy by ID: ```ts appconfig.DeploymentStrategy.fromDeploymentStrategyId( this, 'MyImportedPredefinedDeploymentStrategy', appconfig.DeploymentStrategyId.CANARY_10_PERCENT_20_MINUTES, ); ``` ## Configuration A configuration is a higher-level construct that can either be a `HostedConfiguration` (stored internally through AWS AppConfig) or a `SourcedConfiguration` (stored in an Amazon S3 bucket, AWS Secrets Manager secrets, Systems Manager (SSM) Parameter Store parameters, SSM documents, or AWS CodePipeline). This construct manages deployments on creation. ### HostedConfiguration A hosted configuration represents configuration stored in the AWS AppConfig hosted configuration store. A hosted configuration takes in the configuration content and associated AWS AppConfig application. On construction of a hosted configuration, the configuration is deployed. You can define hosted configuration content using any of the following ConfigurationContent methods: * `fromFile` - Defines the hosted configuration content from a file (you can specify a relative path). The content type will be determined by the file extension unless specified. ```ts declare const application: appconfig.Application; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromFile('config.json'), }); ``` * `fromInlineText` - Defines the hosted configuration from inline text. The content type will be set as `text/plain`. ```ts declare const application: appconfig.Application; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromInlineText('This is my configuration content.'), }); ``` * `fromInlineJson` - Defines the hosted configuration from inline JSON. The content type will be set as `application/json` unless specified. ```ts declare const application: appconfig.Application; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromInlineJson('{}'), }); ``` * `fromInlineYaml` - Defines the hosted configuration from inline YAML. The content type will be set as `application/x-yaml`. ```ts declare const application: appconfig.Application; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromInlineYaml('MyConfig: This is my content.'), }); ``` * `fromInline` - Defines the hosted configuration from user-specified content types. The content type will be set as `application/octet-stream` unless specified. ```ts declare const application: appconfig.Application; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromInline('This is my configuration content.'), }); ``` AWS AppConfig supports the following types of configuration profiles. * **[Feature flag](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-configuration-and-profile-feature-flags.html)**: Use a feature flag configuration to turn on new features that require a timely deployment, such as a product launch or announcement. * **[Freeform](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-free-form-configurations-creating.html)**: Use a freeform configuration to carefully introduce changes to your application. A hosted configuration with type: ```ts declare const application: appconfig.Application; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromInlineText('This is my configuration content.'), type: appconfig.ConfigurationType.FEATURE_FLAGS, }); ``` When you create a configuration and configuration profile, you can specify up to two validators. A validator ensures that your configuration data is syntactically and semantically correct. You can create validators in either JSON Schema or as an AWS Lambda function. See [About validators](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-configuration-and-profile.html#appconfig-creating-configuration-and-profile-validators) for more information. When you import a JSON Schema validator from a file, you can pass in a relative path. A hosted configuration with validators: ```ts declare const application: appconfig.Application; declare const fn: lambda.Function; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromInlineText('This is my configuration content.'), validators: [ appconfig.JsonSchemaValidator.fromFile('schema.json'), appconfig.LambdaValidator.fromFunction(fn), ], }); ``` You can attach a deployment strategy (as described in the previous section) to your configuration to specify how you want your configuration to roll out. A hosted configuration with a deployment strategy: ```ts declare const application: appconfig.Application; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromInlineText('This is my configuration content.'), deploymentStrategy: new appconfig.DeploymentStrategy(this, 'MyDeploymentStrategy', { rolloutStrategy: appconfig.RolloutStrategy.linear({ growthFactor: 15, deploymentDuration: Duration.minutes(30), finalBakeTime: Duration.minutes(15), }), }), }); ``` The `deployTo` parameter is used to specify which environments to deploy the configuration to. A hosted configuration with `deployTo`: ```ts declare const application: appconfig.Application; declare const env: appconfig.Environment; new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { application, content: appconfig.ConfigurationContent.fromInlineText('This is my configuration content.'), deployTo: [env], }); ``` When more than one configuration is set to deploy to the same environment, the deployments will occur one at a time. This is done to satisfy [AppConfig's constraint](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-deploying.html): > [!NOTE] > You can only deploy one configuration at a time to an environment. > However, you can deploy one configuration each to different environments at the same time. The deployment order matches the order in which the configurations are declared. ```ts const app = new appconfig.Application(this, 'MyApp'); const env = new appconfig.Environment(this, 'MyEnv', { application: app, }); new appconfig.HostedConfiguration(this, 'MyFirstHostedConfig', { application: app, deployTo: [env], content: appconfig.ConfigurationContent.fromInlineText('This is my first configuration content.'), }); new appconfig.HostedConfiguration(this, 'MySecondHostedConfig', { application: app, deployTo: [env], content: appconfig.ConfigurationContent.fromInlineText('This is my second configuration content.'), }); ``` If an application would benefit from a deployment order that differs from the declared order, you can defer the decision by using `IEnvironment.addDeployment` rather than the `deployTo` property. In this example, `firstConfig` will be deployed before `secondConfig`. ```ts const app = new appconfig.Application(this, 'MyApp'); const env = new appconfig.Environment(this, 'MyEnv', { application: app, }); const secondConfig = new appconfig.HostedConfiguration(this, 'MySecondHostedConfig', { application: app, content: appconfig.ConfigurationContent.fromInlineText('This is my second configuration content.'), }); const firstConfig = new appconfig.HostedConfiguration(this, 'MyFirstHostedConfig', { application: app, deployTo: [env], content: appconfig.ConfigurationContent.fromInlineText('This is my first configuration content.'), }); env.addDeployment(secondConfig); ``` Alternatively, you can defer multiple deployments in favor of `IEnvironment.addDeployments`, which allows you to declare multiple configurations in the order they will be deployed. In this example the deployment order will be `firstConfig`, then `secondConfig`, and finally `thirdConfig`. ```ts const app = new appconfig.Application(this, 'MyApp'); const env = new appconfig.Environment(this, 'MyEnv', { application: app, }); const secondConfig = new appconfig.HostedConfiguration(this, 'MySecondHostedConfig', { application: app, content: appconfig.ConfigurationContent.fromInlineText('This is my second configuration content.'), }); const thirdConfig = new appconfig.HostedConfiguration(this, 'MyThirdHostedConfig', { application: app, content: appconfig.ConfigurationContent.fromInlineText('This is my third configuration content.'), }); const firstConfig = new appconfig.HostedConfiguration(this, 'MyFirstHostedConfig', { application: app, content: appconfig.ConfigurationContent.fromInlineText('This is my first configuration content.'), }); env.addDeployments(firstConfig, secondConfig, thirdConfig); ``` Any mix of `deployTo`, `addDeployment`, and `addDeployments` is permitted. The declaration order will be respected regardless of the approach used. > [!IMPORTANT] > If none of these options are utilized, there will not be any deployments. ### SourcedConfiguration A sourced configuration represents configuration stored in any of the following: * Amazon S3 bucket * AWS Secrets Manager secret * Systems Manager * (SSM) Parameter Store parameter * SSM document * AWS CodePipeline. A sourced configuration takes in the location source construct and optionally a version number to deploy. On construction of a sourced configuration, the configuration is deployed only if a version number is specified. ### S3 Use an Amazon S3 bucket to store a configuration. ```ts declare const application: appconfig.Application; const bucket = new s3.Bucket(this, 'MyBucket', { versioned: true, }); new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromBucket(bucket, 'path/to/file.json'), }); ``` Use an encrypted bucket: ```ts declare const application: appconfig.Application; const bucket = new s3.Bucket(this, 'MyBucket', { versioned: true, encryption: s3.BucketEncryption.KMS, }); new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromBucket(bucket, 'path/to/file.json'), }); ``` ### AWS Secrets Manager secret Use a Secrets Manager secret to store a configuration. ```ts declare const application: appconfig.Application; declare const secret: secrets.Secret; new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromSecret(secret), }); ``` ### SSM Parameter Store parameter Use an SSM parameter to store a configuration. ```ts declare const application: appconfig.Application; declare const parameter: ssm.StringParameter; new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromParameter(parameter), versionNumber: '1', }); ``` ### SSM document Use an SSM document to store a configuration. ```ts declare const application: appconfig.Application; declare const document: ssm.CfnDocument; new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromCfnDocument(document), }); ``` ### AWS CodePipeline Use an AWS CodePipeline pipeline to store a configuration. ```ts declare const application: appconfig.Application; declare const pipeline: codepipeline.Pipeline; new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromPipeline(pipeline), }); ``` Similar to a hosted configuration, a sourced configuration can optionally take in a type, validators, a `deployTo` parameter, and a deployment strategy. A sourced configuration with type: ```ts declare const application: appconfig.Application; declare const bucket: s3.Bucket; new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromBucket(bucket, 'path/to/file.json'), type: appconfig.ConfigurationType.FEATURE_FLAGS, name: 'MyConfig', description: 'This is my sourced configuration from CDK.', }); ``` A sourced configuration with validators: ```ts declare const application: appconfig.Application; declare const bucket: s3.Bucket; declare const fn: lambda.Function; new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromBucket(bucket, 'path/to/file.json'), validators: [ appconfig.JsonSchemaValidator.fromFile('schema.json'), appconfig.LambdaValidator.fromFunction(fn), ], }); ``` A sourced configuration with a deployment strategy: ```ts declare const application: appconfig.Application; declare const bucket: s3.Bucket; new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { application, location: appconfig.ConfigurationSource.fromBucket(bucket, 'path/to/file.json'), deploymentStrategy: new appconfig.DeploymentStrategy(this, 'MyDeploymentStrategy', { rolloutStrategy: appconfig.RolloutStrategy.linear({ growthFactor: 15, deploymentDuration: Duration.minutes(30), finalBakeTime: Duration.minutes(15), }), }), }); ``` ## Extension An extension augments your ability to inject logic or behavior at different points during the AWS AppConfig workflow of creating or deploying a configuration. See: https://docs.aws.amazon.com/appconfig/latest/userguide/working-with-appconfig-extensions.html ### AWS Lambda destination Use an AWS Lambda as the event destination for an extension. ```ts declare const fn: lambda.Function; new appconfig.Extension(this, 'MyExtension', { actions: [ new appconfig.Action({ actionPoints: [appconfig.ActionPoint.ON_DEPLOYMENT_START], eventDestination: new appconfig.LambdaDestination(fn), }), ], }); ``` Lambda extension with parameters: ```ts declare const fn: lambda.Function; new appconfig.Extension(this, 'MyExtension', { actions: [ new appconfig.Action({ actionPoints: [appconfig.ActionPoint.ON_DEPLOYMENT_START], eventDestination: new appconfig.LambdaDestination(fn), }), ], parameters: [ appconfig.Parameter.required('testParam', 'true'), appconfig.Parameter.notRequired('testNotRequiredParam'), ] }); ``` ### Amazon Simple Queue Service (SQS) destination Use a queue as the event destination for an extension. ```ts declare const queue: sqs.Queue; new appconfig.Extension(this, 'MyExtension', { actions: [ new appconfig.Action({ actionPoints: [appconfig.ActionPoint.ON_DEPLOYMENT_START], eventDestination: new appconfig.SqsDestination(queue), }), ], }); ``` ### Amazon Simple Notification Service (SNS) destination Use an SNS topic as the event destination for an extension. ```ts declare const topic: sns.Topic; new appconfig.Extension(this, 'MyExtension', { actions: [ new appconfig.Action({ actionPoints: [appconfig.ActionPoint.ON_DEPLOYMENT_START], eventDestination: new appconfig.SnsDestination(topic), }), ], }); ``` ### Amazon EventBridge destination Use the default event bus as the event destination for an extension. ```ts const bus = events.EventBus.fromEventBusName(this, 'MyEventBus', 'default'); new appconfig.Extension(this, 'MyExtension', { actions: [ new appconfig.Action({ actionPoints: [appconfig.ActionPoint.ON_DEPLOYMENT_START], eventDestination: new appconfig.EventBridgeDestination(bus), }), ], }); ``` You can also add extensions and their associations directly by calling `onDeploymentComplete()` or any other action point method on the AWS AppConfig application, configuration, or environment resource. To add an association to an existing extension, you can call `addExtension()` on the resource. Adding an association to an AWS AppConfig application: ```ts declare const application: appconfig.Application; declare const extension: appconfig.Extension; declare const lambdaDestination: appconfig.LambdaDestination; application.addExtension(extension); application.onDeploymentComplete(lambdaDestination); ```