diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/appconfigenvironmentDefaultTestDeployAssert75BD28E7.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/appconfigenvironmentDefaultTestDeployAssert75BD28E7.assets.json new file mode 100644 index 0000000000000..947e7fb4d76ea --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/appconfigenvironmentDefaultTestDeployAssert75BD28E7.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "appconfigenvironmentDefaultTestDeployAssert75BD28E7.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/appconfigenvironmentDefaultTestDeployAssert75BD28E7.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/appconfigenvironmentDefaultTestDeployAssert75BD28E7.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/appconfigenvironmentDefaultTestDeployAssert75BD28E7.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/aws-appconfig-environment-grant.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/aws-appconfig-environment-grant.assets.json new file mode 100644 index 0000000000000..4b367676b80f6 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/aws-appconfig-environment-grant.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "2e2c29bc346bf7f1c2e5d10d1331a4f8ce28d4a11b0bd98b45ec6b7ca1d084f4": { + "source": { + "path": "aws-appconfig-environment-grant.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "2e2c29bc346bf7f1c2e5d10d1331a4f8ce28d4a11b0bd98b45ec6b7ca1d084f4.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/aws-appconfig-environment-grant.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/aws-appconfig-environment-grant.template.json new file mode 100644 index 0000000000000..c239fa7f96626 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/aws-appconfig-environment-grant.template.json @@ -0,0 +1,107 @@ +{ + "Resources": { + "MyApplicationForEnv1F597ED9": { + "Type": "AWS::AppConfig::Application", + "Properties": { + "Name": "AppForEnvTest" + } + }, + "MyEnvironment465E4DEA": { + "Type": "AWS::AppConfig::Environment", + "Properties": { + "ApplicationId": { + "Ref": "MyApplicationForEnv1F597ED9" + }, + "Name": "awsappconfigenvironmentgrant-MyEnvironment-6CC47125" + } + }, + "MyUserDC45028B": { + "Type": "AWS::IAM::User" + }, + "MyUserDefaultPolicy7B897426": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "appconfig:GetLatestConfiguration", + "appconfig:StartConfigurationSession" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appconfig:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":application/", + { + "Ref": "MyApplicationForEnv1F597ED9" + }, + "/environment/", + { + "Ref": "MyEnvironment465E4DEA" + }, + "/configuration/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyUserDefaultPolicy7B897426", + "Users": [ + { + "Ref": "MyUserDC45028B" + } + ] + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/integ.json new file mode 100644 index 0000000000000..3ced2a3f7b8ff --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "appconfig-environment/DefaultTest": { + "stacks": [ + "aws-appconfig-environment-grant" + ], + "assertionStack": "appconfig-environment/DefaultTest/DeployAssert", + "assertionStackName": "appconfigenvironmentDefaultTestDeployAssert75BD28E7" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/manifest.json new file mode 100644 index 0000000000000..b301be1ec7a07 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/manifest.json @@ -0,0 +1,131 @@ +{ + "version": "36.0.0", + "artifacts": { + "aws-appconfig-environment-grant.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-appconfig-environment-grant.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-appconfig-environment-grant": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-appconfig-environment-grant.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2e2c29bc346bf7f1c2e5d10d1331a4f8ce28d4a11b0bd98b45ec6b7ca1d084f4.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-appconfig-environment-grant.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-appconfig-environment-grant.assets" + ], + "metadata": { + "/aws-appconfig-environment-grant/MyApplicationForEnv/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyApplicationForEnv1F597ED9" + } + ], + "/aws-appconfig-environment-grant/MyEnvironment/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyEnvironment465E4DEA" + } + ], + "/aws-appconfig-environment-grant/MyUser/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyUserDC45028B" + } + ], + "/aws-appconfig-environment-grant/MyUser/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyUserDefaultPolicy7B897426" + } + ], + "/aws-appconfig-environment-grant/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-appconfig-environment-grant/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-appconfig-environment-grant" + }, + "appconfigenvironmentDefaultTestDeployAssert75BD28E7.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "appconfigenvironmentDefaultTestDeployAssert75BD28E7.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "appconfigenvironmentDefaultTestDeployAssert75BD28E7": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "appconfigenvironmentDefaultTestDeployAssert75BD28E7.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "appconfigenvironmentDefaultTestDeployAssert75BD28E7.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "appconfigenvironmentDefaultTestDeployAssert75BD28E7.assets" + ], + "metadata": { + "/appconfig-environment/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/appconfig-environment/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "appconfig-environment/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/tree.json new file mode 100644 index 0000000000000..a758a857de7f3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.js.snapshot/tree.json @@ -0,0 +1,243 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-appconfig-environment-grant": { + "id": "aws-appconfig-environment-grant", + "path": "aws-appconfig-environment-grant", + "children": { + "MyApplicationForEnv": { + "id": "MyApplicationForEnv", + "path": "aws-appconfig-environment-grant/MyApplicationForEnv", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appconfig-environment-grant/MyApplicationForEnv/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppConfig::Application", + "aws:cdk:cloudformation:props": { + "name": "AppForEnvTest" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appconfig.CfnApplication", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appconfig.Application", + "version": "0.0.0" + } + }, + "MyEnvironment": { + "id": "MyEnvironment", + "path": "aws-appconfig-environment-grant/MyEnvironment", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appconfig-environment-grant/MyEnvironment/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppConfig::Environment", + "aws:cdk:cloudformation:props": { + "applicationId": { + "Ref": "MyApplicationForEnv1F597ED9" + }, + "name": "awsappconfigenvironmentgrant-MyEnvironment-6CC47125" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appconfig.Environment", + "version": "0.0.0" + } + }, + "MyUser": { + "id": "MyUser", + "path": "aws-appconfig-environment-grant/MyUser", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appconfig-environment-grant/MyUser/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::User", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnUser", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-appconfig-environment-grant/MyUser/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appconfig-environment-grant/MyUser/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "appconfig:GetLatestConfiguration", + "appconfig:StartConfigurationSession" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appconfig:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":application/", + { + "Ref": "MyApplicationForEnv1F597ED9" + }, + "/environment/", + { + "Ref": "MyEnvironment465E4DEA" + }, + "/configuration/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyUserDefaultPolicy7B897426", + "users": [ + { + "Ref": "MyUserDC45028B" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.User", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-appconfig-environment-grant/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-appconfig-environment-grant/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "appconfig-environment": { + "id": "appconfig-environment", + "path": "appconfig-environment", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "appconfig-environment/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "appconfig-environment/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "appconfig-environment/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "appconfig-environment/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "appconfig-environment/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.ts new file mode 100644 index 0000000000000..ac01944f3c708 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.environment-grant.ts @@ -0,0 +1,24 @@ +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as iam from 'aws-cdk-lib/aws-iam'; + +import { App, Stack } from 'aws-cdk-lib'; +import { Application, Environment } from 'aws-cdk-lib/aws-appconfig'; + +const app = new App(); + +const stack = new Stack(app, 'aws-appconfig-environment-grant'); + +const appForEnv = new Application(stack, 'MyApplicationForEnv', { + applicationName: 'AppForEnvTest', +}); + +const env = new Environment(stack, 'MyEnvironment', { + application: appForEnv, +}); + +const user = new iam.User(stack, 'MyUser'); +env.grantReadConfig(user); + +new IntegTest(app, 'appconfig-environment', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-appconfig/README.md b/packages/aws-cdk-lib/aws-appconfig/README.md index ee5f4902b7902..4fb20a41ab0aa 100644 --- a/packages/aws-cdk-lib/aws-appconfig/README.md +++ b/packages/aws-cdk-lib/aws-appconfig/README.md @@ -3,13 +3,13 @@ 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: +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 +> 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: @@ -27,7 +27,7 @@ new appconfig.HostedConfiguration(this, 'MyHostedConfig', { }); ``` -This will create the application and environment for your configuration and then deploy your configuration to the +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). @@ -42,11 +42,11 @@ For an in-depth walkthrough of specific resources and how to use them, please ta [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 +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 +When creating an application through CDK, the name and description of an application are optional. Create a simple application: @@ -78,6 +78,25 @@ new appconfig.Environment(this, 'MyEnvironment', { 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) @@ -123,14 +142,14 @@ appconfig.DeploymentStrategy.fromDeploymentStrategyId( ## 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) +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 +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: @@ -208,8 +227,8 @@ new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { }); ``` -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 +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. @@ -231,7 +250,7 @@ new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { }); ``` -You can attach a deployment strategy (as described in the previous section) to your configuration to specify how you want your +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: @@ -252,7 +271,7 @@ new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { }); ``` -The `deployTo` parameter is used to specify which environments to deploy the configuration to. +The `deployTo` parameter is used to specify which environments to deploy the configuration to. A hosted configuration with `deployTo`: @@ -267,14 +286,14 @@ new appconfig.HostedConfiguration(this, 'MyHostedConfiguration', { }); ``` -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 +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. +> [!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. +The deployment order matches the order in which the configurations are declared. ```ts const app = new appconfig.Application(this, 'MyApp'); @@ -295,10 +314,10 @@ new appconfig.HostedConfiguration(this, 'MySecondHostedConfig', { }); ``` -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`. +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'); @@ -320,11 +339,11 @@ const firstConfig = new appconfig.HostedConfiguration(this, 'MyFirstHostedConfig env.addDeployment(secondConfig); ``` -Alternatively, you can defer multiple deployments in favor of -`IEnvironment.addDeployments`, which allows you to declare multiple +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`. +In this example the deployment order will be +`firstConfig`, then `secondConfig`, and finally `thirdConfig`. ```ts const app = new appconfig.Application(this, 'MyApp'); @@ -350,10 +369,10 @@ const firstConfig = new appconfig.HostedConfiguration(this, 'MyFirstHostedConfig 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. +Any mix of `deployTo`, `addDeployment`, and `addDeployments` is permitted. +The declaration order will be respected regardless of the approach used. -> [!IMPORTANT] +> [!IMPORTANT] > If none of these options are utilized, there will not be any deployments. ### SourcedConfiguration @@ -362,13 +381,13 @@ A sourced configuration represents configuration stored in any of the following: * Amazon S3 bucket * AWS Secrets Manager secret -* Systems Manager +* 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 +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 @@ -516,7 +535,7 @@ new appconfig.SourcedConfiguration(this, 'MySourcedConfiguration', { ## Extension -An extension augments your ability to inject logic or behavior at different points during the AWS AppConfig workflow of +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 @@ -608,8 +627,8 @@ new appconfig.Extension(this, 'MyExtension', { }); ``` -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 +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: diff --git a/packages/aws-cdk-lib/aws-appconfig/lib/environment.ts b/packages/aws-cdk-lib/aws-appconfig/lib/environment.ts index be0965edcbe42..08b3f7ed3b151 100644 --- a/packages/aws-cdk-lib/aws-appconfig/lib/environment.ts +++ b/packages/aws-cdk-lib/aws-appconfig/lib/environment.ts @@ -116,6 +116,25 @@ abstract class EnvironmentBase extends Resource implements IEnvironment, IExtens public addExtension(extension: IExtension) { this.extensible.addExtension(extension); } + + public grant(grantee: iam.IGrantable, ...actions: string[]) { + return iam.Grant.addToPrincipal({ + grantee, + actions, + resourceArns: [this.environmentArn], + }); + } + + public grantReadConfig(identity: iam.IGrantable): iam.Grant { + return iam.Grant.addToPrincipal({ + grantee: identity, + actions: [ + 'appconfig:GetLatestConfiguration', + 'appconfig:StartConfigurationSession', + ], + resourceArns: [`${this.environmentArn}/configuration/*`], + }); + } } /** @@ -543,4 +562,21 @@ export interface IEnvironment extends IResource { * @param extension The extension to create an association for */ addExtension(extension: IExtension): void; + + /** + * Adds an IAM policy statement associated with this environment to an IAM principal's policy. + * + * @param grantee the principal (no-op if undefined) + * @param actions the set of actions to allow (i.e., 'appconfig:GetLatestConfiguration', 'appconfig:StartConfigurationSession', etc.) + */ + grant(grantee: iam.IGrantable, ...actions: string[]): iam.Grant; + + /** + * Permits an IAM principal to perform read operations on this environment's configurations. + * + * Actions: GetLatestConfiguration, StartConfigurationSession. + * + * @param grantee Principal to grant read rights to + */ + grantReadConfig(grantee: iam.IGrantable): iam.Grant; } \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-appconfig/test/environment.test.ts b/packages/aws-cdk-lib/aws-appconfig/test/environment.test.ts index eb59aa6742333..398a5dbc728ee 100644 --- a/packages/aws-cdk-lib/aws-appconfig/test/environment.test.ts +++ b/packages/aws-cdk-lib/aws-appconfig/test/environment.test.ts @@ -829,4 +829,44 @@ describe('environment', () => { actual.resourceCountIs('AWS::AppConfig::Deployment', 1); }); + + test('grantReadConfig creates and attaches a policy with read only access to the principal', () => { + const stack = new cdk.Stack(); + const app = new Application(stack, 'MyAppConfig'); + const env = new Environment(stack, 'MyEnvironment', { + application: app, + }); + + const user = new iam.User(stack, 'MyUser'); + env.grantReadConfig(user); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: [ + 'appconfig:GetLatestConfiguration', + 'appconfig:StartConfigurationSession', + ], + Effect: 'Allow', + Resource: { + 'Fn::Join': ['', [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appconfig:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':application/', + { Ref: 'MyAppConfigB4B63E75' }, + '/environment/', + { Ref: 'MyEnvironment465E4DEA' }, + '/configuration/*', + ]], + }, + }, + ], + }, + }); + }); });