From 9d79c518b47384a339b28146e2bc651a84b507f7 Mon Sep 17 00:00:00 2001 From: Pahud Hsieh Date: Thu, 25 Jul 2024 17:25:13 -0400 Subject: [PATCH] fix(appconfig): sourcedConfiguration doesn't use retrievalRole (#30733) ### Issue # (if applicable) Closes #30609 ### Reason for this change To refactor the retrievalRole creation logic. ### Description of changes ### Description of how you validated changes Unit tests: 1. configuration with retrievalRole undefined from bucket source should create a new role 2. configuration with retrievalRole defined should NOT create a new role and should use the passed role for the retrievalRoleArn 3. configuration with retrievalRole undefined from CodePipeline source should NOT create a new role Integ test: 1. update the existing integ test to assert a use case where the retrievalRole is provided. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../index.py | 24 +- .../index.js | 1 + .../aws-appconfig-configuration.assets.json | 23 +- .../aws-appconfig-configuration.template.json | 419 +++++++- .../manifest.json | 74 +- .../integ.configuration.js.snapshot/tree.json | 952 ++++++++++++------ .../aws-appconfig/test/integ.configuration.ts | 62 +- .../aws-appconfig/lib/configuration.ts | 29 +- .../aws-appconfig/test/configuration.test.ts | 149 ++- 9 files changed, 1393 insertions(+), 340 deletions(-) rename packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/{asset.e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00 => asset.0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c}/index.py (94%) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.44e9c4d7a5d3fd2d677e1a7e416b2b56f6b0104bd5eff9cac5557b4c65a9dc61/index.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00/index.py b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c/index.py similarity index 94% rename from packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00/index.py rename to packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c/index.py index 4015927d9c843..e4d3920e40c02 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00/index.py +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c/index.py @@ -5,6 +5,7 @@ import shutil import subprocess import tempfile +import urllib.parse from urllib.request import Request, urlopen from uuid import uuid4 from zipfile import ZipFile @@ -30,7 +31,8 @@ def handler(event, context): def cfn_error(message=None): - logger.error("| cfn_error: %s" % message) + if message: + logger.error("| cfn_error: %s" % message.encode()) cfn_send(event, context, CFN_FAILED, reason=message, physicalResourceId=event.get('PhysicalResourceId', None)) @@ -99,8 +101,8 @@ def cfn_error(message=None): if old_s3_dest == "s3:///": old_s3_dest = None - logger.info("| s3_dest: %s" % s3_dest) - logger.info("| old_s3_dest: %s" % old_s3_dest) + logger.info("| s3_dest: %s" % sanitize_message(s3_dest)) + logger.info("| old_s3_dest: %s" % sanitize_message(old_s3_dest)) # if we are creating a new resource, allocate a physical id for it # otherwise, we expect physical id to be relayed by cloudformation @@ -108,7 +110,7 @@ def cfn_error(message=None): physical_id = "aws.cdk.s3deployment.%s" % str(uuid4()) else: if not physical_id: - cfn_error("invalid request: request type is '%s' but 'PhysicalResourceId' is not defined" % {request_type}) + cfn_error("invalid request: request type is '%s' but 'PhysicalResourceId' is not defined" % request_type) return # delete or create/update (only if "retain_on_delete" is false) @@ -141,6 +143,20 @@ def cfn_error(message=None): logger.exception(e) cfn_error(str(e)) +#--------------------------------------------------------------------------------------------------- +# Sanitize the message to mitigate CWE-117 and CWE-93 vulnerabilities +def sanitize_message(message): + if not message: + return message + + # Sanitize the message to prevent log injection and HTTP response splitting + sanitized_message = message.replace('\n', '').replace('\r', '') + + # Encode the message to handle special characters + encoded_message = urllib.parse.quote(sanitized_message) + + return encoded_message + #--------------------------------------------------------------------------------------------------- # populate all files from s3_source_zips to a destination bucket def s3_deploy(s3_source_zips, s3_dest, user_metadata, system_metadata, prune, exclude, include, source_markers, extract): diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.44e9c4d7a5d3fd2d677e1a7e416b2b56f6b0104bd5eff9cac5557b4c65a9dc61/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.44e9c4d7a5d3fd2d677e1a7e416b2b56f6b0104bd5eff9cac5557b4c65a9dc61/index.js new file mode 100644 index 0000000000000..1002ba018e9fb --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/asset.44e9c4d7a5d3fd2d677e1a7e416b2b56f6b0104bd5eff9cac5557b4c65a9dc61/index.js @@ -0,0 +1 @@ +"use strict";var f=Object.create;var i=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,P=Object.prototype.hasOwnProperty;var A=(t,e)=>{for(var o in e)i(t,o,{get:e[o],enumerable:!0})},d=(t,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of C(e))!P.call(t,s)&&s!==o&&i(t,s,{get:()=>e[s],enumerable:!(r=I(e,s))||r.enumerable});return t};var l=(t,e,o)=>(o=t!=null?f(w(t)):{},d(e||!t||!t.__esModule?i(o,"default",{value:t,enumerable:!0}):o,t)),B=t=>d(i({},"__esModule",{value:!0}),t);var q={};A(q,{autoDeleteHandler:()=>S,handler:()=>H});module.exports=B(q);var h=require("@aws-sdk/client-s3");var y=l(require("https")),m=l(require("url")),a={sendHttpRequest:D,log:T,includeStackTraces:!0,userHandlerIndex:"./index"},p="AWSCDK::CustomResourceProviderFramework::CREATE_FAILED",L="AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID";function R(t){return async(e,o)=>{let r={...e,ResponseURL:"..."};if(a.log(JSON.stringify(r,void 0,2)),e.RequestType==="Delete"&&e.PhysicalResourceId===p){a.log("ignoring DELETE event caused by a failed CREATE event"),await u("SUCCESS",e);return}try{let s=await t(r,o),n=k(e,s);await u("SUCCESS",n)}catch(s){let n={...e,Reason:a.includeStackTraces?s.stack:s.message};n.PhysicalResourceId||(e.RequestType==="Create"?(a.log("CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored"),n.PhysicalResourceId=p):a.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(e)}`)),await u("FAILED",n)}}}function k(t,e={}){let o=e.PhysicalResourceId??t.PhysicalResourceId??t.RequestId;if(t.RequestType==="Delete"&&o!==t.PhysicalResourceId)throw new Error(`DELETE: cannot change the physical resource ID from "${t.PhysicalResourceId}" to "${e.PhysicalResourceId}" during deletion`);return{...t,...e,PhysicalResourceId:o}}async function u(t,e){let o={Status:t,Reason:e.Reason??t,StackId:e.StackId,RequestId:e.RequestId,PhysicalResourceId:e.PhysicalResourceId||L,LogicalResourceId:e.LogicalResourceId,NoEcho:e.NoEcho,Data:e.Data},r=m.parse(e.ResponseURL),s=`${r.protocol}//${r.hostname}/${r.pathname}?***`;a.log("submit response to cloudformation",s,o);let n=JSON.stringify(o),E={hostname:r.hostname,path:r.path,method:"PUT",headers:{"content-type":"","content-length":Buffer.byteLength(n,"utf8")}};await O({attempts:5,sleep:1e3},a.sendHttpRequest)(E,n)}async function D(t,e){return new Promise((o,r)=>{try{let s=y.request(t,n=>{n.resume(),!n.statusCode||n.statusCode>=400?r(new Error(`Unsuccessful HTTP response: ${n.statusCode}`)):o()});s.on("error",r),s.write(e),s.end()}catch(s){r(s)}})}function T(t,...e){console.log(t,...e)}function O(t,e){return async(...o)=>{let r=t.attempts,s=t.sleep;for(;;)try{return await e(...o)}catch(n){if(r--<=0)throw n;await b(Math.floor(Math.random()*s)),s*=2}}}async function b(t){return new Promise(e=>setTimeout(e,t))}var g="aws-cdk:auto-delete-objects",x=JSON.stringify({Version:"2012-10-17",Statement:[]}),c=new h.S3({}),H=R(S);async function S(t){switch(t.RequestType){case"Create":return;case"Update":return{PhysicalResourceId:(await F(t)).PhysicalResourceId};case"Delete":return N(t.ResourceProperties?.BucketName)}}async function F(t){let e=t,o=e.OldResourceProperties?.BucketName;return{PhysicalResourceId:e.ResourceProperties?.BucketName??o}}async function _(t){try{let e=(await c.getBucketPolicy({Bucket:t}))?.Policy??x,o=JSON.parse(e);o.Statement.push({Principal:"*",Effect:"Deny",Action:["s3:PutObject"],Resource:[`arn:aws:s3:::${t}/*`]}),await c.putBucketPolicy({Bucket:t,Policy:JSON.stringify(o)})}catch(e){if(e.name==="NoSuchBucket")throw e;console.log(`Could not set new object deny policy on bucket '${t}' prior to deletion.`)}}async function U(t){let e;do{e=await c.listObjectVersions({Bucket:t});let o=[...e.Versions??[],...e.DeleteMarkers??[]];if(o.length===0)return;let r=o.map(s=>({Key:s.Key,VersionId:s.VersionId}));await c.deleteObjects({Bucket:t,Delete:{Objects:r}})}while(e?.IsTruncated)}async function N(t){if(!t)throw new Error("No BucketName was provided.");try{if(!await W(t)){console.log(`Bucket does not have '${g}' tag, skipping cleaning.`);return}await _(t),await U(t)}catch(e){if(e.name==="NoSuchBucket"){console.log(`Bucket '${t}' does not exist.`);return}throw e}}async function W(t){return(await c.getBucketTagging({Bucket:t})).TagSet?.some(o=>o.Key===g&&o.Value==="true")}0&&(module.exports={autoDeleteHandler,handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/aws-appconfig-configuration.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/aws-appconfig-configuration.assets.json index 82c6d027afe5f..e49571ad44d85 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/aws-appconfig-configuration.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/aws-appconfig-configuration.assets.json @@ -1,6 +1,19 @@ { "version": "36.0.0", "files": { + "44e9c4d7a5d3fd2d677e1a7e416b2b56f6b0104bd5eff9cac5557b4c65a9dc61": { + "source": { + "path": "asset.44e9c4d7a5d3fd2d677e1a7e416b2b56f6b0104bd5eff9cac5557b4c65a9dc61", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "44e9c4d7a5d3fd2d677e1a7e416b2b56f6b0104bd5eff9cac5557b4c65a9dc61.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, "3322b7049fb0ed2b7cbb644a2ada8d1116ff80c32dca89e6ada846b5de26f961": { "source": { "path": "asset.3322b7049fb0ed2b7cbb644a2ada8d1116ff80c32dca89e6ada846b5de26f961.zip", @@ -14,15 +27,15 @@ } } }, - "e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00": { + "0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c": { "source": { - "path": "asset.e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00", + "path": "asset.0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00.zip", + "objectKey": "0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } @@ -53,7 +66,7 @@ } } }, - "bc60e6498e01ff2afc7280330547559fc0e8c9c15f5ff05fc560ea731f76277e": { + "f3c7c62924a5ad7e781abc71a57fb0540e3c9a334acad335dfe1da25e271f381": { "source": { "path": "aws-appconfig-configuration.template.json", "packaging": "file" @@ -61,7 +74,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "bc60e6498e01ff2afc7280330547559fc0e8c9c15f5ff05fc560ea731f76277e.json", + "objectKey": "f3c7c62924a5ad7e781abc71a57fb0540e3c9a334acad335dfe1da25e271f381.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/aws-appconfig-configuration.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/aws-appconfig-configuration.template.json index 2ff57c90bfa5f..2d3078ecab5ec 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/aws-appconfig-configuration.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/aws-appconfig-configuration.template.json @@ -586,6 +586,10 @@ "Type": "AWS::S3::Bucket", "Properties": { "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true" + }, { "Key": "aws-cdk:cr-owned:2255b7ad", "Value": "true" @@ -598,6 +602,143 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "MyBucketPolicyE7FBAC7B": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "MyBucketF68F3FF0" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:List*", + "s3:PutBucketPolicy" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "MyBucketAutoDeleteObjectsCustomResource2C28D565": { + "Type": "Custom::S3AutoDeleteObjects", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn" + ] + }, + "BucketName": { + "Ref": "MyBucketF68F3FF0" + } + }, + "DependsOn": [ + "MyBucketPolicyE7FBAC7B" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ] + } + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "44e9c4d7a5d3fd2d677e1a7e416b2b56f6b0104bd5eff9cac5557b4c65a9dc61.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + }, + "Runtime": { + "Fn::FindInMap": [ + "LatestNodeRuntimeMap", + { + "Ref": "AWS::Region" + }, + "value" + ] + }, + "Description": { + "Fn::Join": [ + "", + [ + "Lambda function for auto-deleting objects in ", + { + "Ref": "MyBucketF68F3FF0" + }, + " S3 bucket." + ] + ] + } + }, + "DependsOn": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + ] + }, "DeployConfigInBucketAwsCliLayerFC57D055": { "Type": "AWS::Lambda::LayerVersion", "Properties": { @@ -776,7 +917,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00.zip" + "S3Key": "0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c.zip" }, "Environment": { "Variables": { @@ -940,6 +1081,158 @@ } } }, + "DummyRoleA4B7EAF1": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "appconfig.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "DummyRoleDefaultPolicy68837380": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject", + "s3:GetObjectMetadata", + "s3:GetObjectVersion" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "MyBucketF68F3FF0" + }, + "/*" + ] + ] + } + }, + { + "Action": [ + "s3:GetBucketLocation", + "s3:GetBucketVersioning", + "s3:ListBucket", + "s3:ListBucketVersions" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "MyBucketF68F3FF0" + } + ] + ] + } + }, + { + "Action": "s3:ListAllMyBuckets", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "DummyRoleDefaultPolicy68837380", + "Roles": [ + { + "Ref": "DummyRoleA4B7EAF1" + } + ] + } + }, + "MyConfigFromBucketWithRoleDeploymentStrategy109EA62F": { + "Type": "AWS::AppConfig::DeploymentStrategy", + "Properties": { + "DeploymentDurationInMinutes": 20, + "FinalBakeTimeInMinutes": 10, + "GrowthFactor": 10, + "GrowthType": "EXPONENTIAL", + "Name": "awsappconfigconfiguration-MyWithRole-DeploymentStrategy-94CCA86F", + "ReplicateTo": "NONE" + }, + "DependsOn": [ + "DummyRoleDefaultPolicy68837380", + "DummyRoleA4B7EAF1" + ] + }, + "MyConfigFromBucketWithRole625F4717": { + "Type": "AWS::AppConfig::ConfigurationProfile", + "Properties": { + "ApplicationId": { + "Ref": "MyAppConfigB4B63E75" + }, + "Description": { + "Fn::Join": [ + "", + [ + "Sourced from ", + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "DeployConfigInBucketCustomResource91997C5B", + "SourceObjectKeys" + ] + } + ] + }, + " with defined role" + ] + ] + }, + "LocationUri": { + "Fn::Join": [ + "", + [ + "s3://", + { + "Ref": "MyBucketF68F3FF0" + }, + "/hello/world/file.txt" + ] + ] + }, + "Name": "awsappconfigconfiguration-MyConfigFromBucketWithRole-AE02C397", + "RetrievalRoleArn": { + "Fn::GetAtt": [ + "DummyRoleA4B7EAF1", + "Arn" + ] + } + }, + "DependsOn": [ + "DummyRoleDefaultPolicy68837380", + "DummyRoleA4B7EAF1" + ] + }, "MySecret8FE80B51": { "Type": "AWS::SecretsManager::Secret", "Properties": { @@ -1787,6 +2080,130 @@ } } }, + "Mappings": { + "LatestNodeRuntimeMap": { + "af-south-1": { + "value": "nodejs20.x" + }, + "ap-east-1": { + "value": "nodejs20.x" + }, + "ap-northeast-1": { + "value": "nodejs20.x" + }, + "ap-northeast-2": { + "value": "nodejs20.x" + }, + "ap-northeast-3": { + "value": "nodejs20.x" + }, + "ap-south-1": { + "value": "nodejs20.x" + }, + "ap-south-2": { + "value": "nodejs20.x" + }, + "ap-southeast-1": { + "value": "nodejs20.x" + }, + "ap-southeast-2": { + "value": "nodejs20.x" + }, + "ap-southeast-3": { + "value": "nodejs20.x" + }, + "ap-southeast-4": { + "value": "nodejs20.x" + }, + "ap-southeast-5": { + "value": "nodejs20.x" + }, + "ap-southeast-7": { + "value": "nodejs20.x" + }, + "ca-central-1": { + "value": "nodejs20.x" + }, + "ca-west-1": { + "value": "nodejs20.x" + }, + "cn-north-1": { + "value": "nodejs18.x" + }, + "cn-northwest-1": { + "value": "nodejs18.x" + }, + "eu-central-1": { + "value": "nodejs20.x" + }, + "eu-central-2": { + "value": "nodejs20.x" + }, + "eu-isoe-west-1": { + "value": "nodejs18.x" + }, + "eu-north-1": { + "value": "nodejs20.x" + }, + "eu-south-1": { + "value": "nodejs20.x" + }, + "eu-south-2": { + "value": "nodejs20.x" + }, + "eu-west-1": { + "value": "nodejs20.x" + }, + "eu-west-2": { + "value": "nodejs20.x" + }, + "eu-west-3": { + "value": "nodejs20.x" + }, + "il-central-1": { + "value": "nodejs20.x" + }, + "me-central-1": { + "value": "nodejs20.x" + }, + "me-south-1": { + "value": "nodejs20.x" + }, + "mx-central-1": { + "value": "nodejs20.x" + }, + "sa-east-1": { + "value": "nodejs20.x" + }, + "us-east-1": { + "value": "nodejs20.x" + }, + "us-east-2": { + "value": "nodejs20.x" + }, + "us-gov-east-1": { + "value": "nodejs18.x" + }, + "us-gov-west-1": { + "value": "nodejs18.x" + }, + "us-iso-east-1": { + "value": "nodejs18.x" + }, + "us-iso-west-1": { + "value": "nodejs18.x" + }, + "us-isob-east-1": { + "value": "nodejs18.x" + }, + "us-west-1": { + "value": "nodejs20.x" + }, + "us-west-2": { + "value": "nodejs20.x" + } + } + }, "Parameters": { "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/manifest.json index 13b08d3f38a1c..7570cc2bc0ed0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "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}/bc60e6498e01ff2afc7280330547559fc0e8c9c15f5ff05fc560ea731f76277e.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/f3c7c62924a5ad7e781abc71a57fb0540e3c9a334acad335dfe1da25e271f381.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -238,6 +238,36 @@ "data": "MyBucketF68F3FF0" } ], + "/aws-appconfig-configuration/MyBucket/Policy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyBucketPolicyE7FBAC7B" + } + ], + "/aws-appconfig-configuration/MyBucket/AutoDeleteObjectsCustomResource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "MyBucketAutoDeleteObjectsCustomResource2C28D565" + } + ], + "/aws-appconfig-configuration/LatestNodeRuntimeMap": [ + { + "type": "aws:cdk:logicalId", + "data": "LatestNodeRuntimeMap" + } + ], + "/aws-appconfig-configuration/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + } + ], + "/aws-appconfig-configuration/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F" + } + ], "/aws-appconfig-configuration/DeployConfigInBucket/AwsCliLayer/Resource": [ { "type": "aws:cdk:logicalId", @@ -286,6 +316,30 @@ "data": "MyConfigFromBucket064B5420" } ], + "/aws-appconfig-configuration/DummyRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DummyRoleA4B7EAF1" + } + ], + "/aws-appconfig-configuration/DummyRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DummyRoleDefaultPolicy68837380" + } + ], + "/aws-appconfig-configuration/MyConfigFromBucketWithRole/DeploymentStrategy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyConfigFromBucketWithRoleDeploymentStrategy109EA62F" + } + ], + "/aws-appconfig-configuration/MyConfigFromBucketWithRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyConfigFromBucketWithRole625F4717" + } + ], "/aws-appconfig-configuration/MySecret/Resource": [ { "type": "aws:cdk:logicalId", @@ -435,24 +489,6 @@ "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } - ], - "MyAppConfigEnvDeployLater26FA1032": [ - { - "type": "aws:cdk:logicalId", - "data": "MyAppConfigEnvDeployLater26FA1032", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] - } - ], - "MyHostedConfigFromJsonDeploymentFA00BC528601D": [ - { - "type": "aws:cdk:logicalId", - "data": "MyHostedConfigFromJsonDeploymentFA00BC528601D", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] - } ] }, "displayName": "aws-appconfig-configuration" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/tree.json index 47b7b5fd0a7d4..1c595e577ce95 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.js.snapshot/tree.json @@ -22,8 +22,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnApplication", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "HostedEnv": { @@ -43,14 +43,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Environment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "HostedEnvFromJson": { @@ -70,14 +70,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Environment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "HostedEnvFromYaml": { @@ -97,14 +97,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Environment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "ParameterEnv": { @@ -124,14 +124,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Environment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DocumentEnv": { @@ -151,14 +151,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Environment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "BucketEnv": { @@ -178,14 +178,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Environment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "SecretEnv": { @@ -205,14 +205,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Environment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "SecretEnvWithKey": { @@ -232,20 +232,20 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnEnvironment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Environment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.Application", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyDeployStrategy": { @@ -266,14 +266,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.DeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyHostedConfigFromFile": { @@ -299,14 +299,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.DeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "ConfigurationProfile": { @@ -323,8 +323,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -344,14 +344,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnHostedConfigurationVersion", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.HostedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyHostedConfig": { @@ -382,8 +382,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -403,8 +403,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnHostedConfigurationVersion", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Deployment8E5DB": { @@ -431,14 +431,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeployment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.HostedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyHostedConfigFromJson": { @@ -459,8 +459,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -480,8 +480,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnHostedConfigurationVersion", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Deployment3AC6E": { @@ -508,14 +508,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeployment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.HostedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyHostedConfigFromYaml": { @@ -536,8 +536,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -557,8 +557,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnHostedConfigurationVersion", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DeploymentD93A5": { @@ -585,14 +585,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeployment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.HostedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyValidatorFunction": { @@ -607,8 +607,8 @@ "id": "ImportServiceRole", "path": "aws-appconfig-configuration/MyValidatorFunction/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -646,14 +646,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -676,8 +676,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "AppConfigPermission": { @@ -697,14 +697,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.Function", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyParameter": { @@ -722,14 +722,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_ssm.CfnParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_ssm.StringParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyConfigFromParameter": { @@ -744,8 +744,8 @@ "id": "ImportRole", "path": "aws-appconfig-configuration/MyConfigFromParameter/Role/ImportRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -806,14 +806,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -870,8 +870,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Deployment28051": { @@ -897,14 +897,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeployment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.SourcedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyDocument": { @@ -933,8 +933,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_ssm.CfnDocument", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyConfigFromDocument": { @@ -949,8 +949,8 @@ "id": "ImportRole", "path": "aws-appconfig-configuration/MyConfigFromDocument/Role/ImportRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1011,14 +1011,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1051,8 +1051,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Deployment7A5BA": { @@ -1077,14 +1077,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeployment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.SourcedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyBucket": { @@ -1098,6 +1098,10 @@ "aws:cdk:cloudformation:type": "AWS::S3::Bucket", "aws:cdk:cloudformation:props": { "tags": [ + { + "key": "aws-cdk:auto-delete-objects", + "value": "true" + }, { "key": "aws-cdk:cr-owned:2255b7ad", "value": "true" @@ -1109,14 +1113,144 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.CfnBucket", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Policy": { + "id": "Policy", + "path": "aws-appconfig-configuration/MyBucket/Policy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appconfig-configuration/MyBucket/Policy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy", + "aws:cdk:cloudformation:props": { + "bucket": { + "Ref": "MyBucketF68F3FF0" + }, + "policyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:List*", + "s3:PutBucketPolicy" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "AutoDeleteObjectsCustomResource": { + "id": "AutoDeleteObjectsCustomResource", + "path": "aws-appconfig-configuration/MyBucket/AutoDeleteObjectsCustomResource", + "children": { + "Default": { + "id": "Default", + "path": "aws-appconfig-configuration/MyBucket/AutoDeleteObjectsCustomResource/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.Bucket", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "LatestNodeRuntimeMap": { + "id": "LatestNodeRuntimeMap", + "path": "aws-appconfig-configuration/LatestNodeRuntimeMap", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Custom::S3AutoDeleteObjectsCustomResourceProvider": { + "id": "Custom::S3AutoDeleteObjectsCustomResourceProvider", + "path": "aws-appconfig-configuration/Custom::S3AutoDeleteObjectsCustomResourceProvider", + "children": { + "Staging": { + "id": "Staging", + "path": "aws-appconfig-configuration/Custom::S3AutoDeleteObjectsCustomResourceProvider/Staging", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Role": { + "id": "Role", + "path": "aws-appconfig-configuration/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Handler": { + "id": "Handler", + "path": "aws-appconfig-configuration/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DeployConfigInBucket": { @@ -1135,22 +1269,22 @@ "id": "Stage", "path": "aws-appconfig-configuration/DeployConfigInBucket/AwsCliLayer/Code/Stage", "constructInfo": { - "fqn": "aws-cdk-lib.AssetStaging", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "AssetBucket": { "id": "AssetBucket", "path": "aws-appconfig-configuration/DeployConfigInBucket/AwsCliLayer/Code/AssetBucket", "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.BucketBase", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3_assets.Asset", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1169,22 +1303,22 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnLayerVersion", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.lambda_layer_awscli.AwsCliLayer", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "CustomResourceHandler": { "id": "CustomResourceHandler", "path": "aws-appconfig-configuration/DeployConfigInBucket/CustomResourceHandler", "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Asset1": { @@ -1195,22 +1329,22 @@ "id": "Stage", "path": "aws-appconfig-configuration/DeployConfigInBucket/Asset1/Stage", "constructInfo": { - "fqn": "aws-cdk-lib.AssetStaging", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "AssetBucket": { "id": "AssetBucket", "path": "aws-appconfig-configuration/DeployConfigInBucket/Asset1/AssetBucket", "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.BucketBase", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3_assets.Asset", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "CustomResource": { @@ -1221,14 +1355,14 @@ "id": "Default", "path": "aws-appconfig-configuration/DeployConfigInBucket/CustomResource/Default", "constructInfo": { - "fqn": "aws-cdk-lib.CfnResource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.CustomResource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Asset2": { @@ -1239,28 +1373,28 @@ "id": "Stage", "path": "aws-appconfig-configuration/DeployConfigInBucket/Asset2/Stage", "constructInfo": { - "fqn": "aws-cdk-lib.AssetStaging", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "AssetBucket": { "id": "AssetBucket", "path": "aws-appconfig-configuration/DeployConfigInBucket/Asset2/AssetBucket", "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.BucketBase", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3_assets.Asset", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3_deployment.BucketDeployment", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C": { @@ -1275,8 +1409,8 @@ "id": "ImportServiceRole", "path": "aws-appconfig-configuration/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1314,8 +1448,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DefaultPolicy": { @@ -1420,20 +1554,20 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Policy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Code": { @@ -1444,22 +1578,22 @@ "id": "Stage", "path": "aws-appconfig-configuration/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Code/Stage", "constructInfo": { - "fqn": "aws-cdk-lib.AssetStaging", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "AssetBucket": { "id": "AssetBucket", "path": "aws-appconfig-configuration/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Code/AssetBucket", "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.BucketBase", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3_assets.Asset", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1472,7 +1606,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "s3Key": "e976a796f036a5efbf44b99e44cfb5a961df08d8dbf7cd37e60bf216fb982a00.zip" + "s3Key": "0158f40002a8c211635388a87874fd4dcc3d68f525fe08a0fe0f014069ae539c.zip" }, "environment": { "variables": { @@ -1496,14 +1630,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.Function", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyConfigFromBucket": { @@ -1529,14 +1663,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.DeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Role": { @@ -1547,8 +1681,8 @@ "id": "ImportRole", "path": "aws-appconfig-configuration/MyConfigFromBucket/Role/ImportRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1635,14 +1769,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1695,14 +1829,238 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.SourcedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DummyRole": { + "id": "DummyRole", + "path": "aws-appconfig-configuration/DummyRole", + "children": { + "ImportDummyRole": { + "id": "ImportDummyRole", + "path": "aws-appconfig-configuration/DummyRole/ImportDummyRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-appconfig-configuration/DummyRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "appconfig.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-appconfig-configuration/DummyRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appconfig-configuration/DummyRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject", + "s3:GetObjectMetadata", + "s3:GetObjectVersion" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "MyBucketF68F3FF0" + }, + "/*" + ] + ] + } + }, + { + "Action": [ + "s3:GetBucketLocation", + "s3:GetBucketVersioning", + "s3:ListBucket", + "s3:ListBucketVersions" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Ref": "MyBucketF68F3FF0" + } + ] + ] + } + }, + { + "Action": "s3:ListAllMyBuckets", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "DummyRoleDefaultPolicy68837380", + "roles": [ + { + "Ref": "DummyRoleA4B7EAF1" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "MyConfigFromBucketWithRole": { + "id": "MyConfigFromBucketWithRole", + "path": "aws-appconfig-configuration/MyConfigFromBucketWithRole", + "children": { + "DeploymentStrategy": { + "id": "DeploymentStrategy", + "path": "aws-appconfig-configuration/MyConfigFromBucketWithRole/DeploymentStrategy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appconfig-configuration/MyConfigFromBucketWithRole/DeploymentStrategy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppConfig::DeploymentStrategy", + "aws:cdk:cloudformation:props": { + "deploymentDurationInMinutes": 20, + "finalBakeTimeInMinutes": 10, + "growthFactor": 10, + "growthType": "EXPONENTIAL", + "name": "awsappconfigconfiguration-MyWithRole-DeploymentStrategy-94CCA86F", + "replicateTo": "NONE" + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-appconfig-configuration/MyConfigFromBucketWithRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppConfig::ConfigurationProfile", + "aws:cdk:cloudformation:props": { + "applicationId": { + "Ref": "MyAppConfigB4B63E75" + }, + "description": { + "Fn::Join": [ + "", + [ + "Sourced from ", + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "DeployConfigInBucketCustomResource91997C5B", + "SourceObjectKeys" + ] + } + ] + }, + " with defined role" + ] + ] + }, + "locationUri": { + "Fn::Join": [ + "", + [ + "s3://", + { + "Ref": "MyBucketF68F3FF0" + }, + "/hello/world/file.txt" + ] + ] + }, + "name": "awsappconfigconfiguration-MyConfigFromBucketWithRole-AE02C397", + "retrievalRoleArn": { + "Fn::GetAtt": [ + "DummyRoleA4B7EAF1", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MySecret": { @@ -1719,14 +2077,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_secretsmanager.CfnSecret", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_secretsmanager.Secret", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyConfigFromSecret": { @@ -1752,14 +2110,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.DeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Role": { @@ -1770,8 +2128,8 @@ "id": "ImportRole", "path": "aws-appconfig-configuration/MyConfigFromSecret/Role/ImportRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1812,14 +2170,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -1844,14 +2202,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.SourcedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyKey": { @@ -1941,14 +2299,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_kms.CfnKey", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_kms.Key", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MySecretWithKey": { @@ -1971,14 +2329,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_secretsmanager.CfnSecret", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_secretsmanager.Secret", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyConfigFromSecretWithKey": { @@ -2004,14 +2362,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.DeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Role": { @@ -2022,8 +2380,8 @@ "id": "ImportRole", "path": "aws-appconfig-configuration/MyConfigFromSecretWithKey/Role/ImportRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -2074,14 +2432,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -2106,14 +2464,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.SourcedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyPipeline": { @@ -2161,14 +2519,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_kms.CfnKey", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_kms.Key", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "ArtifactsBucketEncryptionKeyAlias": { @@ -2191,14 +2549,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_kms.CfnAlias", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_kms.Alias", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "ArtifactsBucket": { @@ -2235,8 +2593,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.CfnBucket", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Policy": { @@ -2294,20 +2652,20 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_s3.Bucket", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Role": { @@ -2318,8 +2676,8 @@ "id": "ImportRole", "path": "aws-appconfig-configuration/MyPipeline/Role/ImportRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -2343,8 +2701,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DefaultPolicy": { @@ -2442,20 +2800,20 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Policy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -2554,8 +2912,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_codepipeline.CfnPipeline", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "beta": { @@ -2574,8 +2932,8 @@ "id": "ImportCodePipelineActionRole", "path": "aws-appconfig-configuration/MyPipeline/beta/Source/CodePipelineActionRole/ImportCodePipelineActionRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -2614,8 +2972,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DefaultPolicy": { @@ -2721,20 +3079,20 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Policy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, @@ -2765,8 +3123,8 @@ "id": "ImportCodePipelineActionRole", "path": "aws-appconfig-configuration/MyPipeline/prod/Deploy/CodePipelineActionRole/ImportCodePipelineActionRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -2805,8 +3163,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DefaultPolicy": { @@ -2910,20 +3268,20 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Policy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, @@ -2940,8 +3298,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_codepipeline.Pipeline", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MyConfigFromPipeline": { @@ -2967,14 +3325,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnDeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.DeploymentStrategy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -3001,36 +3359,36 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.CfnConfigurationProfile", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_appconfig.SourcedConfiguration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "aws-appconfig-configuration/BootstrapVersion", "constructInfo": { - "fqn": "aws-cdk-lib.CfnParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "aws-appconfig-configuration/CheckBootstrapVersion", "constructInfo": { - "fqn": "aws-cdk-lib.CfnRule", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.Stack", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "appconfig-configuration": { @@ -3057,22 +3415,22 @@ "id": "BootstrapVersion", "path": "appconfig-configuration/DefaultTest/DeployAssert/BootstrapVersion", "constructInfo": { - "fqn": "aws-cdk-lib.CfnParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "appconfig-configuration/DefaultTest/DeployAssert/CheckBootstrapVersion", "constructInfo": { - "fqn": "aws-cdk-lib.CfnRule", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.Stack", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, @@ -3097,8 +3455,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.App", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.ts index eb77c8f596506..3d44344688aa5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appconfig/test/integ.configuration.ts @@ -1,11 +1,12 @@ import { IntegTest } from '@aws-cdk/integ-tests-alpha'; -import { App, Duration, Stack, RemovalPolicy, Fn, SecretValue } from 'aws-cdk-lib'; +import { App, Duration, Stack, RemovalPolicy, Fn, SecretValue, ArnFormat } from 'aws-cdk-lib'; import { Artifact, Pipeline } from 'aws-cdk-lib/aws-codepipeline'; import { S3DeployAction, S3SourceAction } from 'aws-cdk-lib/aws-codepipeline-actions'; import { Key } from 'aws-cdk-lib/aws-kms'; import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; import { Bucket } from 'aws-cdk-lib/aws-s3'; import * as s3Deployment from 'aws-cdk-lib/aws-s3-deployment'; +import * as iam from 'aws-cdk-lib/aws-iam'; import { Secret } from 'aws-cdk-lib/aws-secretsmanager'; import { CfnDocument, StringParameter } from 'aws-cdk-lib/aws-ssm'; import { @@ -145,6 +146,7 @@ const bucketEnv = appConfigApp.addEnvironment('BucketEnv'); const bucket = new Bucket(stack, 'MyBucket', { versioned: true, removalPolicy: RemovalPolicy.DESTROY, + autoDeleteObjects: true, }); bucket.applyRemovalPolicy(RemovalPolicy.DESTROY); const deployment = new s3Deployment.BucketDeployment(stack, 'DeployConfigInBucket', { @@ -159,6 +161,21 @@ new SourcedConfiguration(stack, 'MyConfigFromBucket', { deployTo: [bucketEnv], }); +// create a dummyRole +const dummyRole = generateDummyRole(); + +// yet another SourcedConfiguration with defined retrievalRole +const sc = new SourcedConfiguration(stack, 'MyConfigFromBucketWithRole', { + application: appConfigApp, + location: ConfigurationSource.fromBucket(bucket, 'hello/world/file.txt'), + description: `Sourced from ${Fn.select(0, deployment.objectKeys)} with defined role`, + deployTo: [bucketEnv], + retrievalRole: dummyRole, +}); + +// ensure the dependency on the dummy role as well as its default policy +sc.node.addDependency(dummyRole, dummyRole.node.tryFindChild('DefaultPolicy') as iam.CfnPolicy); + // secrets manager as configuration source (without key) const secretEnv = appConfigApp.addEnvironment('SecretEnv'); const secret = new Secret(stack, 'MySecret', { @@ -229,4 +246,45 @@ new IntegTest(app, 'appconfig-configuration', { }, }, }, -}); \ No newline at end of file +}); + +function generateDummyRole(): iam.Role { + const role = new iam.Role(stack, 'DummyRole', { + assumedBy: new iam.ServicePrincipal('appconfig.amazonaws.com'), + }); + role.addToPrincipalPolicy(new iam.PolicyStatement({ + actions: [ + 's3:GetObject', + 's3:GetObjectMetadata', + 's3:GetObjectVersion', + ], + resources: [stack.formatArn({ + region: '', + account: '', + service: 's3', + arnFormat: ArnFormat.NO_RESOURCE_NAME, + resource: `${bucket.bucketName}/*`, + })], + })); + role.addToPrincipalPolicy(new iam.PolicyStatement({ + actions: [ + 's3:GetBucketLocation', + 's3:GetBucketVersioning', + 's3:ListBucket', + 's3:ListBucketVersions', + ], + resources: [stack.formatArn({ + region: '', + account: '', + service: 's3', + arnFormat: ArnFormat.NO_RESOURCE_NAME, + resource: bucket.bucketName, + })], + })); + role.addToPrincipalPolicy(new iam.PolicyStatement({ + actions: ['s3:ListAllMyBuckets'], + resources: ['*'], + })); + + return role; +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-appconfig/lib/configuration.ts b/packages/aws-cdk-lib/aws-appconfig/lib/configuration.ts index 1e2197a411a56..72c94cb9ad5ab 100644 --- a/packages/aws-cdk-lib/aws-appconfig/lib/configuration.ts +++ b/packages/aws-cdk-lib/aws-appconfig/lib/configuration.ts @@ -512,7 +512,7 @@ export interface SourcedConfigurationProps extends ConfigurationProps { /** * The IAM role to retrieve the configuration. * - * @default - A role is generated. + * @default - Auto generated if location type is not ConfigurationSourceType.CODE_PIPELINE otherwise no role specified. */ readonly retrievalRole?: iam.IRole; } @@ -564,16 +564,7 @@ export class SourcedConfiguration extends ConfigurationBase { this.locationUri = this.location.locationUri; this.versionNumber = props.versionNumber; this.sourceKey = this.location.key; - this.retrievalRole = props.retrievalRole || this.location.type != ConfigurationSourceType.CODE_PIPELINE - ? new iam.Role(this, 'Role', { - roleName: PhysicalName.GENERATE_IF_NEEDED, - assumedBy: new iam.ServicePrincipal('appconfig.amazonaws.com'), - inlinePolicies: { - ['AllowAppConfigReadFromSourcePolicy']: this.getPolicyForRole(), - }, - }) - : undefined; - + this.retrievalRole = props.retrievalRole ?? this.getRetrievalRole(); this._cfnConfigurationProfile = new CfnConfigurationProfile(this, 'Resource', { applicationId: this.applicationId, locationUri: this.locationUri, @@ -596,6 +587,22 @@ export class SourcedConfiguration extends ConfigurationBase { this.deployConfigToEnvironments(); } + private getRetrievalRole(): iam.Role | undefined { + // Check if the configuration source is not from CodePipeline + if (this.location.type != ConfigurationSourceType.CODE_PIPELINE) { + return new iam.Role(this, 'Role', { + roleName: PhysicalName.GENERATE_IF_NEEDED, + assumedBy: new iam.ServicePrincipal('appconfig.amazonaws.com'), + inlinePolicies: { + ['AllowAppConfigReadFromSourcePolicy']: this.getPolicyForRole(), + }, + }); + } else { + // No role is needed if the configuration source is from CodePipeline + return undefined; + } + } + private getPolicyForRole(): iam.PolicyDocument { const policy = new iam.PolicyStatement({ effect: iam.Effect.ALLOW, diff --git a/packages/aws-cdk-lib/aws-appconfig/test/configuration.test.ts b/packages/aws-cdk-lib/aws-appconfig/test/configuration.test.ts index 55a30e584d969..2f035acc71d13 100644 --- a/packages/aws-cdk-lib/aws-appconfig/test/configuration.test.ts +++ b/packages/aws-cdk-lib/aws-appconfig/test/configuration.test.ts @@ -1,4 +1,4 @@ -import { Template } from '../../assertions'; +import { Template, Match } from '../../assertions'; import { Artifact, Pipeline } from '../../aws-codepipeline'; import { S3DeployAction, S3SourceAction } from '../../aws-codepipeline-actions'; import * as iam from '../../aws-iam'; @@ -283,6 +283,153 @@ describe('configuration', () => { Template.fromStack(stack).resourceCountIs('AWS::AppConfig::Deployment', 2); }); + test('configuration with retrievalRole undefined from bucket source should create a new role', () => { + // GIVEN + const stack = new cdk.Stack(); + const app = new Application(stack, 'MyAppConfig', { + applicationName: 'MyApplication', + }); + const bucket = new Bucket(stack, 'MyBucket'); + + // WHEN + new SourcedConfiguration(stack, 'MySourcedConfig', { + versionNumber: '1', + location: ConfigurationSource.fromBucket(bucket, 'path/to/object'), + application: app, + }); + + // THEN + // should have a new role provisioned with AllowAppConfigReadFromSourcePolicy + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'appconfig.amazonaws.com', + }, + }, + ], + Version: '2012-10-17', + }, + Policies: [ + { + PolicyName: 'AllowAppConfigReadFromSourcePolicy', + }, + ], + }); + }); + + test('configuration with retrievalRole defined should NOT create a new role', () => { + // GIVEN + const stack = new cdk.Stack(); + const app = new Application(stack, 'MyAppConfig', { + applicationName: 'MyApplication', + }); + const bucket = new Bucket(stack, 'MyBucket'); + + // WHEN + new SourcedConfiguration(stack, 'MySourcedConfig', { + versionNumber: '1', + location: ConfigurationSource.fromBucket(bucket, 'path/to/object'), + application: app, + retrievalRole: new iam.Role(stack, 'MyRole', { + assumedBy: new iam.ServicePrincipal('appconfig.amazonaws.com'), + }), + }); + + // THEN + // should NOT have a new role provisioned with AllowAppConfigReadFromSourcePolicy + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', Match.not({ + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'appconfig.amazonaws.com', + }, + }, + ], + Version: '2012-10-17', + }, + Policies: [ + { + PolicyName: 'AllowAppConfigReadFromSourcePolicy', + }, + ], + })); + // and should use the passed role for the retrievalRoleArn + Template.fromStack(stack).hasResourceProperties('AWS::AppConfig::ConfigurationProfile', { + Name: 'MySourcedConfig', + RetrievalRoleArn: { 'Fn::GetAtt': ['MyRoleF48FFE04', 'Arn'] }, + }); + + }); + + test('configuration with retrievalRole undefined from CodePipeline source should NOT create a new role', () => { + // GIVEN + const stack = new cdk.Stack(); + const app = new Application(stack, 'MyAppConfig', { + applicationName: 'MyApplication', + }); + const bucket = new Bucket(stack, 'MyBucket'); + const sourceAction = new S3SourceAction({ + actionName: 'Source', + bucket: bucket, + bucketKey: 'hello/world/codepipeline.txt', + output: new Artifact('SourceOutput'), + }); + const deployAction = new S3DeployAction({ + actionName: 'Deploy', + input: Artifact.artifact('SourceOutput'), + bucket: bucket, + extract: true, + }); + const pipeline = new Pipeline(stack, 'MyPipeline', { + stages: [ + { + stageName: 'beta', + actions: [sourceAction], + }, + { + stageName: 'prod', + actions: [deployAction], + }, + ], + }); + + // WHEN + new SourcedConfiguration(stack, 'MySourcedConfig', { + versionNumber: '1', + location: ConfigurationSource.fromPipeline(pipeline), + application: app, + }); + + // THEN + // should NOT have a new role provisioned with AllowAppConfigReadFromSourcePolicy + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', Match.not({ + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'appconfig.amazonaws.com', + }, + }, + ], + Version: '2012-10-17', + }, + Policies: [ + { + PolicyName: 'AllowAppConfigReadFromSourcePolicy', + }, + ], + })); + }); + test('configuration with two configurations and no deployment strategy specified', () => { const stack = new cdk.Stack(); const app = new Application(stack, 'MyAppConfig', {