diff --git a/.devcontainer.json b/.devcontainer.json
index 6003d00e23dac..79ad867c5028a 100644
--- a/.devcontainer.json
+++ b/.devcontainer.json
@@ -4,5 +4,6 @@
"postCreateCommand": "yarn build --skip-test --no-bail --skip-prereqs --skip-compat",
"extensions": [
"dbaeumer.vscode-eslint@2.1.5"
- ]
+ ],
+ "remoteUser": "superchain"
}
diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
similarity index 56%
rename from .github/ISSUE_TEMPLATE/bug.yml
rename to .github/ISSUE_TEMPLATE/bug-report.yml
index f77fa5beb193e..aa7f959e2ca80 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -1,44 +1,64 @@
-name: Bug Report
+---
+name: "🐛 Bug Report"
description: Report a bug
-title: "(module name): short issue description"
+title: "(module name): (short issue description)"
labels: [bug, needs-triage]
+assignees: []
body:
- type: textarea
- id: problem
+ id: description
attributes:
- label: What is the problem?
+ label: Describe the bug
+ description: What is the problem? A clear and concise description of the bug.
validations:
required: true
-
- type: textarea
- id: reproduction
+ id: expected
attributes:
- label: Reproduction Steps
+ label: Expected Behavior
description: |
- Minimal amount of code that causes the bug (if possible) or a reference.
-
- The code sample should be an SSCCE. See http://sscce.org/ for details.
- In short, provide a code sample that we can copy/paste, run and reproduce.
+ What did you expect to happen?
validations:
required: true
-
- type: textarea
- id: expected
+ id: current
attributes:
- label: What did you expect to happen?
+ label: Current Behavior
description: |
- What were you trying to achieve by performing the steps above?
+ What actually happened?
+
+ Please include full errors, uncaught exceptions, stack traces, and relevant logs.
+ If service responses are relevant, please include wire logs.
validations:
required: true
-
- type: textarea
- id: actual
+ id: reproduction
attributes:
- label: What actually happened?
+ label: Reproduction Steps
description: |
- What is the unexpected behavior you were seeing? If you got an error, paste it here.
+ Provide a self-contained, concise snippet of code that can be used to reproduce the issue.
+ For more complex issues provide a repo with the smallest sample that reproduces the bug.
+
+ Avoid including business logic or unrelated code, it makes diagnosis more difficult.
+ The code sample should be an SSCCE. See http://sscce.org/ for details. In short, please provide a code sample that we can copy/paste, run and reproduce.
validations:
required: true
+ - type: textarea
+ id: solution
+ attributes:
+ label: Possible Solution
+ description: |
+ Suggest a fix/reason for the bug
+ validations:
+ required: false
+ - type: textarea
+ id: context
+ attributes:
+ label: Additional Information/Context
+ description: |
+ Anything else that might be relevant for troubleshooting this bug. Providing context helps us come up with a solution that is most useful in the real world.
+ validations:
+ required: false
- type: input
id: cdk-version
@@ -99,10 +119,3 @@ body:
e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. associated pull-request, stackoverflow, slack, etc
validations:
required: false
-
- - type: markdown
- attributes:
- value: |
- ---
-
- This is :bug: Bug Report
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index ebbc970f83c09..b4c0c5049128b 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,6 @@
+---
blank_issues_enabled: false
contact_links:
- - name: Stackoverflow
- url: https://stackoverflow.com/questions/tagged/aws-cdk
- about: Please ask and answer questions here.
+ - name: 💬 General Question
+ url: https://github.com/aws/aws-cdk/discussions/categories/q-a
+ about: Please ask and answer questions as a discussion thread
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/doc.yml b/.github/ISSUE_TEMPLATE/doc.yml
deleted file mode 100644
index 974a752cac810..0000000000000
--- a/.github/ISSUE_TEMPLATE/doc.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: Documentation Issue
-description: Issue in the reference documentation or developer guide
-title: "(module name): short issue description"
-labels: [feature-request, documentation, needs-triage]
-body:
- - type: markdown
- attributes:
- value: |
- Developer guide? Raise issue/pr here: https://github.com/awsdocs/aws-cdk-guide
-
- Want to help? Submit a pull request here: https://github.com/aws/aws-cdk
-
- - type: input
- id: doc-link
- attributes:
- label: link to reference doc page
- validations:
- required: false
-
- - type: textarea
- id: issue
- attributes:
- label: Describe your issue?
- validations:
- required: true
-
- - type: markdown
- attributes:
- value: |
- ---
-
- This is a 📕 documentation issue
diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml
new file mode 100644
index 0000000000000..c068514d136c5
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation.yml
@@ -0,0 +1,23 @@
+---
+name: "📕 Documentation Issue"
+description: Report an issue in the API Reference documentation or Developer Guide
+title: "(short issue description)"
+labels: [documentation, needs-triage]
+assignees: []
+body:
+ - type: textarea
+ id: description
+ attributes:
+ label: Describe the issue
+ description: A clear and concise description of the issue.
+ validations:
+ required: true
+
+ - type: textarea
+ id: links
+ attributes:
+ label: Links
+ description: |
+ Include links to affected documentation page(s).
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
index a16053f420a82..23c385d1ef6d1 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.yml
+++ b/.github/ISSUE_TEMPLATE/feature-request.yml
@@ -1,56 +1,59 @@
-name: Feature Request
-description: Request a new feature
-title: "(module name): short issue description"
+---
+name: 🚀 Feature Request
+description: Suggest an idea for this project
+title: "(short issue description)"
labels: [feature-request, needs-triage]
+assignees: []
body:
- type: textarea
id: description
attributes:
- label: Description
- description: Short description of the feature you are proposing.
+ label: Describe the feature
+ description: A clear and concise description of the feature you are proposing.
validations:
required: true
-
- type: textarea
id: use-case
attributes:
label: Use Case
description: |
- Why do you need this feature?
+ Why do you need this feature? For example: "I'm always frustrated when..."
validations:
- required: true
-
+ required: true
- type: textarea
id: solution
attributes:
label: Proposed Solution
description: |
- Please include prototype/workaround/sketch/reference implementation.
+ Suggest how to implement the addition or change. Please include prototype/workaround/sketch/reference implementation.
validations:
- required: true
-
+ required: false
- type: textarea
id: other
attributes:
- label: Other information
+ label: Other Information
description: |
- e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. associated pull-request, stackoverflow, slack, etc
+ Any alternative solutions or features you considered, a more detailed explanation, stack traces, related issues, links for context, etc.
validations:
required: false
-
- type: checkboxes
- id: acknowledgments
+ id: ack
attributes:
- label: Acknowledge
+ label: Acknowledgements
options:
- label: I may be able to implement this feature request
required: false
- label: This feature might incur a breaking change
required: false
-
- - type: markdown
+ - type: input
+ id: sdk-version
attributes:
- value: |
- ---
-
- This is a :rocket: Feature Request
+ label: CDK version used
+ validations:
+ required: true
+ - type: input
+ id: environment
+ attributes:
+ label: Environment details (OS name and version, etc.)
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/general-issue.yml b/.github/ISSUE_TEMPLATE/general-issue.yml
deleted file mode 100644
index 61119a33a761c..0000000000000
--- a/.github/ISSUE_TEMPLATE/general-issue.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-name: General Issue
-description: Create a new issue
-title: "(module name): short issue description"
-labels: [needs-triage, guidance]
-body:
- - type: markdown
- attributes:
- value: |
- If there is an issue regarding developer guide, please create an issue [here](https://github.com/awsdocs/aws-cdk-guide/issues).
-
- - type: input
- id: issue
- attributes:
- label: General Issue
- description: |
- For support questions, please first reference our [documentation](https://docs.aws.amazon.com/cdk/api/latest), then use [Stackoverflow](https://stackoverflow.com/questions/tagged/aws-cdk). This repository's issues are intended for feature requests and bug reports.
- validations:
- required: true
-
- - type: textarea
- id: question
- attributes:
- label: The Question
- description: |
- Ask your question here. Include any details relevant. Make sure you are not falling prey to the [X/Y problem](http://xyproblem.info)!
- validations:
- required: true
-
- - type: input
- id: cdk-version
- attributes:
- label: CDK CLI Version
- description: Output of `cdk version`
- validations:
- required: true
-
- - type: input
- id: framework-version
- attributes:
- label: Framework Version
- validations:
- required: false
-
- - type: input
- id: node-version
- attributes:
- label: Node.js Version
- validations:
- required: false
-
- - type: input
- id: operating-system
- attributes:
- label: OS
- validations:
- required: false
-
- - type: dropdown
- id: language
- attributes:
- label: Language
- multiple: true
- options:
- - Typescript
- - Python
- - .NET
- - Java
- - Go
- validations:
- required: true
-
- - type: input
- id: language-version
- attributes:
- label: Language Version
- description: E.g. TypeScript (3.8.3) | Java (8) | Python (3.7.3)
- validations:
- required: false
-
- - type: textarea
- id: other
- attributes:
- label: Other information
- description: |
- e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. associated pull-request, stackoverflow, slack, etc
- validations:
- required: false
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 639add0db8a3a..dff48e6f94b22 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -12,6 +12,6 @@
### New Features
* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)?
- * [ ] Did you use `cdk-integ` to deploy the infrastructure and generate the snapshot (i.e. `cdk-integ` without `--dry-run`)?
+ * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?
*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 96c1345fa6c78..0fa6e48f1dd44 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -18,3 +18,26 @@ updates:
labels:
- "auto-approve"
open-pull-requests-limit: 5
+
+ # Non-TypeScript init template dependency updates
+ - package-ecosystem: "pip"
+ directory: "/packages/aws-cdk/lib/init-templates"
+ schedule:
+ interval: "weekly"
+ labels:
+ - "auto-approve"
+ open-pull-requests-limit: 5
+ - package-ecosystem: "maven"
+ directory: "/packages/aws-cdk/lib/init-templates"
+ schedule:
+ interval: "weekly"
+ labels:
+ - "auto-approve"
+ open-pull-requests-limit: 5
+ - package-ecosystem: "nuget"
+ directory: "/packages/aws-cdk/lib/init-templates"
+ schedule:
+ interval: "weekly"
+ labels:
+ - "auto-approve"
+ open-pull-requests-limit: 5
diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml
index 1b957f3d539a8..92e77804e73c9 100644
--- a/.github/workflows/auto-approve.yml
+++ b/.github/workflows/auto-approve.yml
@@ -12,6 +12,6 @@ jobs:
permissions:
pull-requests: write
steps:
- - uses: hmarr/auto-approve-action@v2.1.0
+ - uses: hmarr/auto-approve-action@v2.2.1
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml
index ee427df90ef79..4301162431c57 100644
--- a/.github/workflows/close-stale-issues.yml
+++ b/.github/workflows/close-stale-issues.yml
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
name: Stale issue job
steps:
- - uses: aws-actions/stale-issue-cleanup@v3
+ - uses: aws-actions/stale-issue-cleanup@v5
with:
# Setting messages to an empty string will cause the automation to skip
# that category
diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml
new file mode 100644
index 0000000000000..0fd02ddfdcd5f
--- /dev/null
+++ b/.github/workflows/close-stale-prs.yml
@@ -0,0 +1,23 @@
+on:
+ schedule:
+ # Cron format: min hr day month dow
+ - cron: "0 0 * * *"
+jobs:
+ close-stale-prs:
+ permissions:
+ pull-requests: write
+ runs-on: ubuntu-latest
+ steps:
+ - uses: rix0rrr/close-stale-prs@main
+ with:
+ # Required
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ stale-days: 21
+ response-days: 7
+
+ # Optional
+ important-checks-regex: AutoBuildProject89A8053A
+ warn-message: This PR has been in the STATE state for 3 weeks, and looks abandoned. To keep this PR from being closed, please continue work on it. If not, it will automatically be closed in a week.
+ close-message: This PR has been deemed to be abandoned, and will be automatically closed. Please create a new PR for these changes if you think this decision has been made in error.
+ skip-labels: contribution/core
+ close-label: closed-for-staleness
diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml
index 14fe7ff0cde62..619590a0a2077 100644
--- a/.github/workflows/issue-label-assign.yml
+++ b/.github/workflows/issue-label-assign.yml
@@ -2,10 +2,8 @@ name: "Set Issue Label and Assignee"
on:
issues:
types: [opened, edited]
- pull_request:
- types: [opened, edited]
pull_request_target:
- types: [opened, edited]
+ types: [opened]
jobs:
issue-triage-manager:
@@ -39,7 +37,7 @@ jobs:
included-labels: "[guidance]"
default-area: ${{ env.OSDS_DEVS }}
parameters: >
- [{"area":"guidance","keywords":["guidance"]}]
+ [{"area":"guidance","keywords":["guidancekeyword"]}]
pr-triage-manager:
permissions:
issues: write
@@ -48,12 +46,14 @@ jobs:
steps:
- uses: aws-github-ops/aws-issue-triage-manager@main
with:
- github-token: "${{ secrets.GITHUB_TOKEN }}"
+ github-token: "${{ secrets.PROJEN_GITHUB_TOKEN }}"
target: "pull-requests"
area-is-keyword: true
- excluded-labels: "[contribution/core]"
- parameters: ${{ env.AREA_PARAMS }}
- affixes: ${{ env.AREA_AFFIXES }}
+ default-area: >
+ {"reviewers":{"teamReviewers":["aws-cdk-owners"]}}
+ parameters: >
+ [{"area":"pullrequests","keywords":["pullrequestkeyword"]}]
+
env:
OSDS_DEVS: >
@@ -71,8 +71,8 @@ env:
{"area":"package/tools","keywords":["cli","command line","init","synth","diff","bootstrap"],"labels":["package/tools"],"assignees":["rix0rrr"],"enableGlobalAffixes":false},
{"area":"@aws-cdk/alexa-ask","keywords":["alexa-ask","alexa"],"labels":["@aws-cdk/alexa-ask"],"assignees":["madeline-k"]},
{"area":"@aws-cdk/app-delivery","keywords":["app-delivery"],"labels":["@aws-cdk/app-delivery"],"assignees":["skinny85"]},
- {"area":"@aws-cdk/assert","keywords":["assert"],"labels":["@aws-cdk/assert"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/assertions","keywords":["assertions"],"labels":["@aws-cdk/assertions"],"assignees":["kaizen3031593"]},
+ {"area":"@aws-cdk/assert","keywords":["assert"],"labels":["@aws-cdk/assert"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/assertions","keywords":["assertions"],"labels":["@aws-cdk/assertions"],"assignees":["kaizencc"]},
{"area":"@aws-cdk/assets","keywords":["assets","staging"],"labels":["@aws-cdk/assets"],"assignees":["otaviomacedo"]},
{"area":"@aws-cdk/aws-accessanalyzer","keywords":["aws-accessanalyzer","accessanalyzer"],"labels":["@aws-cdk/aws-accessanalyzer"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-acmpca","keywords":["aws-acmpca","acmpca","certificateauthority"],"labels":["@aws-cdk/aws-acmpca"],"assignees":["skinny85"]},
@@ -98,13 +98,13 @@ env:
{"area":"@aws-cdk/aws-autoscaling-common","keywords":["aws-autoscaling-common","autoscaling-common","arbitraryintervals","completescalinginterval","scalinginterval"],"labels":["@aws-cdk/aws-autoscaling-common"],"assignees":["comcalvi"]},
{"area":"@aws-cdk/aws-autoscaling-hooktargets","keywords":["aws-autoscaling-hooktargets","autoscaling hooktargets","functionhook","queuehook","topichook"],"labels":["@aws-cdk/aws-autoscaling-hooktargets"],"assignees":["comcalvi"]},
{"area":"@aws-cdk/aws-autoscalingplans","keywords":["aws-autoscalingplans","autoscaling-plans"],"labels":["@aws-cdk/aws-autoscalingplans"],"assignees":["comcalvi"]},
- {"area":"@aws-cdk/aws-backup","keywords":["aws-backup","backup","backupselection","backupvault","backupplan"],"labels":["@aws-cdk/aws-backup"],"assignees":["kaizen3031593"]},
+ {"area":"@aws-cdk/aws-backup","keywords":["aws-backup","backup","backupselection","backupvault","backupplan"],"labels":["@aws-cdk/aws-backup"],"assignees":["kaizencc"]},
{"area":"@aws-cdk/aws-batch","keywords":["aws-batch","batch","computeenvironment","jobdefinition","jobqueue"],"labels":["@aws-cdk/aws-batch"],"assignees":["madeline-k"],"affixes":{"suffixes":["-alpha"]}},
{"area":"@aws-cdk/aws-budgets","keywords":["aws-budgets","budgets"],"labels":["@aws-cdk/aws-budgets"],"assignees":["otaviomacedo"]},
{"area":"@aws-cdk/aws-cassandra","keywords":["aws-cassandra","cassandra"],"labels":["@aws-cdk/aws-cassandra"],"assignees":["otaviomacedo"]},
{"area":"@aws-cdk/aws-ce","keywords":["aws-ce","costexplorer","cfncostcategory"],"labels":["@aws-cdk/aws-ce"],"assignees":["corymhall"]},
{"area":"@aws-cdk/aws-certificatemanager","keywords":["aws-certificatemanager","certificate-manager","dnsvalidatedcertificate","acm"],"labels":["@aws-cdk/aws-certificatemanager"],"assignees":["comcalvi"]},
- {"area":"@aws-cdk/aws-chatbot","keywords":["aws-chatbot","chatbot","slackchannelconfiguration"],"labels":["@aws-cdk/aws-chatbot"],"assignees":["kaizen3031593"]},
+ {"area":"@aws-cdk/aws-chatbot","keywords":["aws-chatbot","chatbot","slackchannelconfiguration"],"labels":["@aws-cdk/aws-chatbot"],"assignees":["kaizencc"]},
{"area":"@aws-cdk/aws-cloud9","keywords":["aws-cloud9","cloud9","ec2environment"],"labels":["@aws-cdk/aws-cloud9"],"assignees":["skinny85"],"affixes":{"suffixes":["-alpha"]}},
{"area":"@aws-cdk/aws-cloudformation","keywords":["aws-cloudformation","cloudformation"],"labels":["@aws-cdk/aws-cloudformation"],"assignees":["rix0rrr"]},
{"area":"@aws-cdk/aws-cloudfront","keywords":["aws-cloudfront","cloudfront","cachepolicy","distribution","cloudfrontwebdistribution"],"labels":["@aws-cdk/aws-cloudfront"],"assignees":["comcalvi"]},
@@ -127,9 +127,9 @@ env:
{"area":"@aws-cdk/aws-cognito-identitypool","keywords":["aws-cognito-identitypool","cognito-identitypool"],"labels":["@aws-cdk/aws-cognito-identitypool"],"assignees":["corymhall"],"affixes":{"suffixes":["-alpha"]}},
{"area":"@aws-cdk/aws-config","keywords":["aws-config","config","accesskeysrotated","CloudFormationStackDriftDetectionCheck","CloudFormationStackNotificationCheck","managedrule"],"labels":["@aws-cdk/aws-config"],"assignees":["rix0rrr"]},
{"area":"@aws-cdk/aws-customerprofiles","keywords":["aws-customerprofiles","customerprofiles"],"labels":["@aws-cdk/aws-customerprofiles"],"assignees":["otaviomacedo"]},
- {"area":"@aws-cdk/aws-databrew","keywords":["aws-databrew","databrew"],"labels":["@aws-cdk/aws-databrew"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-datapipeline","keywords":["aws-datapipeline","datapipeline"],"labels":["@aws-cdk/aws-datapipeline"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-datasync","keywords":["aws-datasync","datasync"],"labels":["@aws-cdk/aws-datasync"],"assignees":["kaizen3031593"]},
+ {"area":"@aws-cdk/aws-databrew","keywords":["aws-databrew","databrew"],"labels":["@aws-cdk/aws-databrew"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-datapipeline","keywords":["aws-datapipeline","datapipeline"],"labels":["@aws-cdk/aws-datapipeline"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-datasync","keywords":["aws-datasync","datasync"],"labels":["@aws-cdk/aws-datasync"],"assignees":["kaizencc"]},
{"area":"@aws-cdk/aws-dax","keywords":["aws-dax","dax"],"labels":["@aws-cdk/aws-dax"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-detective","keywords":["aws-detective","detective"],"labels":["@aws-cdk/aws-detective"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-devopsguru","keywords":["aws-devopsguru","devopsguru"],"labels":["@aws-cdk/aws-devopsguru"],"assignees":["corymhall"]},
@@ -153,9 +153,9 @@ env:
{"area":"@aws-cdk/aws-elasticloadbalancingv2","keywords":["aws-elasticloadbalancingv2","elastic-loadbalancing-v2","elbv2","applicationlistener","applicationloadbalancer","applicationtargetgroup","networklistener","networkloadbalancer","networktargetgroup"],"labels":["@aws-cdk/aws-elasticloadbalancingv2"],"assignees":["corymhall"]},
{"area":"@aws-cdk/aws-elasticloadbalancingv2-actions","keywords":["aws-elasticloadbalancingv2-actions","elasticloadbalancingv2-actions"],"labels":["@aws-cdk/aws-elasticloadbalancingv2-actions"],"assignees":["corymhall"]},
{"area":"@aws-cdk/aws-elasticloadbalancingv2-targets","keywords":["aws-elasticloadbalancingv2-targets","elbv2-targets","elbv2-targets"],"labels":["@aws-cdk/aws-elasticloadbalancingv2-targets"],"assignees":["corymhall"]},
- {"area":"@aws-cdk/aws-elasticsearch","keywords":["aws-elasticsearch","elastic-search"],"labels":["@aws-cdk/aws-elasticsearch"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-emr","keywords":["aws-emr","emr"],"labels":["@aws-cdk/aws-emr"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-emrcontainers","keywords":["(aws-emrcontainers)","(emrcontainers)"],"labels":["@aws-cdk/aws-emrcontainers"],"assignees":["kaizen3031593"]},
+ {"area":"@aws-cdk/aws-elasticsearch","keywords":["aws-elasticsearch","elastic-search"],"labels":["@aws-cdk/aws-elasticsearch"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-emr","keywords":["aws-emr","emr"],"labels":["@aws-cdk/aws-emr"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-emrcontainers","keywords":["(aws-emrcontainers)","(emrcontainers)"],"labels":["@aws-cdk/aws-emrcontainers"],"assignees":["kaizencc"]},
{"area":"@aws-cdk/aws-events","keywords":["aws-events","events","event-bridge","eventbus"],"labels":["@aws-cdk/aws-events"],"assignees":["rix0rrr"]},
{"area":"@aws-cdk/aws-events-targets","keywords":["aws-events-targets","events-targets","events targets"],"labels":["@aws-cdk/aws-events-targets"],"assignees":["rix0rrr"]},
{"area":"@aws-cdk/aws-eventschemas","keywords":["aws-eventschemas","event schemas"],"labels":["@aws-cdk/aws-eventschemas"],"assignees":["skinny85"]},
@@ -167,7 +167,7 @@ env:
{"area":"@aws-cdk/aws-gamelift","keywords":["aws-gamelift","gamelift"],"labels":["@aws-cdk/aws-gamelift"],"assignees":["madeline-k"]},
{"area":"@aws-cdk/aws-globalaccelerator","keywords":["aws-globalaccelerator","global-accelerator"],"labels":["@aws-cdk/aws-globalaccelerator"],"assignees":["rix0rrr"]},
{"area":"@aws-cdk/aws-globalaccelerator-endpoints","keywords":["aws-globalaccelerator-endpoints","globalaccelerator-endpoints"],"labels":["@aws-cdk/aws-globalaccelerator-endpoints"],"assignees":["rix0rrr"]},
- {"area":"@aws-cdk/aws-glue","keywords":["aws-glue","glue"],"labels":["@aws-cdk/aws-glue"],"assignees":["kaizen3031593"],"affixes":{"suffixes":["-alpha"]}},
+ {"area":"@aws-cdk/aws-glue","keywords":["aws-glue","glue"],"labels":["@aws-cdk/aws-glue"],"assignees":["kaizencc"],"affixes":{"suffixes":["-alpha"]}},
{"area":"@aws-cdk/aws-greengrass","keywords":["aws-greengrass","green-grass"],"labels":["@aws-cdk/aws-greengrass"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-greengrassv2","keywords":["aws-greengrassv2","greengrassv2"],"labels":["@aws-cdk/aws-greengrassv2"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-groundstation","keywords":["aws-groundstation","groundstation"],"labels":["@aws-cdk/aws-groundstation"],"assignees":["comcalvi"]},
@@ -194,9 +194,9 @@ env:
{"area":"@aws-cdk/aws-kinesisfirehose-destinations","keywords":["aws-kinesisfirehose-destinations","kinesisfirehose-destinations"],"labels":["@aws-cdk/aws-kinesisfirehose"],"assignees":["otaviomacedo"],"affixes":{"suffixes":["-alpha"]}},
{"area":"@aws-cdk/aws-kms","keywords":["key-management-service","aws-kms","kms"],"labels":["@aws-cdk/aws-kms"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-lakeformation","keywords":["data-lake","aws-lakeformation","lakeformation"],"labels":["@aws-cdk/aws-lakeformation"],"assignees":["comcalvi"]},
- {"area":"@aws-cdk/aws-lambda","keywords":["function","layerversion","aws-lambda","lambda"],"labels":["@aws-cdk/aws-lambda"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-lambda-destinations","keywords":["aws-lambda-destinations","lambda-destinations"],"labels":["@aws-cdk/aws-lambda-destinations"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-lambda-event-sources","keywords":["dynamoeventsource","aws-lambda-event-sources","lambda-event-sources","apieventsource","kinesiseventsource"],"labels":["@aws-cdk/aws-lambda-event-sources"],"assignees":["kaizen3031593"]},
+ {"area":"@aws-cdk/aws-lambda","keywords":["function","layerversion","aws-lambda","lambda"],"labels":["@aws-cdk/aws-lambda"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-lambda-destinations","keywords":["aws-lambda-destinations","lambda-destinations"],"labels":["@aws-cdk/aws-lambda-destinations"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-lambda-event-sources","keywords":["dynamoeventsource","aws-lambda-event-sources","lambda-event-sources","apieventsource","kinesiseventsource"],"labels":["@aws-cdk/aws-lambda-event-sources"],"assignees":["kaizencc"]},
{"area":"@aws-cdk/aws-lambda-go","keywords":["aws-lambda-go","lambda-go"],"labels":["@aws-cdk/aws-lambda-go"],"assignees":["corymhall"],"affixes":{"suffixes":["-alpha"]}},
{"area":"@aws-cdk/aws-lambda-nodejs","keywords":["nodejsfunction","aws-lambda-nodejs","lambda-nodejs"],"labels":["@aws-cdk/aws-lambda-nodejs"],"assignees":["corymhall"]},
{"area":"@aws-cdk/aws-lambda-python","keywords":["aws-lambda-python","lambda-python","pythonfunction"],"labels":["@aws-cdk/aws-lambda-python"],"assignees":["corymhall"],"affixes":{"suffixes":["-alpha"]}},
@@ -218,7 +218,7 @@ env:
{"area":"@aws-cdk/aws-networkfirewall","keywords":["aws-networkfirewall","networkfirewall"],"labels":["@aws-cdk/aws-networkfirewall"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-networkmanager","keywords":["aws-networkmanager","networkmanager","globalnetwork"],"labels":["@aws-cdk/aws-networkmanager"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-nimblestudio","keywords":["aws-nimblestudio","nimblestudio"],"labels":["@aws-cdk/aws-nimblestudio"],"assignees":["madeline-k"]},
- {"area":"@aws-cdk/aws-opensearchservice","keywords":["aws-opensearchservice","opensearchservice","aws-opensearch","opensearch"],"labels":["@aws-cdk/aws-opensearch"],"assignees":["kaizen3031593"]},
+ {"area":"@aws-cdk/aws-opensearchservice","keywords":["aws-opensearchservice","opensearchservice","aws-opensearch","opensearch"],"labels":["@aws-cdk/aws-opensearch"],"assignees":["kaizencc"]},
{"area":"@aws-cdk/aws-opsworks","keywords":["aws-opsworks","opsworks"],"labels":["@aws-cdk/aws-opsworks"],"assignees":["madeline-k"]},
{"area":"@aws-cdk/aws-opsworkscm","keywords":["aws-opsworkscm","opsworkscm"],"labels":["@aws-cdk/aws-opsworkscm"],"assignees":["madeline-k"]},
{"area":"@aws-cdk/aws-personalize","keywords":["aws-personalize","personalize"],"labels":["@aws-cdk/aws-personalize"],"assignees":["comcalvi"]},
@@ -252,14 +252,14 @@ env:
{"area":"@aws-cdk/aws-ses","keywords":["receipt-filter","receipt-rule","aws-ses","ses"],"labels":["@aws-cdk/aws-ses"],"assignees":["otaviomacedo"]},
{"area":"@aws-cdk/aws-ses-actions","keywords":["aws-ses-actions","ses-actions"],"labels":["@aws-cdk/aws-ses-actions"],"assignees":["otaviomacedo"]},
{"area":"@aws-cdk/aws-signer","keywords":["aws-signer","signer"],"labels":["@aws-cdk/aws-signer"],"assignees":["corymhall"]},
- {"area":"@aws-cdk/aws-sns","keywords":["simple-notification-service","aws-sns","sns","topic"],"labels":["@aws-cdk/aws-sns"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-sns-subscriptions","keywords":["aws-sns-subscriptions","sns-subscriptions","subscription"],"labels":["@aws-cdk/aws-sns-subscriptions"],"assignees":["kaizen3031593"]},
+ {"area":"@aws-cdk/aws-sns","keywords":["simple-notification-service","aws-sns","sns","topic"],"labels":["@aws-cdk/aws-sns"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-sns-subscriptions","keywords":["aws-sns-subscriptions","sns-subscriptions","subscription"],"labels":["@aws-cdk/aws-sns-subscriptions"],"assignees":["kaizencc"]},
{"area":"@aws-cdk/aws-sqs","keywords":["queue","simple-queue-service","aws-sqs","sqs","fifo"],"labels":["@aws-cdk/aws-sqs"],"assignees":["otaviomacedo"]},
{"area":"@aws-cdk/aws-ssm","keywords":["aws-ssm","ssm","systems-manager","stringparameter","stringlistparameter"],"labels":["@aws-cdk/aws-ssm"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-sso","keywords":["aws-sso","sso","single-sign-on"],"labels":["@aws-cdk/aws-sso"],"assignees":["skinny85"]},
- {"area":"@aws-cdk/aws-stepfunctions","keywords":["aws-stepfunctions","stepfunctions","statemachine", "chain"],"labels":["@aws-cdk/aws-stepfunctions"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-stepfunctions-tasks","keywords":["aws-stepfunctions-tasks","stepfunctions-tasks"],"labels":["@aws-cdk/aws-stepfunctions-tasks"],"assignees":["kaizen3031593"]},
- {"area":"@aws-cdk/aws-synthetics","keywords":["aws-synthetics","synthetics", "canary"],"labels":["@aws-cdk/aws-synthetics"],"assignees":["kaizen3031593"],"affixes":{"suffixes":["-alpha"]}},
+ {"area":"@aws-cdk/aws-stepfunctions","keywords":["aws-stepfunctions","stepfunctions","statemachine", "chain"],"labels":["@aws-cdk/aws-stepfunctions"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-stepfunctions-tasks","keywords":["aws-stepfunctions-tasks","stepfunctions-tasks"],"labels":["@aws-cdk/aws-stepfunctions-tasks"],"assignees":["kaizencc"]},
+ {"area":"@aws-cdk/aws-synthetics","keywords":["aws-synthetics","synthetics", "canary"],"labels":["@aws-cdk/aws-synthetics"],"assignees":["kaizencc"],"affixes":{"suffixes":["-alpha"]}},
{"area":"@aws-cdk/aws-timestream","keywords":["aws-timestream","timestream"],"labels":["@aws-cdk/aws-timestream"],"assignees":["skinny85"]},
{"area":"@aws-cdk/aws-transfer","keywords":["aws-transfer","transfer"],"labels":["@aws-cdk/aws-transfer"],"assignees":["otaviomacedo"]},
{"area":"@aws-cdk/aws-waf","keywords":["waf","aws-waf","web-application-firewall"],"labels":["@aws-cdk/aws-waf"],"assignees":["skinny85"]},
diff --git a/.github/workflows/issue-reprioritization.yml b/.github/workflows/issue-reprioritization.yml
new file mode 100644
index 0000000000000..9a6ade90de43a
--- /dev/null
+++ b/.github/workflows/issue-reprioritization.yml
@@ -0,0 +1,22 @@
+name: issue-reprioritization
+on:
+ schedule:
+ - cron: "0 0 * * 0"
+
+jobs:
+ issue-reprioritization:
+ permissions:
+ issues: write
+ runs-on: ubuntu-latest
+ steps:
+ - uses: kaizencc/issue-reprioritization-manager@main
+ id: reprioritization-manager
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ original-label: p2
+ new-label: p1
+ reprioritization-threshold: 20
+ - uses: kaizencc/pr-triage-manager@main
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ on-pulls: ${{ steps.reprioritization-manager.outputs.linked-pulls }}
diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml
index 55be270e4d0f7..1ce06fd16fcf1 100644
--- a/.github/workflows/pr-labeler.yml
+++ b/.github/workflows/pr-labeler.yml
@@ -24,7 +24,7 @@ jobs:
permissions:
pull-requests: write
steps:
- - uses: kaizen3031593/pr-triage-manager@main
+ - uses: kaizencc/pr-triage-manager@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/team-owners-assignment.yml b/.github/workflows/team-owners-assignment.yml
new file mode 100644
index 0000000000000..6d0f4435a1ab7
--- /dev/null
+++ b/.github/workflows/team-owners-assignment.yml
@@ -0,0 +1,15 @@
+name: "Assigns members from team aws-cdk-owners to PRs"
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ team-assignment-manager:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: peterwoodworth/team-assignment-manager@main
+ with:
+ github-token: "${{ secrets.PROJEN_GITHUB_TOKEN }}"
+ team: "aws-cdk-owners"
+ exempt-team: "aws-cdk-team"
+
diff --git a/.github/workflows/yarn-upgrade.yml b/.github/workflows/yarn-upgrade.yml
index 64e3e6a1ebe70..cb11fb0de614d 100644
--- a/.github/workflows/yarn-upgrade.yml
+++ b/.github/workflows/yarn-upgrade.yml
@@ -40,6 +40,8 @@ jobs:
npm -g install lerna npm-check-updates@^9.0.0
- name: Build CLI
run: cd packages/aws-cdk && ../../scripts/buildup
+ - name: Build Integ Runner
+ run: cd packages/@aws-cdk/integ-runner && ../../../scripts/buildup
- name: List Mono-Repo Packages
id: list-packages
# These need to be ignored from the `ncu` runs!
@@ -63,16 +65,22 @@ jobs:
lerna exec --parallel ncu -- --upgrade --filter=@types/node,@types/fs-extra --target=minor
lerna exec --parallel ncu -- --upgrade --filter=typescript --target=patch
lerna exec --parallel ncu -- --upgrade --reject='@types/node,@types/fs-extra,constructs,typescript,aws-sdk,aws-sdk-mock,${{ steps.list-packages.outputs.list }}' --target=minor
-
+ # Upgrade package.jsons in init templates
+ for pj in $(find packages/aws-cdk/lib/init-templates -name package.json); do
+ (cd $(dirname $pj) && ncu --upgrade --reject='@types/node,@types/fs-extra,constructs,typescript,aws-sdk,aws-sdk-mock,${{ steps.list-packages.outputs.list }}')
+ done
+
# This will ensure the current lockfile is up-to-date with the dependency specifications (necessary for "yarn update" to run)
- name: Run "yarn install"
run: yarn install
- name: Run "yarn upgrade"
run: yarn upgrade
-
+
- name: Regenerate CLI attributions
run: cd packages/aws-cdk && yarn pkglint
+ - name: Regenerate Integ Runner attributions
+ run: cd packages/@aws-cdk/integ-runner && yarn pkglint
# Next, create and upload the changes as a patch file. This will later be downloaded to create a pull request
# Creating a pull request requires write permissions and it's best to keep write privileges isolated.
@@ -81,7 +89,7 @@ jobs:
git add .
git diff --patch --staged > ${{ runner.temp }}/upgrade.patch
- name: Upload Patch
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: upgrade.patch
path: ${{ runner.temp }}/upgrade.patch
@@ -98,7 +106,7 @@ jobs:
uses: actions/checkout@v3
- name: Download patch
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v3
with:
name: upgrade.patch
path: ${{ runner.temp }}
diff --git a/.mergify.yml b/.mergify.yml
index ca9bdc82b9333..b793427123346 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -10,7 +10,7 @@ pull_request_rules:
label:
add: [ contribution/core ]
conditions:
- - author~=^(eladb|RomainMuller|garnaat|nija-at|skinny85|rix0rrr|NGL321|Jerry-AWS|MrArnoldPalmer|NetaNir|iliapolo|njlynch|ericzbeard|ccfife|fulghum|pkandasamy91|SoManyHs|uttarasridhar|otaviomacedo|BenChaimberg|madeline-k|BryanPan342|kaizen3031593|comcalvi|Chriscbr|corymhall|peterwoodworth|ryparker|TheRealAmazonKendra|yuth)$
+ - author~=^(RomainMuller|garnaat|skinny85|rix0rrr|NGL321|Jerry-AWS|MrArnoldPalmer|iliapolo|pkandasamy91|SoManyHs|uttarasridhar|otaviomacedo|madeline-k|kaizencc|comcalvi|Chriscbr|corymhall|peterwoodworth|ryparker|TheRealAmazonKendra|yuth|vinayak-kukreja)$
- -label~="contribution/core"
- name: automatic merge
actions:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1621fa309c36a..007ac12591428 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,172 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+## [1.155.0](https://github.com/aws/aws-cdk/compare/v1.154.0...v1.155.0) (2022-05-04)
+
+
+### Features
+
+* **cfnspec:** cloudformation spec v68.0.0 ([#20065](https://github.com/aws/aws-cdk/issues/20065)) ([f199fad](https://github.com/aws/aws-cdk/commit/f199faddc0b8e565aa413e480e51d25fed5321bf))
+* **cloudwatch:** Add CustomWidget ([#19327](https://github.com/aws/aws-cdk/issues/19327)) ([489340e](https://github.com/aws/aws-cdk/commit/489340ea383c9130c315853afae0137b1fa03eb0)), closes [#17579](https://github.com/aws/aws-cdk/issues/17579)
+* **ec2:** add i4i instance type ([#20134](https://github.com/aws/aws-cdk/issues/20134)) ([64c5064](https://github.com/aws/aws-cdk/commit/64c50640e7f5897f08af3f86cd28a1dab3cd2430))
+* **iam:** add convenience method `inOrganization` to ArnPrincipal ([#20109](https://github.com/aws/aws-cdk/issues/20109)) ([c545bfe](https://github.com/aws/aws-cdk/commit/c545bfe2a3ccb53fa5ae2eb725a1696677703c0a)), closes [/github.com/aws/aws-cdk/pull/19975#discussion_r857385168](https://github.com/aws//github.com/aws/aws-cdk/pull/19975/issues/discussion_r857385168) [#19975](https://github.com/aws/aws-cdk/issues/19975)
+* **lambda:** `function.addAlias()` simplifies Alias creation ([#20034](https://github.com/aws/aws-cdk/issues/20034)) ([a79bc47](https://github.com/aws/aws-cdk/commit/a79bc47aaa6737628562c251e2f1990b2c7b88ef))
+* **rds:** add secret rotation to `DatabaseClusterFromSnapshot` ([#20020](https://github.com/aws/aws-cdk/issues/20020)) ([abc3502](https://github.com/aws/aws-cdk/commit/abc3502eef9b1b950f4e9d2c3f5f44b7e2f6476d)), closes [#12877](https://github.com/aws/aws-cdk/issues/12877)
+
+
+### Bug Fixes
+
+* **lambda:** grant invoke twice with different principals ([#20174](https://github.com/aws/aws-cdk/issues/20174)) ([bb4c950](https://github.com/aws/aws-cdk/commit/bb4c9506c7395fc3c84725fb8e6054ac23ca2bf7))
+* **ubergen:** expose exports in core module for v2 ([#20176](https://github.com/aws/aws-cdk/issues/20176)) ([fc2cd48](https://github.com/aws/aws-cdk/commit/fc2cd48a3aabaf0d5214b322794c6a49d9c700c9)), closes [#19773](https://github.com/aws/aws-cdk/issues/19773)
+
+## [1.154.0](https://github.com/aws/aws-cdk/compare/v1.153.1...v1.154.0) (2022-04-27)
+
+
+### Features
+
+* **aws-cognito:** send emails with a verified domain ([#19790](https://github.com/aws/aws-cdk/issues/19790)) ([1d2b1d3](https://github.com/aws/aws-cdk/commit/1d2b1d30b4357961ef72fd275a58038dd755de17)), closes [#19762](https://github.com/aws/aws-cdk/issues/19762)
+* **aws-eks:** add annotations and labels to service accounts ([#19609](https://github.com/aws/aws-cdk/issues/19609)) ([82aec9d](https://github.com/aws/aws-cdk/commit/82aec9db1fcd23f0c39c75c950c5b2a165d0f99a)), closes [#19607](https://github.com/aws/aws-cdk/issues/19607)
+* **cloudwatch:** expose dashboardArn for CloudWatch dashboard L2 construct ([#20059](https://github.com/aws/aws-cdk/issues/20059)) ([df9814f](https://github.com/aws/aws-cdk/commit/df9814f48b6d94a2c2297cacd9e7cea958993766))
+* **cloudwatch:** expose dashboardName property on the L2 Dashboard construct ([#17721](https://github.com/aws/aws-cdk/issues/17721)) ([8cb5dff](https://github.com/aws/aws-cdk/commit/8cb5dff400e0143b86494f11c565d981c74f875a)), closes [#17648](https://github.com/aws/aws-cdk/issues/17648)
+* **integ-tests:** add `IntegTest` to group test cases ([#20015](https://github.com/aws/aws-cdk/issues/20015)) ([b4f8d91](https://github.com/aws/aws-cdk/commit/b4f8d91318087135c5549c22b43a1e679d70b3ca))
+* **integ-tests:** make assertions on deployed infrastructure ([#20071](https://github.com/aws/aws-cdk/issues/20071)) ([8362efe](https://github.com/aws/aws-cdk/commit/8362efe8f1951289236034161d7560f20975b0ec))
+* **rds:** allow `DatabaseClusterFromSnapshot` to set `copyTagsToSnapshot` property ([#19932](https://github.com/aws/aws-cdk/issues/19932)) ([40a6ceb](https://github.com/aws/aws-cdk/commit/40a6ceb9983694a3645edd78167e93825a9049e9)), closes [#19884](https://github.com/aws/aws-cdk/issues/19884)
+* **redshift:** expose user.secret as property ([#17520](https://github.com/aws/aws-cdk/issues/17520)) ([#20078](https://github.com/aws/aws-cdk/issues/20078)) ([8da006a](https://github.com/aws/aws-cdk/commit/8da006ab551213ecbdb6dc26860fe90c1d2e95e2))
+* **servicecatalog:** graduate to stable 🚀 ([#19515](https://github.com/aws/aws-cdk/issues/19515)) ([4764591](https://github.com/aws/aws-cdk/commit/4764591a59d63026584f1898046974a1a166e166))
+
+
+### Bug Fixes
+
+* **eks:** cluster cannot be created in opt-in regions ([#20009](https://github.com/aws/aws-cdk/issues/20009)) ([ec06f48](https://github.com/aws/aws-cdk/commit/ec06f4893d62f371ef92fccaa52d38f4350d6712)), closes [#13748](https://github.com/aws/aws-cdk/issues/13748) [#15579](https://github.com/aws/aws-cdk/issues/15579)
+* **eks:** remove incomplete support for k8s v1.22 ([#20000](https://github.com/aws/aws-cdk/issues/20000)) ([d38a9e4](https://github.com/aws/aws-cdk/commit/d38a9e44af184e6e7fa8cde14a84ff2c72cec5f9)), closes [#19756](https://github.com/aws/aws-cdk/issues/19756) [#19919](https://github.com/aws/aws-cdk/issues/19919)
+* **integ-runner:** disable-update-workflow default is 'false' instead of false ([#20073](https://github.com/aws/aws-cdk/issues/20073)) ([9f7aa65](https://github.com/aws/aws-cdk/commit/9f7aa654ab92c16743b015f7121a3dc542a7e01a))
+* **integ-runner:** only diff registered stacks ([#20100](https://github.com/aws/aws-cdk/issues/20100)) ([721bd4b](https://github.com/aws/aws-cdk/commit/721bd4b24de8e410fd9181eff7e5431c13bad208))
+* **lambda-python:** handler path is incorrectly generated when using PythonFunction ([#20083](https://github.com/aws/aws-cdk/issues/20083)) ([6787376](https://github.com/aws/aws-cdk/commit/678737607cea769109aa8315520a71bc47eb50ef))
+* **tooling:** container user's uid does not match host's uid ([#20082](https://github.com/aws/aws-cdk/issues/20082)) ([e9670c8](https://github.com/aws/aws-cdk/commit/e9670c85819203069ca597b71e305b6a20313d1f)), closes [#19979](https://github.com/aws/aws-cdk/issues/19979)
+* deploy monitor count is off if there are > 100 changes ([#20067](https://github.com/aws/aws-cdk/issues/20067)) ([fd306ee](https://github.com/aws/aws-cdk/commit/fd306ee05cfa7ebaa8d997007500d89d62868897)), closes [#11805](https://github.com/aws/aws-cdk/issues/11805)
+* **imagebuilder:** AmiDistributionConfiguration renders empty ([#20045](https://github.com/aws/aws-cdk/issues/20045)) ([7bd7139](https://github.com/aws/aws-cdk/commit/7bd7139abafa0f36d0494be2fa6f03b5149702ef))
+* **lambda-python:** Pipenv projects no longer work for Python 3.6 ([#20019](https://github.com/aws/aws-cdk/issues/20019)) ([5024021](https://github.com/aws/aws-cdk/commit/5024021bec9952ca7b1e3d82e2c257f124c6300c))
+* **region-info:** EMR service principal incorrect in China ([#20014](https://github.com/aws/aws-cdk/issues/20014)) ([84649b8](https://github.com/aws/aws-cdk/commit/84649b87aec769be690c627832f73a8472fb785f)), closes [#19867](https://github.com/aws/aws-cdk/issues/19867)
+
+## [1.153.1](https://github.com/aws/aws-cdk/compare/v1.153.0...v1.153.1) (2022-04-22)
+
+
+### Bug Fixes
+
+* **imagebuilder:** revert property field typings ([b2e0eb5](https://github.com/aws/aws-cdk/commit/b2e0eb501e87bb954e985081d28ceecaf42a1ddd))
+
+## [1.153.0](https://github.com/aws/aws-cdk/compare/v1.152.0...v1.153.0) (2022-04-21)
+
+
+### Features
+
+* **apigatewayv2:** set throttling on stages ([#19776](https://github.com/aws/aws-cdk/issues/19776)) ([3cabd10](https://github.com/aws/aws-cdk/commit/3cabd105288789c03d1a8d508637b2d7f46407a4)), closes [#19626](https://github.com/aws/aws-cdk/issues/19626)
+* **autoscaling:** Auto Scaling Group with Launch Template ([#19066](https://github.com/aws/aws-cdk/issues/19066)) ([1581af0](https://github.com/aws/aws-cdk/commit/1581af0e91cd68ace2c76c236be811a4e48bffe6)), closes [#6734](https://github.com/aws/aws-cdk/issues/6734)
+* **aws-ecr:** make it easy to reference image tag or digest, use everywhere ([#19799](https://github.com/aws/aws-cdk/issues/19799)) ([380774e](https://github.com/aws/aws-cdk/commit/380774edd5f8c42294651ead3541eebcf029251c)), closes [#13299](https://github.com/aws/aws-cdk/issues/13299) [#15333](https://github.com/aws/aws-cdk/issues/15333)
+* **cfnspec:** cloudformation spec v66.0.0 ([#19812](https://github.com/aws/aws-cdk/issues/19812)) ([43735fd](https://github.com/aws/aws-cdk/commit/43735fd85cff3d5f9cdf4e6c9f62ffe4c93a72b4)), closes [#19798](https://github.com/aws/aws-cdk/issues/19798)
+* **cfnspec:** cloudformation spec v66.1.0 ([#19929](https://github.com/aws/aws-cdk/issues/19929)) ([8c8b6b6](https://github.com/aws/aws-cdk/commit/8c8b6b68b98e090580357172c247267ce92f2668))
+* **cli:** glob-style key matching to context --reset ([#19840](https://github.com/aws/aws-cdk/issues/19840)) ([edb4119](https://github.com/aws/aws-cdk/commit/edb411925cf84ebe38e5a45acdec20f339087ea6)), closes [#19797](https://github.com/aws/aws-cdk/issues/19797)
+* **codebuild:** add ability to customize build status reporting for third-party Git sources ([#19408](https://github.com/aws/aws-cdk/issues/19408)) ([423d72f](https://github.com/aws/aws-cdk/commit/423d72f79b979d6f5f8ba70df05b7e1580d6a349))
+* **codepipeline:** allow to disable stage transition ([#19911](https://github.com/aws/aws-cdk/issues/19911)) ([ac9901a](https://github.com/aws/aws-cdk/commit/ac9901ada20e0bcadcae0e6f59e5c58220328714)), closes [#1649](https://github.com/aws/aws-cdk/issues/1649)
+* **integ-runner:** add missing features from the integ manifest ([#19969](https://github.com/aws/aws-cdk/issues/19969)) ([2ca5050](https://github.com/aws/aws-cdk/commit/2ca5050865f94e033fda850961439d8fcb01f468))
+* **integ-runner:** integ-runner enhancements ([#19865](https://github.com/aws/aws-cdk/issues/19865)) ([697fdbe](https://github.com/aws/aws-cdk/commit/697fdbe71642c93492c38e834e654ed736a9edb4))
+* **integ-runner:** test update path when running tests ([#19915](https://github.com/aws/aws-cdk/issues/19915)) ([d0ace8f](https://github.com/aws/aws-cdk/commit/d0ace8f2db53d56cdb670979c7c173ee17b6bcd8))
+* **integ-tests:** Add `IntegTestCase` ([#19829](https://github.com/aws/aws-cdk/issues/19829)) ([ad249c9](https://github.com/aws/aws-cdk/commit/ad249c9943c2d602b2b077435935731f723db715))
+* **iotevents:** support comparison operators ([#19329](https://github.com/aws/aws-cdk/issues/19329)) ([95cb3f3](https://github.com/aws/aws-cdk/commit/95cb3f3c7a4c98ebf4a4818af2f4e725fc16aa29))
+* **lambda:** function URLs ([#19817](https://github.com/aws/aws-cdk/issues/19817)) ([4fd515a](https://github.com/aws/aws-cdk/commit/4fd515a3a1de87977ad71329bb7cecb0527558f4)), closes [#19798](https://github.com/aws/aws-cdk/issues/19798)
+* **logs:** add QueryDefinition L2 Construct ([#18655](https://github.com/aws/aws-cdk/issues/18655)) ([fcf981b](https://github.com/aws/aws-cdk/commit/fcf981b31c12f0366e49e15d5aa67d412e84caf0))
+* **route53:** fromPublicHostedZoneAttributes method with zoneName ([#19771](https://github.com/aws/aws-cdk/issues/19771)) ([7867dc4](https://github.com/aws/aws-cdk/commit/7867dc499af50edad11c9263c37cb71e72193c04)), closes [#18700](https://github.com/aws/aws-cdk/issues/18700)
+* **s3-deployment:** ephemeral storage size property for bucket deployment ([#19958](https://github.com/aws/aws-cdk/issues/19958)) ([3ce40b4](https://github.com/aws/aws-cdk/commit/3ce40b4455215b066833fa0ebe0e0a99a2928573)), closes [#19947](https://github.com/aws/aws-cdk/issues/19947)
+* check for accidental exposure of secrets ([#19543](https://github.com/aws/aws-cdk/issues/19543)) ([789e8d2](https://github.com/aws/aws-cdk/commit/789e8d2aaa0aefb6d17e4ebc0d56c17e9999add0))
+
+
+### Bug Fixes
+
+* **autoscaling:** update validation on maxInstanceLifetime ([#19584](https://github.com/aws/aws-cdk/issues/19584)) ([d115b47](https://github.com/aws/aws-cdk/commit/d115b476688eb39a935074490435f855f7fee9c0))
+* **aws-cloudfront:** Add sslSupportMethod ([#19737](https://github.com/aws/aws-cdk/issues/19737)) ([c5a9679](https://github.com/aws/aws-cdk/commit/c5a96793818f57141efc78ab60f13b48a3b1e460)), closes [#19476](https://github.com/aws/aws-cdk/issues/19476)
+* **aws-ecr-assets:** correct file existence validation in tests ([#19945](https://github.com/aws/aws-cdk/issues/19945)) ([d4c13c0](https://github.com/aws/aws-cdk/commit/d4c13c01c2d2a910a09db7c6fdfc67f410d6b195)), closes [40aws-cdk/aws-ecr-assets/test/image-asset.test.ts#L387](https://github.com/40aws-cdk/aws-ecr-assets/test/image-asset.test.ts/issues/L387) [#19944](https://github.com/aws/aws-cdk/issues/19944)
+* **cfn-diff:** allow resources to change types ([#19891](https://github.com/aws/aws-cdk/issues/19891)) ([4f3a340](https://github.com/aws/aws-cdk/commit/4f3a340ab8794ce793b903042a6ba9470bec8955)), closes [#13921](https://github.com/aws/aws-cdk/issues/13921)
+* **cfn-include:** detect a resource cycle in the included template ([#19871](https://github.com/aws/aws-cdk/issues/19871)) ([2c2bc0b](https://github.com/aws/aws-cdk/commit/2c2bc0b4ba2be87706a87c141f35f32fbe1ea615)), closes [#16654](https://github.com/aws/aws-cdk/issues/16654)
+* **cfnspec:** aws-sam deployment preferences hooks ([#19732](https://github.com/aws/aws-cdk/issues/19732)) ([a205734](https://github.com/aws/aws-cdk/commit/a205734f609202c168119dddf1fdc30080f18744))
+* **cfnSpec:** wrong type for SAM API properties GatewayResponses and Models ([#19885](https://github.com/aws/aws-cdk/issues/19885)) ([b214ede](https://github.com/aws/aws-cdk/commit/b214ede1bd264afc1de7f34541bfc4220fa507bc)), closes [#19870](https://github.com/aws/aws-cdk/issues/19870)
+* **cli:** hangs on retrieving notices ([#19967](https://github.com/aws/aws-cdk/issues/19967)) ([daeeafa](https://github.com/aws/aws-cdk/commit/daeeafa5855d3bbb5b5070f10fd7cba52d035112)), closes [#19542](https://github.com/aws/aws-cdk/issues/19542)
+* **cli:** stack monitor prints over error messages ([#19859](https://github.com/aws/aws-cdk/issues/19859)) ([42e5d08](https://github.com/aws/aws-cdk/commit/42e5d08be2b505b4cf6ca818844c02b95bc43e43)), closes [#19742](https://github.com/aws/aws-cdk/issues/19742)
+* **cloudwatch:** MathExpression `id` contract is not clear ([#19825](https://github.com/aws/aws-cdk/issues/19825)) ([5472b11](https://github.com/aws/aws-cdk/commit/5472b11ab1d10514dd5f67dfaf5e21eba979d572)), closes [#13942](https://github.com/aws/aws-cdk/issues/13942) [#17126](https://github.com/aws/aws-cdk/issues/17126)
+* **core:** exportValue does not work on number attributes ([#19818](https://github.com/aws/aws-cdk/issues/19818)) ([12459ca](https://github.com/aws/aws-cdk/commit/12459ca368012a81bfc11c023a100764cf8fd0ed)), closes [#19537](https://github.com/aws/aws-cdk/issues/19537)
+* **docdb:** make most attributes of DatabaseClusterAttributes optional ([#19625](https://github.com/aws/aws-cdk/issues/19625)) ([5f6d20c](https://github.com/aws/aws-cdk/commit/5f6d20c2a881ffd9decaa8afe3d35dd677b601f1)), closes [#14492](https://github.com/aws/aws-cdk/issues/14492)
+* **ecr:** scanOnPush not supported in certain regions ([#19940](https://github.com/aws/aws-cdk/issues/19940)) ([2ff3143](https://github.com/aws/aws-cdk/commit/2ff3143ad47d4dcf963fdb5d0e333a3a86ef8a2e)), closes [#19918](https://github.com/aws/aws-cdk/issues/19918)
+* **ecs:** get rid of EFS casing warnings ([#19681](https://github.com/aws/aws-cdk/issues/19681)) ([eafc11a](https://github.com/aws/aws-cdk/commit/eafc11afbd6a09451afbecd8110c1e0a1a9088a4)), closes [#15025](https://github.com/aws/aws-cdk/issues/15025)
+* **eks:** malformed command when installing helm chart from OCI artifact ([#19778](https://github.com/aws/aws-cdk/issues/19778)) ([f8babb8](https://github.com/aws/aws-cdk/commit/f8babb8f0f88fec6216bcb5de95ac4ec57be39db)), closes [/github.com/aws/aws-cdk/pull/18547#issuecomment-1088737549](https://github.com/aws//github.com/aws/aws-cdk/pull/18547/issues/issuecomment-1088737549)
+* **iam:** role/group/user's path not included in ARN ([#13258](https://github.com/aws/aws-cdk/issues/13258)) ([ef2b480](https://github.com/aws/aws-cdk/commit/ef2b480699f687aace64481ece654842461a9f13)), closes [#13156](https://github.com/aws/aws-cdk/issues/13156)
+* **integ-runner:** enable all feature flags by default ([#19955](https://github.com/aws/aws-cdk/issues/19955)) ([ca3920d](https://github.com/aws/aws-cdk/commit/ca3920dbd588ebd9c68f17bfbf420713cf42790a))
+* **lambda-event-sources:** unsupported property `onFailure` for KafkaEventSources ([#19995](https://github.com/aws/aws-cdk/issues/19995)) ([383171b](https://github.com/aws/aws-cdk/commit/383171b54873705a01b7f113a7c6b5c98be2117b)), closes [#19917](https://github.com/aws/aws-cdk/issues/19917)
+* **rds:** MySQL 8.0 uses wrong Parameter for S3 export ([#19775](https://github.com/aws/aws-cdk/issues/19775)) ([5a895a3](https://github.com/aws/aws-cdk/commit/5a895a308ef2b6e66a330038c7ae35ea95a0fba4)), closes [#19735](https://github.com/aws/aws-cdk/issues/19735)
+* **stepfunctions:** incorrect default documentation for integrationPattern ([#19936](https://github.com/aws/aws-cdk/issues/19936)) ([4cb3b2b](https://github.com/aws/aws-cdk/commit/4cb3b2bdb959ae398ffe2f8a5a927280f5d63306)), closes [#19815](https://github.com/aws/aws-cdk/issues/19815)
+
+
+### Reverts
+
+* "feat(cli): glob-style key matching to context --reset ([#19840](https://github.com/aws/aws-cdk/issues/19840))" ([#19888](https://github.com/aws/aws-cdk/issues/19888)) ([89ec597](https://github.com/aws/aws-cdk/commit/89ec5972e855695fee61628440e61df79c12fdc5))
+
+## [1.152.0](https://github.com/aws/aws-cdk/compare/v1.151.0...v1.152.0) (2022-04-06)
+
+
+### Features
+
+* **cfnspec:** cloudformation spec v63.0.0 ([#19679](https://github.com/aws/aws-cdk/issues/19679)) ([dba96a9](https://github.com/aws/aws-cdk/commit/dba96a9ec6193f630baf6c0d306def903024a56d))
+* **cfnspec:** cloudformation spec v65.0.0 ([#19745](https://github.com/aws/aws-cdk/issues/19745)) ([796fc64](https://github.com/aws/aws-cdk/commit/796fc6401124c00b835cbb8679b47cd373811209))
+* **cli:** add --build option ([#19663](https://github.com/aws/aws-cdk/issues/19663)) ([eb9b8e2](https://github.com/aws/aws-cdk/commit/eb9b8e23906e2e1375f45f795d71b905bc0a52af)), closes [#19667](https://github.com/aws/aws-cdk/issues/19667)
+* **cli:** preview of `cdk import` ([#17666](https://github.com/aws/aws-cdk/issues/17666)) ([4f12209](https://github.com/aws/aws-cdk/commit/4f122099e2d4a6b3bdf6edfb2e99986dd266a71e))
+* **core:** throw error when stack name exceeds max length ([#19725](https://github.com/aws/aws-cdk/issues/19725)) ([1ffd45e](https://github.com/aws/aws-cdk/commit/1ffd45e5aa179aef0622902306701a526f6dfa6c))
+* **eks:** add k8s v1.22 ([#19756](https://github.com/aws/aws-cdk/issues/19756)) ([9a518c5](https://github.com/aws/aws-cdk/commit/9a518c59f5fcb74dd73df1a91681039b6c150fec))
+* **opensearch:** Add latest Opensearch Version 1.2 ([#19749](https://github.com/aws/aws-cdk/issues/19749)) ([a2ac36e](https://github.com/aws/aws-cdk/commit/a2ac36e6dbe486aa87e46d17f5472d6af6c39397))
+* add new integration test runner ([#19754](https://github.com/aws/aws-cdk/issues/19754)) ([1b4d010](https://github.com/aws/aws-cdk/commit/1b4d010ed29cfb4a8f7f5a8ecc22c7c97bccde4e))
+* **eks:** alb-controller v2.4.1 ([#19653](https://github.com/aws/aws-cdk/issues/19653)) ([1ec08df](https://github.com/aws/aws-cdk/commit/1ec08dfc85122fc6f3d9e3c28abc7cd116f08d91))
+* **lambda:** add support for ephemeral storage ([#19552](https://github.com/aws/aws-cdk/issues/19552)) ([f1d9b6a](https://github.com/aws/aws-cdk/commit/f1d9b6aa39c10a85c61ab3aaceabac88789bd2cf)), closes [#19605](https://github.com/aws/aws-cdk/issues/19605)
+* **s3:** EventBridge bucket notifications ([#18614](https://github.com/aws/aws-cdk/issues/18614)) ([d8e602b](https://github.com/aws/aws-cdk/commit/d8e602b6c1b4cb8ca7038f4b21a7a7092ea8466d)), closes [#18076](https://github.com/aws/aws-cdk/issues/18076)
+* **synthetics:** new puppeteer 3.5 runtime ([#19673](https://github.com/aws/aws-cdk/issues/19673)) ([ce2b91b](https://github.com/aws/aws-cdk/commit/ce2b91b319da0221adffcdda54321b860db2a56d)), closes [#19634](https://github.com/aws/aws-cdk/issues/19634)
+
+
+### Bug Fixes
+
+* **aws_applicationautoscaling:** Add missing members to PredefinedMetric enum ([#18978](https://github.com/aws/aws-cdk/issues/18978)) ([75a6fa7](https://github.com/aws/aws-cdk/commit/75a6fa75d053fc1172e83b57a27e4b450bb79729)), closes [#18969](https://github.com/aws/aws-cdk/issues/18969)
+* **cli:** apps with many resources scroll resource output offscreen ([#19742](https://github.com/aws/aws-cdk/issues/19742)) ([053d22c](https://github.com/aws/aws-cdk/commit/053d22cb77016e0e65157c8713fefedb3c0bf91b)), closes [#19160](https://github.com/aws/aws-cdk/issues/19160)
+* **cli:** support attributes of DynamoDB Tables for hotswapping ([#19620](https://github.com/aws/aws-cdk/issues/19620)) ([2321ece](https://github.com/aws/aws-cdk/commit/2321eced6cc16925c6d50e35b140f9ad4008d758)), closes [#19421](https://github.com/aws/aws-cdk/issues/19421)
+* **cloudwatch:** automatic metric math label cannot be suppressed ([#17639](https://github.com/aws/aws-cdk/issues/17639)) ([7fa3bf2](https://github.com/aws/aws-cdk/commit/7fa3bf2e385451171fcaeda388a93602cb12f4d8))
+* **codedeploy:** add name validation for Application, Deployment Group and Deployment Configuration ([#19473](https://github.com/aws/aws-cdk/issues/19473)) ([9185042](https://github.com/aws/aws-cdk/commit/91850423db97e7fa244d125a115477fa007a12a0))
+* **codedeploy:** the Service Principal is wrong in isolated regions ([#19729](https://github.com/aws/aws-cdk/issues/19729)) ([7e9a43d](https://github.com/aws/aws-cdk/commit/7e9a43dcad55645a8e816e39af54feeb04d7a8cf)), closes [#19399](https://github.com/aws/aws-cdk/issues/19399)
+* **core:** `Fn.select` incorrectly short-circuits complex expressions ([#19680](https://github.com/aws/aws-cdk/issues/19680)) ([7f26fad](https://github.com/aws/aws-cdk/commit/7f26fad5241756cdb6b15c9fb20995a96bba71f2))
+* **core:** detect and resolve stringified number tokens ([#19578](https://github.com/aws/aws-cdk/issues/19578)) ([7d9ab2a](https://github.com/aws/aws-cdk/commit/7d9ab2a783d1d3ae4508760149dee7ac263fdd44)), closes [#19546](https://github.com/aws/aws-cdk/issues/19546) [#19550](https://github.com/aws/aws-cdk/issues/19550)
+* **core:** reduce CFN template indent size to save bytes ([#19656](https://github.com/aws/aws-cdk/issues/19656)) ([fd63ca3](https://github.com/aws/aws-cdk/commit/fd63ca3995fb74b563a348589adf5fb06b4ef771))
+* **ecs:** 'desiredCount' and 'ephemeralStorageGiB' cannot be tokens ([#19453](https://github.com/aws/aws-cdk/issues/19453)) ([c852239](https://github.com/aws/aws-cdk/commit/c852239936b79581dbcf0dc8d56e3bb76a52e2dc)), closes [#16648](https://github.com/aws/aws-cdk/issues/16648)
+* **ecs:** remove unnecessary error when adding volume to external task definition ([#19774](https://github.com/aws/aws-cdk/issues/19774)) ([5446ded](https://github.com/aws/aws-cdk/commit/5446ded3d858098655b6427c9fdea56e77e2c0cd)), closes [#19259](https://github.com/aws/aws-cdk/issues/19259)
+* **iam:** policies aren't minimized as far as possible ([#19764](https://github.com/aws/aws-cdk/issues/19764)) ([876ed8a](https://github.com/aws/aws-cdk/commit/876ed8ad1726d6b77e7450eadbd1a4ded8236544)), closes [#19751](https://github.com/aws/aws-cdk/issues/19751)
+* **logs:** Faulty Resource Policy Generated ([#19640](https://github.com/aws/aws-cdk/issues/19640)) ([1fdf122](https://github.com/aws/aws-cdk/commit/1fdf1223304e15d905723553a40640b8bcb0ec56)), closes [#17544](https://github.com/aws/aws-cdk/issues/17544)
+
+## [1.151.0](https://github.com/aws/aws-cdk/compare/v1.150.0...v1.151.0) (2022-03-31)
+
+
+### Features
+
+* **aws-ec2:** Enable/disable EC2 "Detailed Monitoring" ([#19437](https://github.com/aws/aws-cdk/issues/19437)) ([94f9d27](https://github.com/aws/aws-cdk/commit/94f9d27e626bced5fc68a6ebbd653fea21c6e21e))
+* **cognito:** configure SNS region for UserPool SMS messages ([#19519](https://github.com/aws/aws-cdk/issues/19519)) ([6eb775e](https://github.com/aws/aws-cdk/commit/6eb775e829d62913bff849d43ed7339f9910d8de)), closes [#19434](https://github.com/aws/aws-cdk/issues/19434)
+* **core:** add size.isUnresolved ([#19569](https://github.com/aws/aws-cdk/issues/19569)) ([ed26731](https://github.com/aws/aws-cdk/commit/ed26731a0a6263482d76441fc06e9607963ac838))
+* **ecs-patterns:** PlacementStrategy and PlacementConstraint for many patterns ([#19612](https://github.com/aws/aws-cdk/issues/19612)) ([0096e67](https://github.com/aws/aws-cdk/commit/0096e672e02123a2ae4e094ba9bb11af3aef20b2))
+* **elbv2:** use `addAction()` on an imported application listener ([#19293](https://github.com/aws/aws-cdk/issues/19293)) ([18a6b0c](https://github.com/aws/aws-cdk/commit/18a6b0cecb5e8a419d09a1456953cb2f422a6d76)), closes [#10902](https://github.com/aws/aws-cdk/issues/10902)
+* **kinesisanalytics-flink:** Add metrics to Flink applications ([#19599](https://github.com/aws/aws-cdk/issues/19599)) ([dab6aca](https://github.com/aws/aws-cdk/commit/dab6aca5005c8d6d180aada699a4cebc2ef5aefa))
+* **lambda:** warn if you use `function.grantInvoke` while also using `currentVersion` ([#19464](https://github.com/aws/aws-cdk/issues/19464)) ([fd1fff9](https://github.com/aws/aws-cdk/commit/fd1fff904a70d18dc9c7863aefc03b3ee44c2863)), closes [#19273](https://github.com/aws/aws-cdk/issues/19273) [#19318](https://github.com/aws/aws-cdk/issues/19318)
+
+
+### Bug Fixes
+
+* **apigateway:** allow using GENERATE_IF_NEEDED for the physical name in LambdaRestApi ([#19638](https://github.com/aws/aws-cdk/issues/19638)) ([e817381](https://github.com/aws/aws-cdk/commit/e8173812aad5f482b1bfcc6737f63cfef0c4841c)), closes [#9374](https://github.com/aws/aws-cdk/issues/9374)
+* **apigateway:** id in schema model maps to $id ([#15113](https://github.com/aws/aws-cdk/issues/15113)) ([ac5a345](https://github.com/aws/aws-cdk/commit/ac5a3458fe3687014166b20aefe30442867d162a)), closes [#14585](https://github.com/aws/aws-cdk/issues/14585)
+* **aws-cognito:** Lambda::Permission of lambdaTrigger should have a SourceArn ([#19622](https://github.com/aws/aws-cdk/issues/19622)) ([c62eeb7](https://github.com/aws/aws-cdk/commit/c62eeb7162d85c8cb162f8c0ad4b93fb5bccf981)), closes [#19604](https://github.com/aws/aws-cdk/issues/19604)
+* **docdb:** DB Instance ARN uses 'docdb' as the service component instead of 'rds' ([#19555](https://github.com/aws/aws-cdk/issues/19555)) ([6a63924](https://github.com/aws/aws-cdk/commit/6a63924c0b184342befd92903b8867e45b158252)), closes [#19554](https://github.com/aws/aws-cdk/issues/19554)
+* **eks:** incorrect version of aws-node-termination-handler ([#19510](https://github.com/aws/aws-cdk/issues/19510)) ([9c712cc](https://github.com/aws/aws-cdk/commit/9c712cc457ccb80d7180fee67a101b76fc01d207))
+* **elbv2:** unable to add multiple certificates to NLB ([#19289](https://github.com/aws/aws-cdk/issues/19289)) ([e8142e9](https://github.com/aws/aws-cdk/commit/e8142e944ac5fae9948e5c010fe475806b83c94b)), closes [#13490](https://github.com/aws/aws-cdk/issues/13490) [#8918](https://github.com/aws/aws-cdk/issues/8918) [#15328](https://github.com/aws/aws-cdk/issues/15328)
+* **rds:** `SnapshotCredentials.fromSecret()` takes a `Secret`, not `ISecret` ([#19639](https://github.com/aws/aws-cdk/issues/19639)) ([a74d82e](https://github.com/aws/aws-cdk/commit/a74d82e667ba3cfbb3341392f7c641b0e29d47f0)), closes [#19409](https://github.com/aws/aws-cdk/issues/19409)
+
## [1.150.0](https://github.com/aws/aws-cdk/compare/v1.149.0...v1.150.0) (2022-03-26)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c769e0f191e1c..f435ae4589694 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -172,23 +172,49 @@ eval $(gp env -e)
## Pull Requests
+Below is a flow chart that describes how your PR may be treated by repository maintainers:
+
+```mermaid
+graph TD
+ A[Incoming PR] -->B[Is an issue attached?]
+ B -->|Yes - labels copied from issue| C[Is it labeled P1?]
+ B -->|No - auto-labeled as P2| D["Is the effort small?"]
+ C -->|Yes - P1| E[Is the PR build succeeding?]
+ C -->|No - it is P2| D
+ D -->|Yes| E
+ D -->|No| F[Can you break down the PR into smaller chunks?]
+ F --->|Yes| I[Please do. This will help get traction on your PR.]
+ F -->|No| J[Try to garner community support on the issue you are This container got built and started as part of the integ test. This container got built and started as part of the integ test. This container got built and started as part of the integ test. This container got built and started as part of the integ test. This container got built and started as part of the integ test. This container got built and started as part of the integ test. With markdown Allows the remote domain owner to accept an inbound cross-cluster connection request. Attaches tags to an existing domain. Tags are a set of case-sensitive key value pairs. An domain can have up to 10 tags. See Tagging Amazon OpenSearch Service domains for more information. Associates a package with an Amazon OpenSearch Service domain. Cancels a scheduled service software update for an Amazon OpenSearch Service domain. You can only perform this operation before the Creates a new Amazon OpenSearch Service domain. For more information, see Creating and managing Amazon OpenSearch Service domains in the Amazon OpenSearch Service Developer Guide. Creates a new cross-cluster connection from a local OpenSearch domain to a remote OpenSearch domain. Create a package for use with Amazon OpenSearch Service domains. Permanently deletes the specified domain and all of its data. Once a domain is deleted, it cannot be recovered. Allows the remote domain owner to delete an existing inbound cross-cluster connection. Allows the local domain owner to delete an existing outbound cross-cluster connection. Deletes the package. Returns domain configuration information about the specified domain, including the domain ID, domain endpoint, and domain ARN. Provides scheduled Auto-Tune action details for the domain, such as Auto-Tune action type, description, severity, and scheduled date. Provides cluster configuration information about the specified domain, such as the state, creation date, update version, and update date for cluster options. Returns domain configuration information about the specified domains, including the domain ID, domain endpoint, and domain ARN. Lists all the inbound cross-cluster connections for a remote domain. Describe the limits for a given instance type and OpenSearch or Elasticsearch version. When modifying an existing domain, specify the Lists all the outbound cross-cluster connections for a local domain. Describes all packages available to Amazon OpenSearch Service domains. Includes options for filtering, limiting the number of results, and pagination. Lists available reserved OpenSearch instance offerings. Returns information about reserved OpenSearch instances for this account. Dissociates a package from the Amazon OpenSearch Service domain. Returns a list of upgrade-compatible versions of OpenSearch/Elasticsearch. You can optionally pass a Returns a list of package versions, along with their creation time and commit message. Retrieves the complete history of the last 10 upgrades performed on the domain. Retrieves the latest status of the last upgrade or upgrade eligibility check performed on the domain. Returns the names of all domains owned by the current user's account. Lists all Amazon OpenSearch Service domains associated with the package. Lists all packages associated with the Amazon OpenSearch Service domain. Returns all tags for the given domain. List all supported versions of OpenSearch and Elasticsearch. Allows you to purchase reserved OpenSearch instances. Allows the remote domain owner to reject an inbound cross-cluster connection request. Removes the specified set of tags from the given domain. Schedules a service software update for an Amazon OpenSearch Service domain. Modifies the cluster configuration of the specified domain, such as setting the instance type and the number of instances. Updates a package for use with Amazon OpenSearch Service domains. Allows you to either upgrade your domain or perform an upgrade eligibility check to a compatible version of OpenSearch or Elasticsearch. The Amazon Resource Name (ARN) of the domain. See Identifiers for IAM Entities in Using AWS Identity and Access Management for more information. The ID of the inbound connection you want to accept. Container for the parameters to the The The result of an The access policy configured for the domain. Access policies can be resource-based, IP-based, or IAM-based. See Configuring access policiesfor more information. The status of the access policy for the domain. See The configured access rules for the domain's document and search endpoints, and the current status of those rules. Specify the List of Container for the parameters to the Additional limit is specific to a given InstanceType and for each of its
trying to solve. With 20 +1s, the issue will be relabeled as P1.]
+ E --->|Yes| G[We will review your PR as soon as we can]
+ E -->|No| H[If the build is failing for more than 4 weeks
without any work on it, we will close the PR.]
+```
+
+Note that, if we do not have time to review your PR, it is not the end of the road. We are asking
+for more community support on the attached issue before we focus our attention there. Any `P2` issue
+with 20 or more +1s will be automatically upgraded from `P2`to `P1`.
+
### Step 1: Find something to work on
-If you want to contribute a specific feature or fix you have in mind, look at active [pull
-requests](https://github.com/aws/aws-cdk/pulls) to see if someone else is already working on it. If not, you can start
-contributing your changes.
+If you want to contribute a specific feature or fix you have in mind, look to see if an issue
+already exists in our [backlog](https://github.com/aws/aws-cdk/issues). If not, please contribute
+a feature request or bug report prior to contributing the PR. We will triage this issue promptly,
+and the priority of the issue (`P1` or `P2`) will give indication of how much attention your PR
+may get.
+
+It's not required to submit an issue first, but PRs that come in without attached issues will be
+automatically labeled as `P2`.
On the other hand, if you are here looking for an issue to work on, explore our [backlog of
-issues](https://github.com/aws/aws-cdk/issues) and find something that piques your interest. We have labeled all of our
-issues for easy searching.
-If you are looking for your first contribution, the ['good first issue'
-label](https://github.com/aws/aws-cdk/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) will be of help.
+issues](https://github.com/aws/aws-cdk/issues) and find something that piques your interest.
+We have labeled all of our issues for easy searching. If you are looking for your first contribution,
+the ['good first issue' label](https://github.com/aws/aws-cdk/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
+will be of help.
It's a good idea to keep the priority of issues in mind when deciding what to
work on. If we have labelled an issue as `P2`, it means it's something we won't
get to soon, and we're waiting on more feedback from the community (in the form
of +1s and comments) to give it a higher priority. A PR for a `P2` issue may
-take us some time to review, especially if it involves a complex
+be closed by a maintainer, especially if it involves a complex
implementation. `P1` issues impact a significant number of customers, so we are
much more likely to give a PR for those issues prompt attention.
@@ -325,6 +351,9 @@ $ yarn watch & # runs in the background
* Once the pull request is submitted, a reviewer will be assigned by the maintainers.
+* If the PR build is failing, update the PR with fixes until the build succeeds. You may have trouble getting attention
+ from maintainers if your build is failing, and after 4 weeks of staleness, your PR will be automatically closed.
+
* Discuss review comments and iterate until you get at least one "Approve". When iterating, push new commits to the
same branch. Usually all these are going to be squashed when you merge to master. The commit messages should be hints
for you when you finalize your merge commit message.
diff --git a/INTEGRATION_TESTS.md b/INTEGRATION_TESTS.md
index 3f21037d95aa2..f6c95623d1093 100644
--- a/INTEGRATION_TESTS.md
+++ b/INTEGRATION_TESTS.md
@@ -10,13 +10,14 @@ on what type of changes require integrations tests and how you should write inte
- [New L2 Constructs](#new-l2-constructs)
- [Existing L2 Constructs](#existing-l2-constructs)
- [Assertions](#assertions)
+- [Running Integration Tests](#running-integration-tests)
## What are CDK Integration Tests
All Construct libraries in the CDK code base have integration tests that serve to -
1. Acts as a regression detector. It does this by running `cdk synth` on the integration test and comparing it against
- the `*.expected.json` file. This highlights how a change affects the synthesized stacks.
+ the Cloud Assembly stored in the snapshot (`*.integ.snapshot/`) directory. This highlights how a change affects the synthesized stacks.
2. Allows for a way to verify if the stacks are still valid CloudFormation templates, as part of an intrusive change.
This is done by running `yarn integ` which will run `cdk deploy` across all of the integration tests in that package.
If you are developing a new integration test or for some other reason want to work on a single integration test
@@ -102,14 +103,14 @@ To run the test you would run:
*Note - filename must be `*.js`*
```
-npm run cdk-integ integ.lambda.js
+yarn integ --update-on-failed integ.lambda.js
```
This will:
1. Synthesize the CDK app
2. `cdk deploy` to your AWS account
3. `cdk destroy` to delete the stack
-4. Save a snapshot of the synthed CloudFormation template to `integ.lambda.expected.json`
+4. Save a snapshot of the Cloud Assembly to `lambda.integ.snapshot/`
Now when you run `npm test` it will synth the integ app and compare the result with the snapshot.
If the snapshot has changed the same process must be followed to update the snapshot.
@@ -223,3 +224,40 @@ to deploy the Lambda Function _and_ then rerun the assertions to ensure that the
### Assertions
...Coming soon...
+
+## Running Integration Tests
+
+Most of the time you will only need to run integration tests for an individual module (i.e. `aws-lambda`). Other times you may need to run tests across multiple modules.
+In this case I would recommend running from the root directory like below.
+
+_Run snapshot tests only_
+```bash
+yarn integ-runner --directory packages/@aws-cdk
+```
+
+_Run snapshot tests and then re-run integration tests for failed snapshots_
+```bash
+yarn integ-runner --directory packages/@aws-cdk --update-on-failed
+```
+
+One benefit of running from the root directory like this is that it will only collect tests from "built" modules. If you have built the entire
+repo it will run all integration tests, but if you have only built a couple modules it will only run tests from those.
+
+### Running large numbers of Tests
+
+If you need to re-run a large number of tests you can run them in parallel like this.
+
+```bash
+yarn integ-runner --directory packages/@aws-cdk --update-on-failed \
+ --parallel-regions us-east-1 \
+ --parallel-regions us-east-2 \
+ --parallel-regions us-west-2 \
+ --parallel-regions eu-west-1 \
+ --profiles profile1 \
+ --profiles profile2 \
+ --profiles profile3 \
+ --verbose
+```
+
+When using both `--parallel-regions` and `--profiles` it will execute (regions*profiles) tests in parallel (in this example 12)
+If you want to execute more than 16 tests in parallel you can pass a higher value to `--max-workers`.
diff --git a/README.md b/README.md
index 7349b1909d6b1..ddf9cce9d3997 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,7 @@ For a detailed walkthrough, see the [tutorial](https://docs.aws.amazon.com/cdk/l
Install or update the [AWS CDK CLI] from npm (requires [Node.js ≥ 14.15.0](https://nodejs.org/download/release/latest-v14.x/)). We recommend using a version in [Active LTS](https://nodejs.org/en/about/releases/)
```console
-$ npm i -g aws-cdk
+npm i -g aws-cdk
```
(See [Manual Installation](./MANUAL_INSTALLATION.md) for installing the CDK from a signed .zip file).
@@ -87,9 +87,9 @@ $ npm i -g aws-cdk
Initialize a project:
```console
-$ mkdir hello-cdk
-$ cd hello-cdk
-$ cdk init sample-app --language=typescript
+mkdir hello-cdk
+cd hello-cdk
+cdk init sample-app --language=typescript
```
This creates a sample project looking like this:
@@ -113,7 +113,7 @@ export class HelloCdkStack extends cdk.Stack {
Deploy this to your account:
```console
-$ cdk deploy
+cdk deploy
```
Use the `cdk` command-line toolkit to interact with your project:
diff --git a/allowed-breaking-changes.txt b/allowed-breaking-changes.txt
index 864ea5178512b..371f4711ee727 100644
--- a/allowed-breaking-changes.txt
+++ b/allowed-breaking-changes.txt
@@ -75,7 +75,7 @@ strengthened:@aws-cdk/aws-stepfunctions-tasks.BatchSubmitJobProps
removed:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps.cluster
strengthened:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps
-# Remove IO2 from autoscaling EbsDeviceVolumeType. This value is not supported
+# Remove IO2 from autoscaling EbsDeviceVolumeType. This value is not supported
# at the moment and was not supported in the past.
removed:@aws-cdk/aws-autoscaling.EbsDeviceVolumeType.IO2
@@ -83,12 +83,12 @@ removed:@aws-cdk/aws-autoscaling.EbsDeviceVolumeType.IO2
removed:@aws-cdk/aws-stepfunctions-tasks.EmrCreateCluster.AutoTerminationPolicyProperty
removed:@aws-cdk/aws-stepfunctions-tasks.EmrCreateClusterProps.autoTerminationPolicy
-# Changed property securityGroupId to optional because either securityGroupId or
+# Changed property securityGroupId to optional because either securityGroupId or
# securityGroupName is required. Therefore securityGroupId is no longer mandatory.
weakened:@aws-cdk/cloud-assembly-schema.SecurityGroupContextQuery
# refactor autoscaling lifecycle hook target bind() methods to make role optional by
-# having bind() methods create the role if it isn't passed to them
+# having bind() methods create the role if it isn't passed to them
incompatible-argument:@aws-cdk/aws-autoscaling-hooktargets.FunctionHook.bind
incompatible-argument:@aws-cdk/aws-autoscaling-hooktargets.QueueHook.bind
incompatible-argument:@aws-cdk/aws-autoscaling-hooktargets.TopicHook.bind
@@ -106,7 +106,7 @@ removed:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps.maxRecord
removed:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps.parallelizationFactor
removed:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps.reportBatchItemFailures
removed:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps.retryAttempts
-removed:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps.tumblingWindow
+removed:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps.tumblingWindow
removed:@aws-cdk/aws-lambda-event-sources.SelfManagedKafkaEventSourceProps.bisectBatchOnError
removed:@aws-cdk/aws-lambda-event-sources.SelfManagedKafkaEventSourceProps.maxRecordAge
removed:@aws-cdk/aws-lambda-event-sources.SelfManagedKafkaEventSourceProps.parallelizationFactor
@@ -125,4 +125,17 @@ changed-type:@aws-cdk/aws-elasticloadbalancingv2.NetworkLoadBalancer.vpc
# removed methods and properties related to event bridge notifications for S3 buckets as they are not yet supported (19 Jan 2022)
removed:@aws-cdk/aws-s3.Bucket.enableEventBridgeNotification
removed:@aws-cdk/aws-s3.BucketBase.enableEventBridgeNotification
-removed:@aws-cdk/aws-s3.BucketProps.eventBridgeEnabled
\ No newline at end of file
+removed:@aws-cdk/aws-s3.BucketProps.eventBridgeEnabled
+
+# changed the type of RDS's SnapshotCredentials.secret from Secret to ISecret,
+# shouldn't matter
+changed-type:@aws-cdk/aws-rds.SnapshotCredentials.secret
+
+# removed property from kafka eventsources as they are not supported
+removed:@aws-cdk/aws-lambda-event-sources.BaseStreamEventSourceProps.onFailure
+removed:@aws-cdk/aws-lambda-event-sources.KafkaEventSourceProps.onFailure
+removed:@aws-cdk/aws-lambda-event-sources.ManagedKafkaEventSourceProps.onFailure
+removed:@aws-cdk/aws-lambda-event-sources.SelfManagedKafkaEventSourceProps.onFailure
+
+# removed kubernetes version from EKS
+removed:@aws-cdk/aws-eks.KubernetesVersion.V1_22
diff --git a/deprecated_apis.txt b/deprecated_apis.txt
index aa0ae3918b0d6..1f52234d183f6 100644
--- a/deprecated_apis.txt
+++ b/deprecated_apis.txt
@@ -27,7 +27,6 @@
@aws-cdk/core.DefaultStackSynthesizerProps#fileAssetKeyArnExportName
@aws-cdk/core.DockerImageAssetSource#repositoryName
@aws-cdk/core.Duration#toISOString
-@aws-cdk/core.FileAssetLocation#kmsKeyArn
@aws-cdk/core.FileAssetLocation#s3Url
@aws-cdk/core.ITemplateOptions#transform
@aws-cdk/core.Lazy#anyValue
@@ -754,7 +753,6 @@ constructs.Node#uniqueId
@aws-cdk/aws-cloudfront.AliasConfiguration#names
@aws-cdk/aws-cloudfront.AliasConfiguration#securityPolicy
@aws-cdk/aws-cloudfront.AliasConfiguration#sslMethod
-@aws-cdk/aws-cloudfront.Behavior#trustedSigners
@aws-cdk/aws-cloudfront.CloudFrontWebDistribution#domainName
@aws-cdk/aws-cloudfront.CloudFrontWebDistributionProps#aliasConfiguration
@aws-cdk/aws-cloudfront.GeoRestriction#blacklist
diff --git a/design/aws-ecs/aws-ecs-priv-registry-support.md b/design/aws-ecs/aws-ecs-priv-registry-support.md
index 91c4618f50621..9d1f5451409a6 100644
--- a/design/aws-ecs/aws-ecs-priv-registry-support.md
+++ b/design/aws-ecs/aws-ecs-priv-registry-support.md
@@ -16,7 +16,7 @@ DockerHub images are assumed public, however DockerHub also provides private rep
There's also no explicit way to specify images hosted outside of DockerHub, AWS, or your local machine. Customers hosting their own registries or using another registry host, like Quay.io or JFrog Artifactory, would need to be able to specify both the image URI and the registry credentials in order to pull their images down for ECS tasks.
-Fundamentally, specifying images hosted in DockerHub or elsewhere works the same, because when passed an image URI vs. a plain (or namespaced) image name + tag, the Docker daemon does the right thing and tries to pull the image from the specified registery.
+Fundamentally, specifying images hosted in DockerHub or elsewhere works the same, because when passed an image URI vs. a plain (or namespaced) image name + tag, the Docker daemon does the right thing and tries to pull the image from the specified registry.
Therefore, we should rename the existing `DockerHubImage` type be more generic and add the ability to optionally specify credentials.
diff --git a/package.json b/package.json
index 7680a471da635..c14d5e45cac13 100644
--- a/package.json
+++ b/package.json
@@ -19,12 +19,12 @@
"cdk-generate-synthetic-examples": "^0.1.8",
"conventional-changelog-cli": "^2.2.2",
"fs-extra": "^9.1.0",
- "graceful-fs": "^4.2.9",
- "jest-junit": "^13.0.0",
- "jsii-diff": "^1.55.1",
- "jsii-pacmak": "^1.55.1",
- "jsii-reflect": "^1.55.1",
- "jsii-rosetta": "^1.55.1",
+ "graceful-fs": "^4.2.10",
+ "jest-junit": "^13.1.0",
+ "jsii-diff": "^1.57.0",
+ "jsii-pacmak": "^1.57.0",
+ "jsii-reflect": "^1.57.0",
+ "jsii-rosetta": "^1.57.0",
"lerna": "^4.0.0",
"patch-package": "^6.4.7",
"semver": "^6.3.0",
diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/.gitignore b/packages/@aws-cdk-containers/ecs-service-extensions/.gitignore
index 5bd97777170a0..0865b27d394a2 100644
--- a/packages/@aws-cdk-containers/ecs-service-extensions/.gitignore
+++ b/packages/@aws-cdk-containers/ecs-service-extensions/.gitignore
@@ -19,4 +19,8 @@ nyc.config.js
junit.xml
-!jest.config.js
\ No newline at end of file
+!jest.config.js
+!**/*.integ.snapshot/**/asset.*/*.js
+!**/*.integ.snapshot/**/asset.*/*.d.ts
+
+!**/*.integ.snapshot/**/asset.*/**
diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/.npmignore b/packages/@aws-cdk-containers/ecs-service-extensions/.npmignore
index 163c1ff80fe5a..9bcdfbb4d0764 100644
--- a/packages/@aws-cdk-containers/ecs-service-extensions/.npmignore
+++ b/packages/@aws-cdk-containers/ecs-service-extensions/.npmignore
@@ -24,4 +24,6 @@ tsconfig.json
junit.xml
test/
-jest.config.js
\ No newline at end of file
+jest.config.js
+**/*.integ.snapshot
+**/*.integ.snapshot
diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/README.md b/packages/@aws-cdk-containers/ecs-service-extensions/README.md
index 84dd42fc93eff..49ebf7186ef2a 100644
--- a/packages/@aws-cdk-containers/ecs-service-extensions/README.md
+++ b/packages/@aws-cdk-containers/ecs-service-extensions/README.md
@@ -9,6 +9,11 @@
+> ⚠️ v2 of this library is now available! It is compatible with AWS CDK v2 and available in
+> multiple languages.
+> The source code for v2 lives [here](https://github.com/cdklabs/cdk-ecs-service-extensions).
+> To migrate from this library to v2, see the [Migration Guide](https://github.com/cdklabs/cdk-ecs-service-extensions/blob/main/MIGRATING.md).
+
This library provides a high level, extensible pattern for constructing services
deployed using Amazon ECS.
diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/package.json b/packages/@aws-cdk-containers/ecs-service-extensions/package.json
index 3587f60c10eda..9ab34110fe6cb 100644
--- a/packages/@aws-cdk-containers/ecs-service-extensions/package.json
+++ b/packages/@aws-cdk-containers/ecs-service-extensions/package.json
@@ -14,7 +14,7 @@
"watch": "cdk-watch",
"lint": "cdk-lint",
"test": "cdk-test",
- "integ": "cdk-integ",
+ "integ": "integ-runner",
"pkglint": "pkglint -f",
"package": "cdk-package",
"awslint": "cdk-awslint",
@@ -39,7 +39,7 @@
"devDependencies": {
"@types/jest": "^27.4.1",
"@aws-cdk/cdk-build-tools": "0.0.0",
- "@aws-cdk/cdk-integ-tools": "0.0.0",
+ "@aws-cdk/integ-runner": "0.0.0",
"@aws-cdk/aws-autoscaling": "0.0.0",
"@aws-cdk/cfn2ts": "0.0.0",
"jest": "^27.5.1",
diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/test/all-service-addons.integ.snapshot/aws-ecs-integ.template.json b/packages/@aws-cdk-containers/ecs-service-extensions/test/all-service-addons.integ.snapshot/aws-ecs-integ.template.json
new file mode 100644
index 0000000000000..de73b03a2adba
--- /dev/null
+++ b/packages/@aws-cdk-containers/ecs-service-extensions/test/all-service-addons.integ.snapshot/aws-ecs-integ.template.json
@@ -0,0 +1,3311 @@
+{
+ "Resources": {
+ "mymeshEA67EDEF": {
+ "Type": "AWS::AppMesh::Mesh",
+ "Properties": {
+ "MeshName": "awsecsintegmymeshFCC0D554",
+ "Spec": {}
+ }
+ },
+ "productionenvironmentvpcAEB47DF7": {
+ "Type": "AWS::EC2::VPC",
+ "Properties": {
+ "CidrBlock": "10.0.0.0/16",
+ "EnableDnsHostnames": true,
+ "EnableDnsSupport": true,
+ "InstanceTenancy": "default",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPublicSubnet1Subnet8D92C089": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.0.0/18",
+ "MapPublicIpOnLaunch": true,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Public"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Public"
+ },
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPublicSubnet1RouteTable6E9ABC21": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPublicSubnet1RouteTableAssociationA8117374": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "productionenvironmentvpcPublicSubnet1RouteTable6E9ABC21"
+ },
+ "SubnetId": {
+ "Ref": "productionenvironmentvpcPublicSubnet1Subnet8D92C089"
+ }
+ }
+ },
+ "productionenvironmentvpcPublicSubnet1DefaultRoute524C894D": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "productionenvironmentvpcPublicSubnet1RouteTable6E9ABC21"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "GatewayId": {
+ "Ref": "productionenvironmentvpcIGWE7C39890"
+ }
+ },
+ "DependsOn": [
+ "productionenvironmentvpcVPCGW1B428D07"
+ ]
+ },
+ "productionenvironmentvpcPublicSubnet1EIP54BA88DB": {
+ "Type": "AWS::EC2::EIP",
+ "Properties": {
+ "Domain": "vpc",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPublicSubnet1NATGateway6075E4CA": {
+ "Type": "AWS::EC2::NatGateway",
+ "Properties": {
+ "SubnetId": {
+ "Ref": "productionenvironmentvpcPublicSubnet1Subnet8D92C089"
+ },
+ "AllocationId": {
+ "Fn::GetAtt": [
+ "productionenvironmentvpcPublicSubnet1EIP54BA88DB",
+ "AllocationId"
+ ]
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPublicSubnet2Subnet298E6C31": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.64.0/18",
+ "MapPublicIpOnLaunch": true,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Public"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Public"
+ },
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPublicSubnet2RouteTable842A68D7": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPublicSubnet2RouteTableAssociation0A7549F3": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "productionenvironmentvpcPublicSubnet2RouteTable842A68D7"
+ },
+ "SubnetId": {
+ "Ref": "productionenvironmentvpcPublicSubnet2Subnet298E6C31"
+ }
+ }
+ },
+ "productionenvironmentvpcPublicSubnet2DefaultRoute92CD697D": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "productionenvironmentvpcPublicSubnet2RouteTable842A68D7"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "GatewayId": {
+ "Ref": "productionenvironmentvpcIGWE7C39890"
+ }
+ },
+ "DependsOn": [
+ "productionenvironmentvpcVPCGW1B428D07"
+ ]
+ },
+ "productionenvironmentvpcPublicSubnet2EIP14CA46AA": {
+ "Type": "AWS::EC2::EIP",
+ "Properties": {
+ "Domain": "vpc",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPublicSubnet2NATGatewayE1850FCC": {
+ "Type": "AWS::EC2::NatGateway",
+ "Properties": {
+ "SubnetId": {
+ "Ref": "productionenvironmentvpcPublicSubnet2Subnet298E6C31"
+ },
+ "AllocationId": {
+ "Fn::GetAtt": [
+ "productionenvironmentvpcPublicSubnet2EIP14CA46AA",
+ "AllocationId"
+ ]
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPrivateSubnet1Subnet53F632E6": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.128.0/18",
+ "MapPublicIpOnLaunch": false,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Private"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Private"
+ },
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPrivateSubnet1RouteTable2C6DFF0C": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPrivateSubnet1RouteTableAssociation8BA32463": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "productionenvironmentvpcPrivateSubnet1RouteTable2C6DFF0C"
+ },
+ "SubnetId": {
+ "Ref": "productionenvironmentvpcPrivateSubnet1Subnet53F632E6"
+ }
+ }
+ },
+ "productionenvironmentvpcPrivateSubnet1DefaultRouteFBB3DE6C": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "productionenvironmentvpcPrivateSubnet1RouteTable2C6DFF0C"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "NatGatewayId": {
+ "Ref": "productionenvironmentvpcPublicSubnet1NATGateway6075E4CA"
+ }
+ }
+ },
+ "productionenvironmentvpcPrivateSubnet2Subnet756FB93C": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.192.0/18",
+ "MapPublicIpOnLaunch": false,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Private"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Private"
+ },
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPrivateSubnet2RouteTable2F77D0D2": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcPrivateSubnet2RouteTableAssociation09188261": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "productionenvironmentvpcPrivateSubnet2RouteTable2F77D0D2"
+ },
+ "SubnetId": {
+ "Ref": "productionenvironmentvpcPrivateSubnet2Subnet756FB93C"
+ }
+ }
+ },
+ "productionenvironmentvpcPrivateSubnet2DefaultRoute5F9AB6C1": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "productionenvironmentvpcPrivateSubnet2RouteTable2F77D0D2"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "NatGatewayId": {
+ "Ref": "productionenvironmentvpcPublicSubnet2NATGatewayE1850FCC"
+ }
+ }
+ },
+ "productionenvironmentvpcIGWE7C39890": {
+ "Type": "AWS::EC2::InternetGateway",
+ "Properties": {
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "aws-ecs-integ/production-environment-vpc"
+ }
+ ]
+ }
+ },
+ "productionenvironmentvpcVPCGW1B428D07": {
+ "Type": "AWS::EC2::VPCGatewayAttachment",
+ "Properties": {
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ },
+ "InternetGatewayId": {
+ "Ref": "productionenvironmentvpcIGWE7C39890"
+ }
+ }
+ },
+ "productionenvironmentclusterC6599D2D": {
+ "Type": "AWS::ECS::Cluster"
+ },
+ "productionenvironmentclusterDefaultServiceDiscoveryNamespaceBE74D64D": {
+ "Type": "AWS::ServiceDiscovery::PrivateDnsNamespace",
+ "Properties": {
+ "Name": "production",
+ "Vpc": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ }
+ }
+ },
+ "namelogsF4B17D31": {
+ "Type": "AWS::Logs::LogGroup",
+ "Properties": {
+ "LogGroupName": "name-logs",
+ "RetentionInDays": 7
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "nametaskdefinitionTaskRole50FE844E": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "ecs-tasks.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/AWSXRayDaemonWriteAccess"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "nametaskdefinitionTaskRoleDefaultPolicyE66EDC68": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "logs:CreateLogGroup",
+ "logs:CreateLogStream",
+ "logs:DescribeLogStreams",
+ "logs:PutLogEvents"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "nametaskdefinitionTaskRoleDefaultPolicyE66EDC68",
+ "Roles": [
+ {
+ "Ref": "nametaskdefinitionTaskRole50FE844E"
+ }
+ ]
+ }
+ },
+ "nametaskdefinition690762BB": {
+ "Type": "AWS::ECS::TaskDefinition",
+ "Properties": {
+ "ContainerDefinitions": [
+ {
+ "Cpu": 1024,
+ "DependsOn": [
+ {
+ "Condition": "START",
+ "ContainerName": "firelens"
+ },
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ },
+ {
+ "Condition": "START",
+ "ContainerName": "cloudwatch-agent"
+ },
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "xray"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "PORT",
+ "Value": "80"
+ }
+ ],
+ "Essential": true,
+ "Image": "nathanpeck/name",
+ "LogConfiguration": {
+ "LogDriver": "awsfirelens",
+ "Options": {
+ "Name": "cloudwatch",
+ "region": {
+ "Ref": "AWS::Region"
+ },
+ "log_group_name": {
+ "Ref": "namelogsF4B17D31"
+ },
+ "log_stream_prefix": "name/"
+ }
+ },
+ "Memory": 2048,
+ "Name": "app",
+ "PortMappings": [
+ {
+ "ContainerPort": 80,
+ "Protocol": "tcp"
+ }
+ ],
+ "Ulimits": [
+ {
+ "HardLimit": 1024000,
+ "Name": "nofile",
+ "SoftLimit": 1024000
+ }
+ ]
+ },
+ {
+ "Environment": [
+ {
+ "Name": "APPMESH_VIRTUAL_NODE_NAME",
+ "Value": {
+ "Fn::Join": [
+ "",
+ [
+ "mesh/",
+ {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "/virtualNode/name"
+ ]
+ ]
+ }
+ },
+ {
+ "Name": "AWS_REGION",
+ "Value": {
+ "Ref": "AWS::Region"
+ }
+ },
+ {
+ "Name": "ENABLE_ENVOY_STATS_TAGS",
+ "Value": "1"
+ },
+ {
+ "Name": "ENABLE_ENVOY_DOG_STATSD",
+ "Value": "1"
+ }
+ ],
+ "Essential": true,
+ "HealthCheck": {
+ "Command": [
+ "CMD-SHELL",
+ "curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
+ ],
+ "Interval": 5,
+ "Retries": 3,
+ "StartPeriod": 10,
+ "Timeout": 2
+ },
+ "Image": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::FindInMap": [
+ "nameenvoyimageaccountmapping",
+ {
+ "Ref": "AWS::Region"
+ },
+ "ecrRepo"
+ ]
+ },
+ ".dkr.ecr.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".",
+ {
+ "Ref": "AWS::URLSuffix"
+ },
+ "/aws-appmesh-envoy:v1.15.1.0-prod"
+ ]
+ ]
+ },
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "nametaskdefinitionenvoyLogGroup258B673B"
+ },
+ "awslogs-stream-prefix": "envoy",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 128,
+ "Name": "envoy",
+ "Ulimits": [
+ {
+ "HardLimit": 1024000,
+ "Name": "nofile",
+ "SoftLimit": 1024000
+ }
+ ],
+ "User": "1337"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Essential": true,
+ "FirelensConfiguration": {
+ "Type": "fluentbit"
+ },
+ "Image": {
+ "Ref": "SsmParameterValueawsserviceawsforfluentbitlatestC96584B6F00A464EAD1953AFF4B05118Parameter"
+ },
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "nametaskdefinitionfirelensLogGroup80DDA60F"
+ },
+ "awslogs-stream-prefix": "firelens",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 50,
+ "Name": "firelens",
+ "User": "0:1338"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "AWS_REGION",
+ "Value": {
+ "Ref": "AWS::Region"
+ }
+ }
+ ],
+ "Essential": true,
+ "HealthCheck": {
+ "Command": [
+ "CMD-SHELL",
+ "curl -s http://localhost:2000"
+ ],
+ "Interval": 5,
+ "Retries": 3,
+ "StartPeriod": 10,
+ "Timeout": 2
+ },
+ "Image": "amazon/aws-xray-daemon:latest",
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "nametaskdefinitionxrayLogGroup4AF4CA37"
+ },
+ "awslogs-stream-prefix": "xray",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 256,
+ "Name": "xray",
+ "User": "1337"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "CW_CONFIG_CONTENT",
+ "Value": "{\"logs\":{\"metrics_collected\":{\"emf\":{}}},\"metrics\":{\"metrics_collected\":{\"statsd\":{}}}}"
+ }
+ ],
+ "Essential": true,
+ "Image": "amazon/cloudwatch-agent:latest",
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "nametaskdefinitioncloudwatchagentLogGroup78DDC685"
+ },
+ "awslogs-stream-prefix": "cloudwatch-agent",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 50,
+ "Name": "cloudwatch-agent",
+ "User": "0:1338"
+ }
+ ],
+ "Cpu": "1024",
+ "ExecutionRoleArn": {
+ "Fn::GetAtt": [
+ "nametaskdefinitionExecutionRole45AC5C9A",
+ "Arn"
+ ]
+ },
+ "Family": "awsecsintegnametaskdefinition0EA6A1A0",
+ "Memory": "2048",
+ "NetworkMode": "awsvpc",
+ "ProxyConfiguration": {
+ "ContainerName": "envoy",
+ "ProxyConfigurationProperties": [
+ {
+ "Name": "AppPorts",
+ "Value": "80"
+ },
+ {
+ "Name": "ProxyEgressPort",
+ "Value": "15001"
+ },
+ {
+ "Name": "ProxyIngressPort",
+ "Value": "15000"
+ },
+ {
+ "Name": "IgnoredUID",
+ "Value": "1337"
+ },
+ {
+ "Name": "IgnoredGID",
+ "Value": "1338"
+ },
+ {
+ "Name": "EgressIgnoredIPs",
+ "Value": "169.254.170.2,169.254.169.254"
+ }
+ ],
+ "Type": "APPMESH"
+ },
+ "RequiresCompatibilities": [
+ "EC2",
+ "FARGATE"
+ ],
+ "TaskRoleArn": {
+ "Fn::GetAtt": [
+ "nametaskdefinitionTaskRole50FE844E",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "nametaskdefinitionenvoyLogGroup258B673B": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "nametaskdefinitionExecutionRole45AC5C9A": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "ecs-tasks.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "nametaskdefinitionExecutionRoleDefaultPolicyF7942D20": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "ecr:BatchCheckLayerAvailability",
+ "ecr:BatchGetImage",
+ "ecr:GetDownloadUrlForLayer"
+ ],
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":ecr:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Fn::FindInMap": [
+ "nameenvoyimageaccountmapping",
+ {
+ "Ref": "AWS::Region"
+ },
+ "ecrRepo"
+ ]
+ },
+ ":repository/aws-appmesh-envoy"
+ ]
+ ]
+ }
+ },
+ {
+ "Action": [
+ "ecr:BatchCheckLayerAvailability",
+ "ecr:BatchGetImage",
+ "ecr:GetAuthorizationToken",
+ "ecr:GetDownloadUrlForLayer"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ },
+ {
+ "Action": [
+ "logs:CreateLogStream",
+ "logs:PutLogEvents"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "nametaskdefinitioncloudwatchagentLogGroup78DDC685",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "nametaskdefinitionenvoyLogGroup258B673B",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "nametaskdefinitionfirelensLogGroup80DDA60F",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "nametaskdefinitionxrayLogGroup4AF4CA37",
+ "Arn"
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "nametaskdefinitionExecutionRoleDefaultPolicyF7942D20",
+ "Roles": [
+ {
+ "Ref": "nametaskdefinitionExecutionRole45AC5C9A"
+ }
+ ]
+ }
+ },
+ "nametaskdefinitionfirelensLogGroup80DDA60F": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "nametaskdefinitionxrayLogGroup4AF4CA37": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "nametaskdefinitioncloudwatchagentLogGroup78DDC685": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "nameenvoytoappmesh2767D3E6": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "appmesh:StreamAggregatedResources",
+ "Effect": "Allow",
+ "Resource": {
+ "Ref": "mymeshEA67EDEF"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "nameenvoytoappmesh2767D3E6",
+ "Roles": [
+ {
+ "Ref": "nametaskdefinitionTaskRole50FE844E"
+ }
+ ]
+ }
+ },
+ "namepublishmetricsF329C7AE": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "cloudwatch:PutMetricData",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "namepublishmetricsF329C7AE",
+ "Roles": [
+ {
+ "Ref": "nametaskdefinitionTaskRole50FE844E"
+ }
+ ]
+ }
+ },
+ "nameserviceService8015C8D6": {
+ "Type": "AWS::ECS::Service",
+ "Properties": {
+ "Cluster": {
+ "Ref": "productionenvironmentclusterC6599D2D"
+ },
+ "DeploymentConfiguration": {
+ "MaximumPercent": 150,
+ "MinimumHealthyPercent": 100
+ },
+ "DesiredCount": 2,
+ "EnableECSManagedTags": false,
+ "LaunchType": "FARGATE",
+ "NetworkConfiguration": {
+ "AwsvpcConfiguration": {
+ "AssignPublicIp": "DISABLED",
+ "SecurityGroups": [
+ {
+ "Fn::GetAtt": [
+ "nameserviceSecurityGroup33F4662C",
+ "GroupId"
+ ]
+ }
+ ],
+ "Subnets": [
+ {
+ "Ref": "productionenvironmentvpcPrivateSubnet1Subnet53F632E6"
+ },
+ {
+ "Ref": "productionenvironmentvpcPrivateSubnet2Subnet756FB93C"
+ }
+ ]
+ }
+ },
+ "ServiceRegistries": [
+ {
+ "RegistryArn": {
+ "Fn::GetAtt": [
+ "nameserviceCloudmapService3D5B0548",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "TaskDefinition": {
+ "Ref": "nametaskdefinition690762BB"
+ }
+ }
+ },
+ "nameserviceCloudmapService3D5B0548": {
+ "Type": "AWS::ServiceDiscovery::Service",
+ "Properties": {
+ "DnsConfig": {
+ "DnsRecords": [
+ {
+ "TTL": 10,
+ "Type": "A"
+ }
+ ],
+ "NamespaceId": {
+ "Fn::GetAtt": [
+ "productionenvironmentclusterDefaultServiceDiscoveryNamespaceBE74D64D",
+ "Id"
+ ]
+ },
+ "RoutingPolicy": "MULTIVALUE"
+ },
+ "HealthCheckCustomConfig": {
+ "FailureThreshold": 2
+ },
+ "Name": "name",
+ "NamespaceId": {
+ "Fn::GetAtt": [
+ "productionenvironmentclusterDefaultServiceDiscoveryNamespaceBE74D64D",
+ "Id"
+ ]
+ }
+ }
+ },
+ "nameserviceSecurityGroup33F4662C": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Properties": {
+ "GroupDescription": "aws-ecs-integ/name-service/SecurityGroup",
+ "SecurityGroupEgress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow all outbound traffic by default",
+ "IpProtocol": "-1"
+ }
+ ],
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ }
+ }
+ },
+ "nameserviceSecurityGroupfromawsecsinteggreeterserviceSecurityGroup055DC23B8048057EFF": {
+ "Type": "AWS::EC2::SecurityGroupIngress",
+ "Properties": {
+ "IpProtocol": "tcp",
+ "Description": "Accept inbound traffic from greeter",
+ "FromPort": 80,
+ "GroupId": {
+ "Fn::GetAtt": [
+ "nameserviceSecurityGroup33F4662C",
+ "GroupId"
+ ]
+ },
+ "SourceSecurityGroupId": {
+ "Fn::GetAtt": [
+ "greeterserviceSecurityGroupDB4AC3A9",
+ "GroupId"
+ ]
+ },
+ "ToPort": 80
+ }
+ },
+ "nameserviceTaskCountTarget366C2B3A": {
+ "Type": "AWS::ApplicationAutoScaling::ScalableTarget",
+ "Properties": {
+ "MaxCapacity": 8,
+ "MinCapacity": 2,
+ "ResourceId": {
+ "Fn::Join": [
+ "",
+ [
+ "service/",
+ {
+ "Ref": "productionenvironmentclusterC6599D2D"
+ },
+ "/",
+ {
+ "Fn::GetAtt": [
+ "nameserviceService8015C8D6",
+ "Name"
+ ]
+ }
+ ]
+ ]
+ },
+ "RoleARN": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"
+ ]
+ ]
+ },
+ "ScalableDimension": "ecs:service:DesiredCount",
+ "ServiceNamespace": "ecs"
+ }
+ },
+ "nameserviceTaskCountTargetnametargetcpuutilization5018B16243": {
+ "Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
+ "Properties": {
+ "PolicyName": "awsecsintegnameserviceTaskCountTargetnametargetcpuutilization50CAB59E05",
+ "PolicyType": "TargetTrackingScaling",
+ "ScalingTargetId": {
+ "Ref": "nameserviceTaskCountTarget366C2B3A"
+ },
+ "TargetTrackingScalingPolicyConfiguration": {
+ "PredefinedMetricSpecification": {
+ "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
+ },
+ "ScaleInCooldown": 60,
+ "ScaleOutCooldown": 60,
+ "TargetValue": 50
+ }
+ }
+ },
+ "namevirtualnode6C99CB14": {
+ "Type": "AWS::AppMesh::VirtualNode",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Listeners": [
+ {
+ "PortMapping": {
+ "Port": 80,
+ "Protocol": "http"
+ }
+ }
+ ],
+ "ServiceDiscovery": {
+ "AWSCloudMap": {
+ "NamespaceName": "production",
+ "ServiceName": {
+ "Fn::GetAtt": [
+ "nameserviceCloudmapService3D5B0548",
+ "Name"
+ ]
+ }
+ }
+ }
+ },
+ "VirtualNodeName": "name"
+ }
+ },
+ "namevirtualrouterC00E1ACE": {
+ "Type": "AWS::AppMesh::VirtualRouter",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Listeners": [
+ {
+ "PortMapping": {
+ "Port": 80,
+ "Protocol": "http"
+ }
+ }
+ ]
+ },
+ "VirtualRouterName": "name"
+ }
+ },
+ "namevirtualrouternamerouteDCDF3715": {
+ "Type": "AWS::AppMesh::Route",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "HttpRoute": {
+ "Action": {
+ "WeightedTargets": [
+ {
+ "VirtualNode": {
+ "Fn::GetAtt": [
+ "namevirtualnode6C99CB14",
+ "VirtualNodeName"
+ ]
+ },
+ "Weight": 1
+ }
+ ]
+ },
+ "Match": {
+ "Prefix": "/"
+ }
+ }
+ },
+ "VirtualRouterName": {
+ "Fn::GetAtt": [
+ "namevirtualrouterC00E1ACE",
+ "VirtualRouterName"
+ ]
+ },
+ "RouteName": "name-route"
+ }
+ },
+ "namevirtualservice3DDDDF1E": {
+ "Type": "AWS::AppMesh::VirtualService",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Provider": {
+ "VirtualRouter": {
+ "VirtualRouterName": {
+ "Fn::GetAtt": [
+ "namevirtualrouterC00E1ACE",
+ "VirtualRouterName"
+ ]
+ }
+ }
+ }
+ },
+ "VirtualServiceName": "name.production"
+ }
+ },
+ "greetinglogsCC360934": {
+ "Type": "AWS::Logs::LogGroup",
+ "Properties": {
+ "LogGroupName": "greeting-logs",
+ "RetentionInDays": 7
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "greetingtaskdefinitionTaskRole9179DA4A": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "ecs-tasks.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/AWSXRayDaemonWriteAccess"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "greetingtaskdefinitionTaskRoleDefaultPolicy5DB4510A": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "logs:CreateLogGroup",
+ "logs:CreateLogStream",
+ "logs:DescribeLogStreams",
+ "logs:PutLogEvents"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "greetingtaskdefinitionTaskRoleDefaultPolicy5DB4510A",
+ "Roles": [
+ {
+ "Ref": "greetingtaskdefinitionTaskRole9179DA4A"
+ }
+ ]
+ }
+ },
+ "greetingtaskdefinition31690093": {
+ "Type": "AWS::ECS::TaskDefinition",
+ "Properties": {
+ "ContainerDefinitions": [
+ {
+ "Cpu": 1024,
+ "DependsOn": [
+ {
+ "Condition": "START",
+ "ContainerName": "firelens"
+ },
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ },
+ {
+ "Condition": "START",
+ "ContainerName": "cloudwatch-agent"
+ },
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "xray"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "PORT",
+ "Value": "80"
+ }
+ ],
+ "Essential": true,
+ "Image": "nathanpeck/greeting",
+ "LogConfiguration": {
+ "LogDriver": "awsfirelens",
+ "Options": {
+ "Name": "cloudwatch",
+ "region": {
+ "Ref": "AWS::Region"
+ },
+ "log_group_name": {
+ "Ref": "greetinglogsCC360934"
+ },
+ "log_stream_prefix": "greeting/"
+ }
+ },
+ "Memory": 2048,
+ "Name": "app",
+ "PortMappings": [
+ {
+ "ContainerPort": 80,
+ "Protocol": "tcp"
+ }
+ ],
+ "Ulimits": [
+ {
+ "HardLimit": 1024000,
+ "Name": "nofile",
+ "SoftLimit": 1024000
+ }
+ ]
+ },
+ {
+ "Environment": [
+ {
+ "Name": "APPMESH_VIRTUAL_NODE_NAME",
+ "Value": {
+ "Fn::Join": [
+ "",
+ [
+ "mesh/",
+ {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "/virtualNode/greeting"
+ ]
+ ]
+ }
+ },
+ {
+ "Name": "AWS_REGION",
+ "Value": {
+ "Ref": "AWS::Region"
+ }
+ },
+ {
+ "Name": "ENABLE_ENVOY_STATS_TAGS",
+ "Value": "1"
+ },
+ {
+ "Name": "ENABLE_ENVOY_DOG_STATSD",
+ "Value": "1"
+ }
+ ],
+ "Essential": true,
+ "HealthCheck": {
+ "Command": [
+ "CMD-SHELL",
+ "curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
+ ],
+ "Interval": 5,
+ "Retries": 3,
+ "StartPeriod": 10,
+ "Timeout": 2
+ },
+ "Image": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::FindInMap": [
+ "greetingenvoyimageaccountmapping",
+ {
+ "Ref": "AWS::Region"
+ },
+ "ecrRepo"
+ ]
+ },
+ ".dkr.ecr.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".",
+ {
+ "Ref": "AWS::URLSuffix"
+ },
+ "/aws-appmesh-envoy:v1.15.1.0-prod"
+ ]
+ ]
+ },
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "greetingtaskdefinitionenvoyLogGroup6556AC35"
+ },
+ "awslogs-stream-prefix": "envoy",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 128,
+ "Name": "envoy",
+ "Ulimits": [
+ {
+ "HardLimit": 1024000,
+ "Name": "nofile",
+ "SoftLimit": 1024000
+ }
+ ],
+ "User": "1337"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Essential": true,
+ "FirelensConfiguration": {
+ "Type": "fluentbit"
+ },
+ "Image": {
+ "Ref": "SsmParameterValueawsserviceawsforfluentbitlatestC96584B6F00A464EAD1953AFF4B05118Parameter"
+ },
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "greetingtaskdefinitionfirelensLogGroupD7A398A7"
+ },
+ "awslogs-stream-prefix": "firelens",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 50,
+ "Name": "firelens",
+ "User": "0:1338"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "AWS_REGION",
+ "Value": {
+ "Ref": "AWS::Region"
+ }
+ }
+ ],
+ "Essential": true,
+ "HealthCheck": {
+ "Command": [
+ "CMD-SHELL",
+ "curl -s http://localhost:2000"
+ ],
+ "Interval": 5,
+ "Retries": 3,
+ "StartPeriod": 10,
+ "Timeout": 2
+ },
+ "Image": "amazon/aws-xray-daemon:latest",
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "greetingtaskdefinitionxrayLogGroupD25C072D"
+ },
+ "awslogs-stream-prefix": "xray",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 256,
+ "Name": "xray",
+ "User": "1337"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "CW_CONFIG_CONTENT",
+ "Value": "{\"logs\":{\"metrics_collected\":{\"emf\":{}}},\"metrics\":{\"metrics_collected\":{\"statsd\":{}}}}"
+ }
+ ],
+ "Essential": true,
+ "Image": "amazon/cloudwatch-agent:latest",
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "greetingtaskdefinitioncloudwatchagentLogGroupCEF72742"
+ },
+ "awslogs-stream-prefix": "cloudwatch-agent",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 50,
+ "Name": "cloudwatch-agent",
+ "User": "0:1338"
+ }
+ ],
+ "Cpu": "1024",
+ "ExecutionRoleArn": {
+ "Fn::GetAtt": [
+ "greetingtaskdefinitionExecutionRole9E3A7CF3",
+ "Arn"
+ ]
+ },
+ "Family": "awsecsinteggreetingtaskdefinitionA6E8A57B",
+ "Memory": "2048",
+ "NetworkMode": "awsvpc",
+ "ProxyConfiguration": {
+ "ContainerName": "envoy",
+ "ProxyConfigurationProperties": [
+ {
+ "Name": "AppPorts",
+ "Value": "80"
+ },
+ {
+ "Name": "ProxyEgressPort",
+ "Value": "15001"
+ },
+ {
+ "Name": "ProxyIngressPort",
+ "Value": "15000"
+ },
+ {
+ "Name": "IgnoredUID",
+ "Value": "1337"
+ },
+ {
+ "Name": "IgnoredGID",
+ "Value": "1338"
+ },
+ {
+ "Name": "EgressIgnoredIPs",
+ "Value": "169.254.170.2,169.254.169.254"
+ }
+ ],
+ "Type": "APPMESH"
+ },
+ "RequiresCompatibilities": [
+ "EC2",
+ "FARGATE"
+ ],
+ "TaskRoleArn": {
+ "Fn::GetAtt": [
+ "greetingtaskdefinitionTaskRole9179DA4A",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "greetingtaskdefinitionenvoyLogGroup6556AC35": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "greetingtaskdefinitionExecutionRole9E3A7CF3": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "ecs-tasks.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "greetingtaskdefinitionExecutionRoleDefaultPolicy31B93022": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "ecr:BatchCheckLayerAvailability",
+ "ecr:BatchGetImage",
+ "ecr:GetDownloadUrlForLayer"
+ ],
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":ecr:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Fn::FindInMap": [
+ "greetingenvoyimageaccountmapping",
+ {
+ "Ref": "AWS::Region"
+ },
+ "ecrRepo"
+ ]
+ },
+ ":repository/aws-appmesh-envoy"
+ ]
+ ]
+ }
+ },
+ {
+ "Action": [
+ "ecr:BatchCheckLayerAvailability",
+ "ecr:BatchGetImage",
+ "ecr:GetAuthorizationToken",
+ "ecr:GetDownloadUrlForLayer"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ },
+ {
+ "Action": [
+ "logs:CreateLogStream",
+ "logs:PutLogEvents"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "greetingtaskdefinitioncloudwatchagentLogGroupCEF72742",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "greetingtaskdefinitionenvoyLogGroup6556AC35",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "greetingtaskdefinitionfirelensLogGroupD7A398A7",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "greetingtaskdefinitionxrayLogGroupD25C072D",
+ "Arn"
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "greetingtaskdefinitionExecutionRoleDefaultPolicy31B93022",
+ "Roles": [
+ {
+ "Ref": "greetingtaskdefinitionExecutionRole9E3A7CF3"
+ }
+ ]
+ }
+ },
+ "greetingtaskdefinitionfirelensLogGroupD7A398A7": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "greetingtaskdefinitionxrayLogGroupD25C072D": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "greetingtaskdefinitioncloudwatchagentLogGroupCEF72742": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "greetingenvoytoappmesh97051B23": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "appmesh:StreamAggregatedResources",
+ "Effect": "Allow",
+ "Resource": {
+ "Ref": "mymeshEA67EDEF"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "greetingenvoytoappmesh97051B23",
+ "Roles": [
+ {
+ "Ref": "greetingtaskdefinitionTaskRole9179DA4A"
+ }
+ ]
+ }
+ },
+ "greetingpublishmetricsF17124EF": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "cloudwatch:PutMetricData",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "greetingpublishmetricsF17124EF",
+ "Roles": [
+ {
+ "Ref": "greetingtaskdefinitionTaskRole9179DA4A"
+ }
+ ]
+ }
+ },
+ "greetingserviceService8DA58640": {
+ "Type": "AWS::ECS::Service",
+ "Properties": {
+ "Cluster": {
+ "Ref": "productionenvironmentclusterC6599D2D"
+ },
+ "DeploymentConfiguration": {
+ "MaximumPercent": 150,
+ "MinimumHealthyPercent": 100
+ },
+ "DesiredCount": 2,
+ "EnableECSManagedTags": false,
+ "LaunchType": "FARGATE",
+ "NetworkConfiguration": {
+ "AwsvpcConfiguration": {
+ "AssignPublicIp": "DISABLED",
+ "SecurityGroups": [
+ {
+ "Fn::GetAtt": [
+ "greetingserviceSecurityGroupE9BE665B",
+ "GroupId"
+ ]
+ }
+ ],
+ "Subnets": [
+ {
+ "Ref": "productionenvironmentvpcPrivateSubnet1Subnet53F632E6"
+ },
+ {
+ "Ref": "productionenvironmentvpcPrivateSubnet2Subnet756FB93C"
+ }
+ ]
+ }
+ },
+ "ServiceRegistries": [
+ {
+ "RegistryArn": {
+ "Fn::GetAtt": [
+ "greetingserviceCloudmapService0A2D7385",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "TaskDefinition": {
+ "Ref": "greetingtaskdefinition31690093"
+ }
+ }
+ },
+ "greetingserviceCloudmapService0A2D7385": {
+ "Type": "AWS::ServiceDiscovery::Service",
+ "Properties": {
+ "DnsConfig": {
+ "DnsRecords": [
+ {
+ "TTL": 10,
+ "Type": "A"
+ }
+ ],
+ "NamespaceId": {
+ "Fn::GetAtt": [
+ "productionenvironmentclusterDefaultServiceDiscoveryNamespaceBE74D64D",
+ "Id"
+ ]
+ },
+ "RoutingPolicy": "MULTIVALUE"
+ },
+ "HealthCheckCustomConfig": {
+ "FailureThreshold": 2
+ },
+ "Name": "greeting",
+ "NamespaceId": {
+ "Fn::GetAtt": [
+ "productionenvironmentclusterDefaultServiceDiscoveryNamespaceBE74D64D",
+ "Id"
+ ]
+ }
+ }
+ },
+ "greetingserviceSecurityGroupE9BE665B": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Properties": {
+ "GroupDescription": "aws-ecs-integ/greeting-service/SecurityGroup",
+ "SecurityGroupEgress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow all outbound traffic by default",
+ "IpProtocol": "-1"
+ }
+ ],
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ }
+ }
+ },
+ "greetingserviceSecurityGroupfromawsecsinteggreeterserviceSecurityGroup055DC23B807B9C4357": {
+ "Type": "AWS::EC2::SecurityGroupIngress",
+ "Properties": {
+ "IpProtocol": "tcp",
+ "Description": "Accept inbound traffic from greeter",
+ "FromPort": 80,
+ "GroupId": {
+ "Fn::GetAtt": [
+ "greetingserviceSecurityGroupE9BE665B",
+ "GroupId"
+ ]
+ },
+ "SourceSecurityGroupId": {
+ "Fn::GetAtt": [
+ "greeterserviceSecurityGroupDB4AC3A9",
+ "GroupId"
+ ]
+ },
+ "ToPort": 80
+ }
+ },
+ "greetingserviceTaskCountTargetA036048C": {
+ "Type": "AWS::ApplicationAutoScaling::ScalableTarget",
+ "Properties": {
+ "MaxCapacity": 8,
+ "MinCapacity": 2,
+ "ResourceId": {
+ "Fn::Join": [
+ "",
+ [
+ "service/",
+ {
+ "Ref": "productionenvironmentclusterC6599D2D"
+ },
+ "/",
+ {
+ "Fn::GetAtt": [
+ "greetingserviceService8DA58640",
+ "Name"
+ ]
+ }
+ ]
+ ]
+ },
+ "RoleARN": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"
+ ]
+ ]
+ },
+ "ScalableDimension": "ecs:service:DesiredCount",
+ "ServiceNamespace": "ecs"
+ }
+ },
+ "greetingserviceTaskCountTargetgreetingtargetcpuutilization50FEAF6434": {
+ "Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
+ "Properties": {
+ "PolicyName": "awsecsinteggreetingserviceTaskCountTargetgreetingtargetcpuutilization504C76B1F4",
+ "PolicyType": "TargetTrackingScaling",
+ "ScalingTargetId": {
+ "Ref": "greetingserviceTaskCountTargetA036048C"
+ },
+ "TargetTrackingScalingPolicyConfiguration": {
+ "PredefinedMetricSpecification": {
+ "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
+ },
+ "ScaleInCooldown": 60,
+ "ScaleOutCooldown": 60,
+ "TargetValue": 50
+ }
+ }
+ },
+ "greetingvirtualnodeC4A2C517": {
+ "Type": "AWS::AppMesh::VirtualNode",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Listeners": [
+ {
+ "PortMapping": {
+ "Port": 80,
+ "Protocol": "http"
+ }
+ }
+ ],
+ "ServiceDiscovery": {
+ "AWSCloudMap": {
+ "NamespaceName": "production",
+ "ServiceName": {
+ "Fn::GetAtt": [
+ "greetingserviceCloudmapService0A2D7385",
+ "Name"
+ ]
+ }
+ }
+ }
+ },
+ "VirtualNodeName": "greeting"
+ }
+ },
+ "greetingvirtualrouter0F898D1A": {
+ "Type": "AWS::AppMesh::VirtualRouter",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Listeners": [
+ {
+ "PortMapping": {
+ "Port": 80,
+ "Protocol": "http"
+ }
+ }
+ ]
+ },
+ "VirtualRouterName": "greeting"
+ }
+ },
+ "greetingvirtualroutergreetingroute46305F50": {
+ "Type": "AWS::AppMesh::Route",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "HttpRoute": {
+ "Action": {
+ "WeightedTargets": [
+ {
+ "VirtualNode": {
+ "Fn::GetAtt": [
+ "greetingvirtualnodeC4A2C517",
+ "VirtualNodeName"
+ ]
+ },
+ "Weight": 1
+ }
+ ]
+ },
+ "Match": {
+ "Prefix": "/"
+ }
+ }
+ },
+ "VirtualRouterName": {
+ "Fn::GetAtt": [
+ "greetingvirtualrouter0F898D1A",
+ "VirtualRouterName"
+ ]
+ },
+ "RouteName": "greeting-route"
+ }
+ },
+ "greetingvirtualservice60AD3AD9": {
+ "Type": "AWS::AppMesh::VirtualService",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Provider": {
+ "VirtualRouter": {
+ "VirtualRouterName": {
+ "Fn::GetAtt": [
+ "greetingvirtualrouter0F898D1A",
+ "VirtualRouterName"
+ ]
+ }
+ }
+ }
+ },
+ "VirtualServiceName": "greeting.production"
+ }
+ },
+ "greeterlogsCCD2F8B2": {
+ "Type": "AWS::Logs::LogGroup",
+ "Properties": {
+ "LogGroupName": "greeter-logs",
+ "RetentionInDays": 7
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "greeterloadbalancer85256741": {
+ "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
+ "Properties": {
+ "LoadBalancerAttributes": [
+ {
+ "Key": "deletion_protection.enabled",
+ "Value": "false"
+ }
+ ],
+ "Scheme": "internet-facing",
+ "SecurityGroups": [
+ {
+ "Fn::GetAtt": [
+ "greeterloadbalancerSecurityGroupEE1B20F3",
+ "GroupId"
+ ]
+ }
+ ],
+ "Subnets": [
+ {
+ "Ref": "productionenvironmentvpcPublicSubnet1Subnet8D92C089"
+ },
+ {
+ "Ref": "productionenvironmentvpcPublicSubnet2Subnet298E6C31"
+ }
+ ],
+ "Type": "application"
+ },
+ "DependsOn": [
+ "productionenvironmentvpcPublicSubnet1DefaultRoute524C894D",
+ "productionenvironmentvpcPublicSubnet2DefaultRoute92CD697D"
+ ]
+ },
+ "greeterloadbalancerSecurityGroupEE1B20F3": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Properties": {
+ "GroupDescription": "Automatically created Security Group for ELB awsecsinteggreeterloadbalancer147D1D5C",
+ "SecurityGroupIngress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow from anyone on port 80",
+ "FromPort": 80,
+ "IpProtocol": "tcp",
+ "ToPort": 80
+ }
+ ],
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ }
+ }
+ },
+ "greeterloadbalancerSecurityGrouptoawsecsinteggreeterserviceSecurityGroup055DC23B803EEF3320": {
+ "Type": "AWS::EC2::SecurityGroupEgress",
+ "Properties": {
+ "GroupId": {
+ "Fn::GetAtt": [
+ "greeterloadbalancerSecurityGroupEE1B20F3",
+ "GroupId"
+ ]
+ },
+ "IpProtocol": "tcp",
+ "Description": "Load balancer to target",
+ "DestinationSecurityGroupId": {
+ "Fn::GetAtt": [
+ "greeterserviceSecurityGroupDB4AC3A9",
+ "GroupId"
+ ]
+ },
+ "FromPort": 80,
+ "ToPort": 80
+ }
+ },
+ "greeterloadbalancergreeterlistener952E028B": {
+ "Type": "AWS::ElasticLoadBalancingV2::Listener",
+ "Properties": {
+ "DefaultActions": [
+ {
+ "TargetGroupArn": {
+ "Ref": "greeterloadbalancergreeterlistenergreeterGroupFFBFF0C2"
+ },
+ "Type": "forward"
+ }
+ ],
+ "LoadBalancerArn": {
+ "Ref": "greeterloadbalancer85256741"
+ },
+ "Port": 80,
+ "Protocol": "HTTP"
+ }
+ },
+ "greeterloadbalancergreeterlistenergreeterGroupFFBFF0C2": {
+ "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
+ "Properties": {
+ "Port": 80,
+ "Protocol": "HTTP",
+ "TargetGroupAttributes": [
+ {
+ "Key": "deregistration_delay.timeout_seconds",
+ "Value": "10"
+ },
+ {
+ "Key": "stickiness.enabled",
+ "Value": "false"
+ }
+ ],
+ "TargetType": "ip",
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ }
+ }
+ },
+ "greetertaskdefinitionTaskRole2A098ACC": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "ecs-tasks.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/AWSXRayDaemonWriteAccess"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "greetertaskdefinitionTaskRoleDefaultPolicyD0F53B1C": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "logs:CreateLogGroup",
+ "logs:CreateLogStream",
+ "logs:DescribeLogStreams",
+ "logs:PutLogEvents"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "greetertaskdefinitionTaskRoleDefaultPolicyD0F53B1C",
+ "Roles": [
+ {
+ "Ref": "greetertaskdefinitionTaskRole2A098ACC"
+ }
+ ]
+ }
+ },
+ "greetertaskdefinitionE956EEA2": {
+ "Type": "AWS::ECS::TaskDefinition",
+ "Properties": {
+ "ContainerDefinitions": [
+ {
+ "Cpu": 1024,
+ "DependsOn": [
+ {
+ "Condition": "START",
+ "ContainerName": "firelens"
+ },
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ },
+ {
+ "Condition": "START",
+ "ContainerName": "cloudwatch-agent"
+ },
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "xray"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "PORT",
+ "Value": "80"
+ },
+ {
+ "Name": "GREETING_URL",
+ "Value": "http://greeting.production"
+ },
+ {
+ "Name": "NAME_URL",
+ "Value": "http://name.production"
+ }
+ ],
+ "Essential": true,
+ "Image": "nathanpeck/greeter",
+ "LogConfiguration": {
+ "LogDriver": "awsfirelens",
+ "Options": {
+ "Name": "cloudwatch",
+ "region": {
+ "Ref": "AWS::Region"
+ },
+ "log_group_name": {
+ "Ref": "greeterlogsCCD2F8B2"
+ },
+ "log_stream_prefix": "greeter/"
+ }
+ },
+ "Memory": 2048,
+ "Name": "app",
+ "PortMappings": [
+ {
+ "ContainerPort": 80,
+ "Protocol": "tcp"
+ }
+ ],
+ "Ulimits": [
+ {
+ "HardLimit": 1024000,
+ "Name": "nofile",
+ "SoftLimit": 1024000
+ }
+ ]
+ },
+ {
+ "Environment": [
+ {
+ "Name": "APPMESH_VIRTUAL_NODE_NAME",
+ "Value": {
+ "Fn::Join": [
+ "",
+ [
+ "mesh/",
+ {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "/virtualNode/greeter"
+ ]
+ ]
+ }
+ },
+ {
+ "Name": "AWS_REGION",
+ "Value": {
+ "Ref": "AWS::Region"
+ }
+ },
+ {
+ "Name": "ENABLE_ENVOY_STATS_TAGS",
+ "Value": "1"
+ },
+ {
+ "Name": "ENABLE_ENVOY_DOG_STATSD",
+ "Value": "1"
+ }
+ ],
+ "Essential": true,
+ "HealthCheck": {
+ "Command": [
+ "CMD-SHELL",
+ "curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
+ ],
+ "Interval": 5,
+ "Retries": 3,
+ "StartPeriod": 10,
+ "Timeout": 2
+ },
+ "Image": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::FindInMap": [
+ "greeterenvoyimageaccountmapping",
+ {
+ "Ref": "AWS::Region"
+ },
+ "ecrRepo"
+ ]
+ },
+ ".dkr.ecr.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".",
+ {
+ "Ref": "AWS::URLSuffix"
+ },
+ "/aws-appmesh-envoy:v1.15.1.0-prod"
+ ]
+ ]
+ },
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "greetertaskdefinitionenvoyLogGroup6E10B93E"
+ },
+ "awslogs-stream-prefix": "envoy",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 128,
+ "Name": "envoy",
+ "Ulimits": [
+ {
+ "HardLimit": 1024000,
+ "Name": "nofile",
+ "SoftLimit": 1024000
+ }
+ ],
+ "User": "1337"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Essential": true,
+ "FirelensConfiguration": {
+ "Type": "fluentbit"
+ },
+ "Image": {
+ "Ref": "SsmParameterValueawsserviceawsforfluentbitlatestC96584B6F00A464EAD1953AFF4B05118Parameter"
+ },
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "greetertaskdefinitionfirelensLogGroupD5BAAC35"
+ },
+ "awslogs-stream-prefix": "firelens",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 50,
+ "Name": "firelens",
+ "User": "0:1338"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "AWS_REGION",
+ "Value": {
+ "Ref": "AWS::Region"
+ }
+ }
+ ],
+ "Essential": true,
+ "HealthCheck": {
+ "Command": [
+ "CMD-SHELL",
+ "curl -s http://localhost:2000"
+ ],
+ "Interval": 5,
+ "Retries": 3,
+ "StartPeriod": 10,
+ "Timeout": 2
+ },
+ "Image": "amazon/aws-xray-daemon:latest",
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "greetertaskdefinitionxrayLogGroupBC1558B6"
+ },
+ "awslogs-stream-prefix": "xray",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 256,
+ "Name": "xray",
+ "User": "1337"
+ },
+ {
+ "DependsOn": [
+ {
+ "Condition": "HEALTHY",
+ "ContainerName": "envoy"
+ }
+ ],
+ "Environment": [
+ {
+ "Name": "CW_CONFIG_CONTENT",
+ "Value": "{\"logs\":{\"metrics_collected\":{\"emf\":{}}},\"metrics\":{\"metrics_collected\":{\"statsd\":{}}}}"
+ }
+ ],
+ "Essential": true,
+ "Image": "amazon/cloudwatch-agent:latest",
+ "LogConfiguration": {
+ "LogDriver": "awslogs",
+ "Options": {
+ "awslogs-group": {
+ "Ref": "greetertaskdefinitioncloudwatchagentLogGroupE7EAF327"
+ },
+ "awslogs-stream-prefix": "cloudwatch-agent",
+ "awslogs-region": {
+ "Ref": "AWS::Region"
+ }
+ }
+ },
+ "MemoryReservation": 50,
+ "Name": "cloudwatch-agent",
+ "User": "0:1338"
+ }
+ ],
+ "Cpu": "1024",
+ "ExecutionRoleArn": {
+ "Fn::GetAtt": [
+ "greetertaskdefinitionExecutionRoleAED0EC79",
+ "Arn"
+ ]
+ },
+ "Family": "awsecsinteggreetertaskdefinitionB95239FB",
+ "Memory": "2048",
+ "NetworkMode": "awsvpc",
+ "ProxyConfiguration": {
+ "ContainerName": "envoy",
+ "ProxyConfigurationProperties": [
+ {
+ "Name": "AppPorts",
+ "Value": "80"
+ },
+ {
+ "Name": "ProxyEgressPort",
+ "Value": "15001"
+ },
+ {
+ "Name": "ProxyIngressPort",
+ "Value": "15000"
+ },
+ {
+ "Name": "IgnoredUID",
+ "Value": "1337"
+ },
+ {
+ "Name": "IgnoredGID",
+ "Value": "1338"
+ },
+ {
+ "Name": "EgressIgnoredIPs",
+ "Value": "169.254.170.2,169.254.169.254"
+ }
+ ],
+ "Type": "APPMESH"
+ },
+ "RequiresCompatibilities": [
+ "EC2",
+ "FARGATE"
+ ],
+ "TaskRoleArn": {
+ "Fn::GetAtt": [
+ "greetertaskdefinitionTaskRole2A098ACC",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "greetertaskdefinitionenvoyLogGroup6E10B93E": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "greetertaskdefinitionExecutionRoleAED0EC79": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "ecs-tasks.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "greetertaskdefinitionExecutionRoleDefaultPolicy0D8E9106": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "ecr:BatchCheckLayerAvailability",
+ "ecr:BatchGetImage",
+ "ecr:GetDownloadUrlForLayer"
+ ],
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":ecr:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Fn::FindInMap": [
+ "greeterenvoyimageaccountmapping",
+ {
+ "Ref": "AWS::Region"
+ },
+ "ecrRepo"
+ ]
+ },
+ ":repository/aws-appmesh-envoy"
+ ]
+ ]
+ }
+ },
+ {
+ "Action": [
+ "ecr:BatchCheckLayerAvailability",
+ "ecr:BatchGetImage",
+ "ecr:GetAuthorizationToken",
+ "ecr:GetDownloadUrlForLayer"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ },
+ {
+ "Action": [
+ "logs:CreateLogStream",
+ "logs:PutLogEvents"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "greetertaskdefinitioncloudwatchagentLogGroupE7EAF327",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "greetertaskdefinitionenvoyLogGroup6E10B93E",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "greetertaskdefinitionfirelensLogGroupD5BAAC35",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "greetertaskdefinitionxrayLogGroupBC1558B6",
+ "Arn"
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "greetertaskdefinitionExecutionRoleDefaultPolicy0D8E9106",
+ "Roles": [
+ {
+ "Ref": "greetertaskdefinitionExecutionRoleAED0EC79"
+ }
+ ]
+ }
+ },
+ "greetertaskdefinitionfirelensLogGroupD5BAAC35": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "greetertaskdefinitionxrayLogGroupBC1558B6": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "greetertaskdefinitioncloudwatchagentLogGroupE7EAF327": {
+ "Type": "AWS::Logs::LogGroup",
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "greeterenvoytoappmesh1A94938B": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "appmesh:StreamAggregatedResources",
+ "Effect": "Allow",
+ "Resource": {
+ "Ref": "mymeshEA67EDEF"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "greeterenvoytoappmesh1A94938B",
+ "Roles": [
+ {
+ "Ref": "greetertaskdefinitionTaskRole2A098ACC"
+ }
+ ]
+ }
+ },
+ "greeterpublishmetrics0CCA359A": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "cloudwatch:PutMetricData",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "greeterpublishmetrics0CCA359A",
+ "Roles": [
+ {
+ "Ref": "greetertaskdefinitionTaskRole2A098ACC"
+ }
+ ]
+ }
+ },
+ "greeterserviceService8EDD3244": {
+ "Type": "AWS::ECS::Service",
+ "Properties": {
+ "Cluster": {
+ "Ref": "productionenvironmentclusterC6599D2D"
+ },
+ "DeploymentConfiguration": {
+ "MaximumPercent": 150,
+ "MinimumHealthyPercent": 100
+ },
+ "DesiredCount": 2,
+ "EnableECSManagedTags": false,
+ "HealthCheckGracePeriodSeconds": 60,
+ "LaunchType": "FARGATE",
+ "LoadBalancers": [
+ {
+ "ContainerName": "app",
+ "ContainerPort": 80,
+ "TargetGroupArn": {
+ "Ref": "greeterloadbalancergreeterlistenergreeterGroupFFBFF0C2"
+ }
+ }
+ ],
+ "NetworkConfiguration": {
+ "AwsvpcConfiguration": {
+ "AssignPublicIp": "DISABLED",
+ "SecurityGroups": [
+ {
+ "Fn::GetAtt": [
+ "greeterserviceSecurityGroupDB4AC3A9",
+ "GroupId"
+ ]
+ }
+ ],
+ "Subnets": [
+ {
+ "Ref": "productionenvironmentvpcPrivateSubnet1Subnet53F632E6"
+ },
+ {
+ "Ref": "productionenvironmentvpcPrivateSubnet2Subnet756FB93C"
+ }
+ ]
+ }
+ },
+ "ServiceRegistries": [
+ {
+ "RegistryArn": {
+ "Fn::GetAtt": [
+ "greeterserviceCloudmapServiceEE292978",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "TaskDefinition": {
+ "Ref": "greetertaskdefinitionE956EEA2"
+ }
+ },
+ "DependsOn": [
+ "greeterloadbalancergreeterlistenergreeterGroupFFBFF0C2",
+ "greeterloadbalancergreeterlistener952E028B"
+ ]
+ },
+ "greeterserviceCloudmapServiceEE292978": {
+ "Type": "AWS::ServiceDiscovery::Service",
+ "Properties": {
+ "DnsConfig": {
+ "DnsRecords": [
+ {
+ "TTL": 10,
+ "Type": "A"
+ }
+ ],
+ "NamespaceId": {
+ "Fn::GetAtt": [
+ "productionenvironmentclusterDefaultServiceDiscoveryNamespaceBE74D64D",
+ "Id"
+ ]
+ },
+ "RoutingPolicy": "MULTIVALUE"
+ },
+ "HealthCheckCustomConfig": {
+ "FailureThreshold": 2
+ },
+ "Name": "greeter",
+ "NamespaceId": {
+ "Fn::GetAtt": [
+ "productionenvironmentclusterDefaultServiceDiscoveryNamespaceBE74D64D",
+ "Id"
+ ]
+ }
+ }
+ },
+ "greeterserviceSecurityGroupDB4AC3A9": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Properties": {
+ "GroupDescription": "aws-ecs-integ/greeter-service/SecurityGroup",
+ "SecurityGroupEgress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow all outbound traffic by default",
+ "IpProtocol": "-1"
+ }
+ ],
+ "VpcId": {
+ "Ref": "productionenvironmentvpcAEB47DF7"
+ }
+ }
+ },
+ "greeterserviceSecurityGroupfromawsecsinteggreeterloadbalancerSecurityGroupF791FA838037FDF8F5": {
+ "Type": "AWS::EC2::SecurityGroupIngress",
+ "Properties": {
+ "IpProtocol": "tcp",
+ "Description": "Load balancer to target",
+ "FromPort": 80,
+ "GroupId": {
+ "Fn::GetAtt": [
+ "greeterserviceSecurityGroupDB4AC3A9",
+ "GroupId"
+ ]
+ },
+ "SourceSecurityGroupId": {
+ "Fn::GetAtt": [
+ "greeterloadbalancerSecurityGroupEE1B20F3",
+ "GroupId"
+ ]
+ },
+ "ToPort": 80
+ }
+ },
+ "greeterserviceTaskCountTargetAB95B3D0": {
+ "Type": "AWS::ApplicationAutoScaling::ScalableTarget",
+ "Properties": {
+ "MaxCapacity": 8,
+ "MinCapacity": 2,
+ "ResourceId": {
+ "Fn::Join": [
+ "",
+ [
+ "service/",
+ {
+ "Ref": "productionenvironmentclusterC6599D2D"
+ },
+ "/",
+ {
+ "Fn::GetAtt": [
+ "greeterserviceService8EDD3244",
+ "Name"
+ ]
+ }
+ ]
+ ]
+ },
+ "RoleARN": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"
+ ]
+ ]
+ },
+ "ScalableDimension": "ecs:service:DesiredCount",
+ "ServiceNamespace": "ecs"
+ }
+ },
+ "greeterserviceTaskCountTargetgreetertargetcpuutilization50299508D1": {
+ "Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
+ "Properties": {
+ "PolicyName": "awsecsinteggreeterserviceTaskCountTargetgreetertargetcpuutilization50A75D0C0D",
+ "PolicyType": "TargetTrackingScaling",
+ "ScalingTargetId": {
+ "Ref": "greeterserviceTaskCountTargetAB95B3D0"
+ },
+ "TargetTrackingScalingPolicyConfiguration": {
+ "PredefinedMetricSpecification": {
+ "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
+ },
+ "ScaleInCooldown": 60,
+ "ScaleOutCooldown": 60,
+ "TargetValue": 50
+ }
+ }
+ },
+ "greetervirtualnode21EA7CC9": {
+ "Type": "AWS::AppMesh::VirtualNode",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Backends": [
+ {
+ "VirtualService": {
+ "VirtualServiceName": "name.production"
+ }
+ },
+ {
+ "VirtualService": {
+ "VirtualServiceName": "greeting.production"
+ }
+ }
+ ],
+ "Listeners": [
+ {
+ "PortMapping": {
+ "Port": 80,
+ "Protocol": "http"
+ }
+ }
+ ],
+ "ServiceDiscovery": {
+ "AWSCloudMap": {
+ "NamespaceName": "production",
+ "ServiceName": {
+ "Fn::GetAtt": [
+ "greeterserviceCloudmapServiceEE292978",
+ "Name"
+ ]
+ }
+ }
+ }
+ },
+ "VirtualNodeName": "greeter"
+ }
+ },
+ "greetervirtualrouter193840BB": {
+ "Type": "AWS::AppMesh::VirtualRouter",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Listeners": [
+ {
+ "PortMapping": {
+ "Port": 80,
+ "Protocol": "http"
+ }
+ }
+ ]
+ },
+ "VirtualRouterName": "greeter"
+ }
+ },
+ "greetervirtualroutergreeterroute3EC6ACB0": {
+ "Type": "AWS::AppMesh::Route",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "HttpRoute": {
+ "Action": {
+ "WeightedTargets": [
+ {
+ "VirtualNode": {
+ "Fn::GetAtt": [
+ "greetervirtualnode21EA7CC9",
+ "VirtualNodeName"
+ ]
+ },
+ "Weight": 1
+ }
+ ]
+ },
+ "Match": {
+ "Prefix": "/"
+ }
+ }
+ },
+ "VirtualRouterName": {
+ "Fn::GetAtt": [
+ "greetervirtualrouter193840BB",
+ "VirtualRouterName"
+ ]
+ },
+ "RouteName": "greeter-route"
+ }
+ },
+ "greetervirtualservice6559950C": {
+ "Type": "AWS::AppMesh::VirtualService",
+ "Properties": {
+ "MeshName": {
+ "Fn::GetAtt": [
+ "mymeshEA67EDEF",
+ "MeshName"
+ ]
+ },
+ "Spec": {
+ "Provider": {
+ "VirtualRouter": {
+ "VirtualRouterName": {
+ "Fn::GetAtt": [
+ "greetervirtualrouter193840BB",
+ "VirtualRouterName"
+ ]
+ }
+ }
+ }
+ },
+ "VirtualServiceName": "greeter.production"
+ }
+ }
+ },
+ "Mappings": {
+ "nameenvoyimageaccountmapping": {
+ "ap-northeast-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-northeast-2": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-south-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-southeast-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-southeast-2": {
+ "ecrRepo": "840364872350"
+ },
+ "ca-central-1": {
+ "ecrRepo": "840364872350"
+ },
+ "cn-north-1": {
+ "ecrRepo": "919366029133"
+ },
+ "cn-northwest-1": {
+ "ecrRepo": "919830735681"
+ },
+ "eu-central-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-north-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-south-1": {
+ "ecrRepo": "422531588944"
+ },
+ "eu-west-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-west-2": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-west-3": {
+ "ecrRepo": "840364872350"
+ },
+ "sa-east-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-east-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-east-2": {
+ "ecrRepo": "840364872350"
+ },
+ "us-west-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-west-2": {
+ "ecrRepo": "840364872350"
+ },
+ "me-south-1": {
+ "ecrRepo": "772975370895"
+ },
+ "ap-east-1": {
+ "ecrRepo": "856666278305"
+ },
+ "af-south-1": {
+ "ecrRepo": "924023996002"
+ }
+ },
+ "greetingenvoyimageaccountmapping": {
+ "ap-northeast-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-northeast-2": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-south-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-southeast-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-southeast-2": {
+ "ecrRepo": "840364872350"
+ },
+ "ca-central-1": {
+ "ecrRepo": "840364872350"
+ },
+ "cn-north-1": {
+ "ecrRepo": "919366029133"
+ },
+ "cn-northwest-1": {
+ "ecrRepo": "919830735681"
+ },
+ "eu-central-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-north-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-south-1": {
+ "ecrRepo": "422531588944"
+ },
+ "eu-west-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-west-2": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-west-3": {
+ "ecrRepo": "840364872350"
+ },
+ "sa-east-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-east-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-east-2": {
+ "ecrRepo": "840364872350"
+ },
+ "us-west-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-west-2": {
+ "ecrRepo": "840364872350"
+ },
+ "me-south-1": {
+ "ecrRepo": "772975370895"
+ },
+ "ap-east-1": {
+ "ecrRepo": "856666278305"
+ },
+ "af-south-1": {
+ "ecrRepo": "924023996002"
+ }
+ },
+ "greeterenvoyimageaccountmapping": {
+ "ap-northeast-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-northeast-2": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-south-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-southeast-1": {
+ "ecrRepo": "840364872350"
+ },
+ "ap-southeast-2": {
+ "ecrRepo": "840364872350"
+ },
+ "ca-central-1": {
+ "ecrRepo": "840364872350"
+ },
+ "cn-north-1": {
+ "ecrRepo": "919366029133"
+ },
+ "cn-northwest-1": {
+ "ecrRepo": "919830735681"
+ },
+ "eu-central-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-north-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-south-1": {
+ "ecrRepo": "422531588944"
+ },
+ "eu-west-1": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-west-2": {
+ "ecrRepo": "840364872350"
+ },
+ "eu-west-3": {
+ "ecrRepo": "840364872350"
+ },
+ "sa-east-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-east-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-east-2": {
+ "ecrRepo": "840364872350"
+ },
+ "us-west-1": {
+ "ecrRepo": "840364872350"
+ },
+ "us-west-2": {
+ "ecrRepo": "840364872350"
+ },
+ "me-south-1": {
+ "ecrRepo": "772975370895"
+ },
+ "ap-east-1": {
+ "ecrRepo": "856666278305"
+ },
+ "af-south-1": {
+ "ecrRepo": "924023996002"
+ }
+ }
+ },
+ "Parameters": {
+ "SsmParameterValueawsserviceawsforfluentbitlatestC96584B6F00A464EAD1953AFF4B05118Parameter": {
+ "Type": "AWS::SSM::Parameter::ValueHello from the integ test container
+ Hello from the integ test container
+ Hello from the integ test container
+ Hello from the integ test container
+ Hello from the integ test container
+ Hello from the integ test container
+ This is a sample file
+
+Hello, S3 bucket deployments!
+
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/asset.fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/rabir2v.gif b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/asset.fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/rabir2v.gif
new file mode 100644
index 0000000000000..e82b75cdb2187
Binary files /dev/null and b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/asset.fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/rabir2v.gif differ
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/cdk.out
new file mode 100644
index 0000000000000..90bef2e09ad39
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/cdk.out
@@ -0,0 +1 @@
+{"version":"17.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/integ.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/integ.json
new file mode 100644
index 0000000000000..c5974db95a5ff
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/integ.json
@@ -0,0 +1,14 @@
+{
+ "version": "18.0.0",
+ "testCases": {
+ "aws-s3-deployment/test/integ.bucket-deployment-cloudfront": {
+ "stacks": [
+ "test-bucket-deployments-1"
+ ],
+ "diffAssets": false,
+ "stackUpdateWorkflow": true
+ }
+ },
+ "synthContext": {},
+ "enableLookups": false
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/manifest.json
new file mode 100644
index 0000000000000..dd18b232b6944
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/manifest.json
@@ -0,0 +1,210 @@
+{
+ "version": "17.0.0",
+ "artifacts": {
+ "Tree": {
+ "type": "cdk:tree",
+ "properties": {
+ "file": "tree.json"
+ }
+ },
+ "test-bucket-deployments-1": {
+ "type": "aws:cloudformation:stack",
+ "environment": "aws://unknown-account/unknown-region",
+ "properties": {
+ "templateFile": "test-bucket-deployments-1.template.json",
+ "validateOnSynth": false
+ },
+ "metadata": {
+ "/test-bucket-deployments-1": [
+ {
+ "type": "aws:cdk:asset",
+ "data": {
+ "path": "asset.be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "id": "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "packaging": "zip",
+ "sourceHash": "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "s3BucketParameter": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232",
+ "s3KeyParameter": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE",
+ "artifactHashParameter": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824ArtifactHash76F8FCF2"
+ }
+ },
+ {
+ "type": "aws:cdk:asset",
+ "data": {
+ "path": "asset.01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476.zip",
+ "id": "01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476",
+ "packaging": "file",
+ "sourceHash": "01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476",
+ "s3BucketParameter": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4",
+ "s3KeyParameter": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0",
+ "artifactHashParameter": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476ArtifactHash0FB7E57C"
+ }
+ },
+ {
+ "type": "aws:cdk:asset",
+ "data": {
+ "path": "asset.f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "id": "f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "packaging": "zip",
+ "sourceHash": "f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "s3BucketParameter": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7",
+ "s3KeyParameter": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D",
+ "artifactHashParameter": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daArtifactHashD85D28D8"
+ }
+ },
+ {
+ "type": "aws:cdk:asset",
+ "data": {
+ "path": "asset.fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "id": "fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "packaging": "zip",
+ "sourceHash": "fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "s3BucketParameter": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A",
+ "s3KeyParameter": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C",
+ "artifactHashParameter": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eArtifactHash0E426313"
+ }
+ }
+ ],
+ "/test-bucket-deployments-1/Destination3/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination3E3DC043D"
+ }
+ ],
+ "/test-bucket-deployments-1/Destination3/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination3Policy685DA6C5"
+ }
+ ],
+ "/test-bucket-deployments-1/Destination3/AutoDeleteObjectsCustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination3AutoDeleteObjectsCustomResourceC26EC7B7"
+ }
+ ],
+ "/test-bucket-deployments-1/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092"
+ }
+ ],
+ "/test-bucket-deployments-1/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/S3Bucket": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/S3VersionKey": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/ArtifactHash": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824ArtifactHash76F8FCF2"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/S3Bucket": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/S3VersionKey": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/ArtifactHash": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476ArtifactHash0FB7E57C"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/S3Bucket": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/S3VersionKey": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/ArtifactHash": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daArtifactHashD85D28D8"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/S3Bucket": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/S3VersionKey": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ],
+ "/test-bucket-deployments-1/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/ArtifactHash": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eArtifactHash0E426313"
+ }
+ ],
+ "/test-bucket-deployments-1/Distribution/CFDistribution": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DistributionCFDistribution882A7313"
+ }
+ ],
+ "/test-bucket-deployments-1/DeployWithInvalidation/AwsCliLayer/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployWithInvalidationAwsCliLayerDEDD5787"
+ }
+ ],
+ "/test-bucket-deployments-1/DeployWithInvalidation/CustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployWithInvalidationCustomResourceE3FF7455"
+ }
+ ],
+ "/test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265"
+ }
+ ],
+ "/test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/DefaultPolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF"
+ }
+ ],
+ "/test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536"
+ }
+ ]
+ },
+ "displayName": "test-bucket-deployments-1"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/test-bucket-deployments-1.template.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/test-bucket-deployments-1.template.json
new file mode 100644
index 0000000000000..e1f6b0c7ee613
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/test-bucket-deployments-1.template.json
@@ -0,0 +1,581 @@
+{
+ "Resources": {
+ "Destination3E3DC043D": {
+ "Type": "AWS::S3::Bucket",
+ "Properties": {
+ "Tags": [
+ {
+ "Key": "aws-cdk:auto-delete-objects",
+ "Value": "true"
+ },
+ {
+ "Key": "aws-cdk:cr-owned:4685d093",
+ "Value": "true"
+ }
+ ]
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Destination3Policy685DA6C5": {
+ "Type": "AWS::S3::BucketPolicy",
+ "Properties": {
+ "Bucket": {
+ "Ref": "Destination3E3DC043D"
+ },
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ }
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "Destination3AutoDeleteObjectsCustomResourceC26EC7B7": {
+ "Type": "Custom::S3AutoDeleteObjects",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Destination3E3DC043D"
+ }
+ },
+ "DependsOn": [
+ "Destination3Policy685DA6C5"
+ ],
+ "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": {
+ "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Timeout": 900,
+ "MemorySize": 128,
+ "Handler": "__entrypoint__.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ },
+ "Runtime": "nodejs12.x",
+ "Description": {
+ "Fn::Join": [
+ "",
+ [
+ "Lambda function for auto-deleting objects in ",
+ {
+ "Ref": "Destination3E3DC043D"
+ },
+ " S3 bucket."
+ ]
+ ]
+ }
+ },
+ "DependsOn": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092"
+ ]
+ },
+ "DistributionCFDistribution882A7313": {
+ "Type": "AWS::CloudFront::Distribution",
+ "Properties": {
+ "DistributionConfig": {
+ "DefaultCacheBehavior": {
+ "AllowedMethods": [
+ "GET",
+ "HEAD"
+ ],
+ "CachedMethods": [
+ "GET",
+ "HEAD"
+ ],
+ "Compress": true,
+ "ForwardedValues": {
+ "Cookies": {
+ "Forward": "none"
+ },
+ "QueryString": false
+ },
+ "TargetOriginId": "origin1",
+ "ViewerProtocolPolicy": "redirect-to-https"
+ },
+ "DefaultRootObject": "index.html",
+ "Enabled": true,
+ "HttpVersion": "http2",
+ "IPV6Enabled": true,
+ "Origins": [
+ {
+ "ConnectionAttempts": 3,
+ "ConnectionTimeout": 10,
+ "DomainName": {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "RegionalDomainName"
+ ]
+ },
+ "Id": "origin1",
+ "S3OriginConfig": {}
+ }
+ ],
+ "PriceClass": "PriceClass_100",
+ "ViewerCertificate": {
+ "CloudFrontDefaultCertificate": true
+ }
+ }
+ }
+ },
+ "DeployWithInvalidationAwsCliLayerDEDD5787": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Properties": {
+ "Content": {
+ "S3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Description": "/opt/awscli/aws"
+ }
+ },
+ "DeployWithInvalidationCustomResourceE3FF7455": {
+ "Type": "Custom::CDKBucketDeployment",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536",
+ "Arn"
+ ]
+ },
+ "SourceBucketNames": [
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "SourceObjectKeys": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ "DestinationBucketName": {
+ "Ref": "Destination3E3DC043D"
+ },
+ "RetainOnDelete": false,
+ "Prune": true,
+ "DistributionId": {
+ "Ref": "DistributionCFDistribution882A7313"
+ },
+ "DistributionPaths": [
+ "/images/*.png"
+ ]
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Action": [
+ "s3:Abort*",
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Action": [
+ "cloudfront:CreateInvalidation",
+ "cloudfront:GetInvalidation"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF",
+ "Roles": [
+ {
+ "Ref": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265"
+ }
+ ]
+ }
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "S3Bucket": {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265",
+ "Arn"
+ ]
+ },
+ "Handler": "index.handler",
+ "Layers": [
+ {
+ "Ref": "DeployWithInvalidationAwsCliLayerDEDD5787"
+ }
+ ],
+ "Runtime": "python3.7",
+ "Timeout": 900
+ },
+ "DependsOn": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF",
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265"
+ ]
+ }
+ },
+ "Parameters": {
+ "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232": {
+ "Type": "String",
+ "Description": "S3 bucket for asset \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\""
+ },
+ "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE": {
+ "Type": "String",
+ "Description": "S3 key for asset version \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\""
+ },
+ "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824ArtifactHash76F8FCF2": {
+ "Type": "String",
+ "Description": "Artifact hash for asset \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\""
+ },
+ "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4": {
+ "Type": "String",
+ "Description": "S3 bucket for asset \"01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476\""
+ },
+ "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0": {
+ "Type": "String",
+ "Description": "S3 key for asset version \"01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476\""
+ },
+ "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476ArtifactHash0FB7E57C": {
+ "Type": "String",
+ "Description": "Artifact hash for asset \"01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476\""
+ },
+ "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7": {
+ "Type": "String",
+ "Description": "S3 bucket for asset \"f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da\""
+ },
+ "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D": {
+ "Type": "String",
+ "Description": "S3 key for asset version \"f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da\""
+ },
+ "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daArtifactHashD85D28D8": {
+ "Type": "String",
+ "Description": "Artifact hash for asset \"f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da\""
+ },
+ "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A": {
+ "Type": "String",
+ "Description": "S3 bucket for asset \"fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e\""
+ },
+ "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C": {
+ "Type": "String",
+ "Description": "S3 key for asset version \"fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e\""
+ },
+ "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eArtifactHash0E426313": {
+ "Type": "String",
+ "Description": "Artifact hash for asset \"fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e\""
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/tree.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/tree.json
new file mode 100644
index 0000000000000..19530e168bb9d
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-cloudfront.integ.snapshot/tree.json
@@ -0,0 +1,817 @@
+{
+ "version": "tree-0.1",
+ "tree": {
+ "id": "App",
+ "path": "",
+ "children": {
+ "Tree": {
+ "id": "Tree",
+ "path": "Tree",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "test-bucket-deployments-1": {
+ "id": "test-bucket-deployments-1",
+ "path": "test-bucket-deployments-1",
+ "children": {
+ "Destination3": {
+ "id": "Destination3",
+ "path": "test-bucket-deployments-1/Destination3",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-1/Destination3/Resource",
+ "attributes": {
+ "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:4685d093",
+ "value": "true"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "test-bucket-deployments-1/Destination3/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-1/Destination3/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy",
+ "aws:cdk:cloudformation:props": {
+ "bucket": {
+ "Ref": "Destination3E3DC043D"
+ },
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ }
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketPolicy",
+ "version": "0.0.0"
+ }
+ },
+ "AutoDeleteObjectsCustomResource": {
+ "id": "AutoDeleteObjectsCustomResource",
+ "path": "test-bucket-deployments-1/Destination3/AutoDeleteObjectsCustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-1/Destination3/AutoDeleteObjectsCustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "Custom::S3AutoDeleteObjectsCustomResourceProvider": {
+ "id": "Custom::S3AutoDeleteObjectsCustomResourceProvider",
+ "path": "test-bucket-deployments-1/Custom::S3AutoDeleteObjectsCustomResourceProvider",
+ "children": {
+ "Staging": {
+ "id": "Staging",
+ "path": "test-bucket-deployments-1/Custom::S3AutoDeleteObjectsCustomResourceProvider/Staging",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "Role": {
+ "id": "Role",
+ "path": "test-bucket-deployments-1/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ },
+ "Handler": {
+ "id": "Handler",
+ "path": "test-bucket-deployments-1/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResourceProvider",
+ "version": "0.0.0"
+ }
+ },
+ "AssetParameters": {
+ "id": "AssetParameters",
+ "path": "test-bucket-deployments-1/AssetParameters",
+ "children": {
+ "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824": {
+ "id": "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "path": "test-bucket-deployments-1/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "children": {
+ "S3Bucket": {
+ "id": "S3Bucket",
+ "path": "test-bucket-deployments-1/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/S3Bucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "S3VersionKey": {
+ "id": "S3VersionKey",
+ "path": "test-bucket-deployments-1/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/S3VersionKey",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "ArtifactHash": {
+ "id": "ArtifactHash",
+ "path": "test-bucket-deployments-1/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/ArtifactHash",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476": {
+ "id": "01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476",
+ "path": "test-bucket-deployments-1/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476",
+ "children": {
+ "S3Bucket": {
+ "id": "S3Bucket",
+ "path": "test-bucket-deployments-1/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/S3Bucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "S3VersionKey": {
+ "id": "S3VersionKey",
+ "path": "test-bucket-deployments-1/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/S3VersionKey",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "ArtifactHash": {
+ "id": "ArtifactHash",
+ "path": "test-bucket-deployments-1/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/ArtifactHash",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da": {
+ "id": "f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "path": "test-bucket-deployments-1/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "children": {
+ "S3Bucket": {
+ "id": "S3Bucket",
+ "path": "test-bucket-deployments-1/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/S3Bucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "S3VersionKey": {
+ "id": "S3VersionKey",
+ "path": "test-bucket-deployments-1/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/S3VersionKey",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "ArtifactHash": {
+ "id": "ArtifactHash",
+ "path": "test-bucket-deployments-1/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/ArtifactHash",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e": {
+ "id": "fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "path": "test-bucket-deployments-1/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "children": {
+ "S3Bucket": {
+ "id": "S3Bucket",
+ "path": "test-bucket-deployments-1/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/S3Bucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "S3VersionKey": {
+ "id": "S3VersionKey",
+ "path": "test-bucket-deployments-1/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/S3VersionKey",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "ArtifactHash": {
+ "id": "ArtifactHash",
+ "path": "test-bucket-deployments-1/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/ArtifactHash",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "Distribution": {
+ "id": "Distribution",
+ "path": "test-bucket-deployments-1/Distribution",
+ "children": {
+ "CFDistribution": {
+ "id": "CFDistribution",
+ "path": "test-bucket-deployments-1/Distribution/CFDistribution",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::CloudFront::Distribution",
+ "aws:cdk:cloudformation:props": {
+ "distributionConfig": {
+ "enabled": true,
+ "defaultRootObject": "index.html",
+ "httpVersion": "http2",
+ "priceClass": "PriceClass_100",
+ "ipv6Enabled": true,
+ "origins": [
+ {
+ "id": "origin1",
+ "domainName": {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "RegionalDomainName"
+ ]
+ },
+ "s3OriginConfig": {},
+ "connectionAttempts": 3,
+ "connectionTimeout": 10
+ }
+ ],
+ "defaultCacheBehavior": {
+ "allowedMethods": [
+ "GET",
+ "HEAD"
+ ],
+ "cachedMethods": [
+ "GET",
+ "HEAD"
+ ],
+ "compress": true,
+ "forwardedValues": {
+ "queryString": false,
+ "cookies": {
+ "forward": "none"
+ }
+ },
+ "targetOriginId": "origin1",
+ "viewerProtocolPolicy": "redirect-to-https"
+ },
+ "viewerCertificate": {
+ "cloudFrontDefaultCertificate": true
+ }
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-cloudfront.CfnDistribution",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-cloudfront.CloudFrontWebDistribution",
+ "version": "0.0.0"
+ }
+ },
+ "DeployWithInvalidation": {
+ "id": "DeployWithInvalidation",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation",
+ "children": {
+ "AwsCliLayer": {
+ "id": "AwsCliLayer",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/AwsCliLayer",
+ "children": {
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/AwsCliLayer/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/AwsCliLayer/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/AwsCliLayer/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/AwsCliLayer/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::LayerVersion",
+ "aws:cdk:cloudformation:props": {
+ "content": {
+ "s3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "description": "/opt/awscli/aws"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnLayerVersion",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/lambda-layer-awscli.AwsCliLayer",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourceHandler": {
+ "id": "CustomResourceHandler",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/CustomResourceHandler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Asset1": {
+ "id": "Asset1",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/Asset1",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/Asset1/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/Asset1/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResource": {
+ "id": "CustomResource",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/CustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-1/DeployWithInvalidation/CustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-deployment.BucketDeployment",
+ "version": "0.0.0"
+ }
+ },
+ "Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C": {
+ "id": "Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C",
+ "children": {
+ "ServiceRole": {
+ "id": "ServiceRole",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnRole",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultPolicy": {
+ "id": "DefaultPolicy",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/DefaultPolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/DefaultPolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Action": [
+ "s3:Abort*",
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Action": [
+ "cloudfront:CreateInvalidation",
+ "cloudfront:GetInvalidation"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF",
+ "roles": [
+ {
+ "Ref": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-1/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Function",
+ "aws:cdk:cloudformation:props": {
+ "code": {
+ "s3Bucket": {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "role": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265",
+ "Arn"
+ ]
+ },
+ "handler": "index.handler",
+ "layers": [
+ {
+ "Ref": "DeployWithInvalidationAwsCliLayerDEDD5787"
+ }
+ ],
+ "runtime": "python3.7",
+ "timeout": 900
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnFunction",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.Function",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Stack",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.App",
+ "version": "0.0.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-data.integ.snapshot/TestBucketDeploymentContent.template.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-data.integ.snapshot/TestBucketDeploymentContent.template.json
new file mode 100644
index 0000000000000..446bf4c05c8a3
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment-data.integ.snapshot/TestBucketDeploymentContent.template.json
@@ -0,0 +1,524 @@
+{
+ "Resources": {
+ "Bucket83908E77": {
+ "Type": "AWS::S3::Bucket",
+ "Properties": {
+ "Tags": [
+ {
+ "Key": "aws-cdk:cr-owned:deploy/here/:588fbb1f",
+ "Value": "true"
+ }
+ ]
+ },
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "DeployMeAwsCliLayer5F9219E9": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Properties": {
+ "Content": {
+ "S3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Description": "/opt/awscli/aws"
+ }
+ },
+ "DeployMeCustomResource4455EE35": {
+ "Type": "Custom::CDKBucketDeployment",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536",
+ "Arn"
+ ]
+ },
+ "SourceBucketNames": [
+ {
+ "Ref": "AssetParametersd09271be89b6cb0398f793b40c1531fd9b076aa92ba80b5e436914b1808fe18dS3BucketBC52CF96"
+ },
+ {
+ "Ref": "AssetParameters0f14dedeaf4386031c978375cbda0f65d7b52b29452cabb8873eb8f0d0fa936bS3BucketE46D7C76"
+ },
+ {
+ "Ref": "AssetParameters0d7be86c2a7d62be64fcbe2cbaa36c912a72d445022cc17c37af4f99f1b97a5aS3Bucket485B8F98"
+ }
+ ],
+ "SourceObjectKeys": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersd09271be89b6cb0398f793b40c1531fd9b076aa92ba80b5e436914b1808fe18dS3VersionKeyED6BBB32"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersd09271be89b6cb0398f793b40c1531fd9b076aa92ba80b5e436914b1808fe18dS3VersionKeyED6BBB32"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters0f14dedeaf4386031c978375cbda0f65d7b52b29452cabb8873eb8f0d0fa936bS3VersionKey9FBF1498"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters0f14dedeaf4386031c978375cbda0f65d7b52b29452cabb8873eb8f0d0fa936bS3VersionKey9FBF1498"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters0d7be86c2a7d62be64fcbe2cbaa36c912a72d445022cc17c37af4f99f1b97a5aS3VersionKeyC8D63B0C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters0d7be86c2a7d62be64fcbe2cbaa36c912a72d445022cc17c37af4f99f1b97a5aS3VersionKeyC8D63B0C"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ "SourceMarkers": [
+ {},
+ {
+ "<Hello, S3 bucket deployments!
+
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/asset.fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/rabir2v.gif b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/asset.fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/rabir2v.gif
new file mode 100644
index 0000000000000..e82b75cdb2187
Binary files /dev/null and b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/asset.fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/rabir2v.gif differ
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/cdk.out
new file mode 100644
index 0000000000000..90bef2e09ad39
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/cdk.out
@@ -0,0 +1 @@
+{"version":"17.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/integ.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/integ.json
new file mode 100644
index 0000000000000..a5867e610a5a4
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/integ.json
@@ -0,0 +1,14 @@
+{
+ "version": "18.0.0",
+ "testCases": {
+ "aws-s3-deployment/test/integ.bucket-deployment": {
+ "stacks": [
+ "test-bucket-deployments-2"
+ ],
+ "diffAssets": false,
+ "stackUpdateWorkflow": true
+ }
+ },
+ "synthContext": {},
+ "enableLookups": false
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/manifest.json
new file mode 100644
index 0000000000000..0bffbc6deaeb3
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/manifest.json
@@ -0,0 +1,498 @@
+{
+ "version": "17.0.0",
+ "artifacts": {
+ "Tree": {
+ "type": "cdk:tree",
+ "properties": {
+ "file": "tree.json"
+ }
+ },
+ "test-bucket-deployments-2": {
+ "type": "aws:cloudformation:stack",
+ "environment": "aws://unknown-account/unknown-region",
+ "properties": {
+ "templateFile": "test-bucket-deployments-2.template.json",
+ "validateOnSynth": false
+ },
+ "metadata": {
+ "/test-bucket-deployments-2": [
+ {
+ "type": "aws:cdk:asset",
+ "data": {
+ "path": "asset.be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "id": "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "packaging": "zip",
+ "sourceHash": "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "s3BucketParameter": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232",
+ "s3KeyParameter": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE",
+ "artifactHashParameter": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824ArtifactHash76F8FCF2"
+ }
+ },
+ {
+ "type": "aws:cdk:asset",
+ "data": {
+ "path": "asset.01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476.zip",
+ "id": "01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476",
+ "packaging": "file",
+ "sourceHash": "01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476",
+ "s3BucketParameter": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4",
+ "s3KeyParameter": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0",
+ "artifactHashParameter": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476ArtifactHash0FB7E57C"
+ }
+ },
+ {
+ "type": "aws:cdk:asset",
+ "data": {
+ "path": "asset.f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "id": "f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "packaging": "zip",
+ "sourceHash": "f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "s3BucketParameter": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7",
+ "s3KeyParameter": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D",
+ "artifactHashParameter": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daArtifactHashD85D28D8"
+ }
+ },
+ {
+ "type": "aws:cdk:asset",
+ "data": {
+ "path": "asset.fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "id": "fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "packaging": "zip",
+ "sourceHash": "fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "s3BucketParameter": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A",
+ "s3KeyParameter": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C",
+ "artifactHashParameter": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eArtifactHash0E426313"
+ }
+ }
+ ],
+ "/test-bucket-deployments-2/Destination/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination920A3C57"
+ }
+ ],
+ "/test-bucket-deployments-2/Destination/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DestinationPolicy7982387E"
+ }
+ ],
+ "/test-bucket-deployments-2/Destination/AutoDeleteObjectsCustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DestinationAutoDeleteObjectsCustomResource15E926BA"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/S3Bucket": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/S3VersionKey": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/ArtifactHash": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824ArtifactHash76F8FCF2"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/S3Bucket": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/S3VersionKey": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/ArtifactHash": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476ArtifactHash0FB7E57C"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/S3Bucket": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/S3VersionKey": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/ArtifactHash": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daArtifactHashD85D28D8"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/S3Bucket": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/S3VersionKey": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ],
+ "/test-bucket-deployments-2/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/ArtifactHash": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eArtifactHash0E426313"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployMe/AwsCliLayer/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployMeAwsCliLayer5F9219E9"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployMe/CustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployMeCustomResource4455EE35"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/DefaultPolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpc2605A3C4"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet1/Subnet": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet1Subnet2EDC574A"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet1/RouteTable": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet1RouteTable67856EA2"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet1/RouteTableAssociation": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet1RouteTableAssociationDA9AACF2"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet1/DefaultRoute": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet1DefaultRoute84A6786F"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet1/EIP": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet1EIPCB8385DA"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet1/NATGateway": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet1NATGateway88242629"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet2/Subnet": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet2SubnetAB52037C"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet2/RouteTable": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet2RouteTable053CA1F8"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet2/RouteTableAssociation": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet2RouteTableAssociation3DB8A2E6"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet2/DefaultRoute": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet2DefaultRoute9E9BF17A"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet2/EIP": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet2EIPFCFD7982"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PublicSubnet2/NATGateway": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPublicSubnet2NATGatewayB5A60DA8"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PrivateSubnet1/Subnet": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPrivateSubnet1Subnet0EC98BAD"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PrivateSubnet1/RouteTable": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPrivateSubnet1RouteTable19DB57E6"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PrivateSubnet1/RouteTableAssociation": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPrivateSubnet1RouteTableAssociation9D48EE22"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PrivateSubnet1/DefaultRoute": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPrivateSubnet1DefaultRouteC56CB768"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PrivateSubnet2/Subnet": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPrivateSubnet2Subnet60DB7D03"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PrivateSubnet2/RouteTable": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPrivateSubnet2RouteTableE3C67EFF"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PrivateSubnet2/RouteTableAssociation": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPrivateSubnet2RouteTableAssociation6D6562EB"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/PrivateSubnet2/DefaultRoute": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcPrivateSubnet2DefaultRouteA98D214A"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/IGW": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcIGW515300DC"
+ }
+ ],
+ "/test-bucket-deployments-2/InlineVpc/VPCGW": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "InlineVpcVPCGWE98B1862"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployMeWithEfsStorage/AwsCliLayer/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployMeWithEfsStorageAwsCliLayer1619A3EE"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployMeWithEfsStorage/CustomResource-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployMeWithEfsStorageCustomResourcec8e45d2d82aec23f89c7172e7e6f994ff3d9c444faC9646D53"
+ }
+ ],
+ "/test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ }
+ ],
+ "/test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsSecurityGroup/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroup8A6327B1"
+ }
+ ],
+ "/test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsSecurityGroup/from testbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF:2049": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroupfromtestbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF20498CD714A7"
+ }
+ ],
+ "/test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsMountTarget1": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget140913EA1"
+ }
+ ],
+ "/test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsMountTarget2": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget215F1A11A"
+ }
+ ],
+ "/test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/AccessPoint/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faAccessPoint657AFA25"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/ServiceRole/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRole1F2E85D4"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/ServiceRole/DefaultPolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRoleDefaultPolicyDE2C8526"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/SecurityGroup/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupD7C1D75A"
+ }
+ ],
+ "/test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa03838EC0"
+ }
+ ],
+ "/test-bucket-deployments-2/Destination2/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination281A09BDF"
+ }
+ ],
+ "/test-bucket-deployments-2/Destination2/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination2PolicyA94CC138"
+ }
+ ],
+ "/test-bucket-deployments-2/Destination2/AutoDeleteObjectsCustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination2AutoDeleteObjectsCustomResource8A5BE3F7"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployWithPrefix/AwsCliLayer/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployWithPrefixAwsCliLayerC9DDB597"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployWithPrefix/CustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployWithPrefixCustomResource9CF7C694"
+ }
+ ],
+ "/test-bucket-deployments-2/Destination3/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination3E3DC043D"
+ }
+ ],
+ "/test-bucket-deployments-2/Destination3/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination3Policy685DA6C5"
+ }
+ ],
+ "/test-bucket-deployments-2/Destination3/AutoDeleteObjectsCustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Destination3AutoDeleteObjectsCustomResourceC26EC7B7"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployWithMetadata/AwsCliLayer/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployWithMetadataAwsCliLayer2C774B41"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployWithMetadata/CustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployWithMetadataCustomResourceA73C95DC"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/AwsCliLayer/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployMeWithoutDeletingFilesOnDestinationAwsCliLayer4D54C41C"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/CustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployMeWithoutDeletingFilesOnDestinationCustomResourceA390B02B"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/AwsCliLayer/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployMeWithExcludedFilesOnDestinationAwsCliLayer68F5E11D"
+ }
+ ],
+ "/test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/CustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DeployMeWithExcludedFilesOnDestinationCustomResource48D69581"
+ }
+ ]
+ },
+ "displayName": "test-bucket-deployments-2"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/test-bucket-deployments-2.template.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/test-bucket-deployments-2.template.json
new file mode 100644
index 0000000000000..9099de19669a1
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/test-bucket-deployments-2.template.json
@@ -0,0 +1,2163 @@
+{
+ "Resources": {
+ "Destination920A3C57": {
+ "Type": "AWS::S3::Bucket",
+ "Properties": {
+ "Tags": [
+ {
+ "Key": "aws-cdk:auto-delete-objects",
+ "Value": "true"
+ },
+ {
+ "Key": "aws-cdk:cr-owned:12c80047",
+ "Value": "true"
+ },
+ {
+ "Key": "aws-cdk:cr-owned:c06dfca0",
+ "Value": "true"
+ },
+ {
+ "Key": "aws-cdk:cr-owned:efs/:a01ecd3e",
+ "Value": "true"
+ },
+ {
+ "Key": "aws-cdk:cr-owned:f8ab5a69",
+ "Value": "true"
+ }
+ ],
+ "WebsiteConfiguration": {
+ "IndexDocument": "index.html"
+ }
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "DestinationPolicy7982387E": {
+ "Type": "AWS::S3::BucketPolicy",
+ "Properties": {
+ "Bucket": {
+ "Ref": "Destination920A3C57"
+ },
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ }
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "DestinationAutoDeleteObjectsCustomResource15E926BA": {
+ "Type": "Custom::S3AutoDeleteObjects",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Destination920A3C57"
+ }
+ },
+ "DependsOn": [
+ "DestinationPolicy7982387E"
+ ],
+ "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": {
+ "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Timeout": 900,
+ "MemorySize": 128,
+ "Handler": "__entrypoint__.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ },
+ "Runtime": "nodejs12.x",
+ "Description": {
+ "Fn::Join": [
+ "",
+ [
+ "Lambda function for auto-deleting objects in ",
+ {
+ "Ref": "Destination920A3C57"
+ },
+ " S3 bucket."
+ ]
+ ]
+ }
+ },
+ "DependsOn": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092"
+ ]
+ },
+ "DeployMeAwsCliLayer5F9219E9": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Properties": {
+ "Content": {
+ "S3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Description": "/opt/awscli/aws"
+ }
+ },
+ "DeployMeCustomResource4455EE35": {
+ "Type": "Custom::CDKBucketDeployment",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536",
+ "Arn"
+ ]
+ },
+ "SourceBucketNames": [
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "SourceObjectKeys": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ "DestinationBucketName": {
+ "Ref": "Destination920A3C57"
+ },
+ "RetainOnDelete": false,
+ "Prune": true
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Action": [
+ "s3:Abort*",
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination281A09BDF",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination281A09BDF",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF",
+ "Roles": [
+ {
+ "Ref": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265"
+ }
+ ]
+ }
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "S3Bucket": {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265",
+ "Arn"
+ ]
+ },
+ "Handler": "index.handler",
+ "Layers": [
+ {
+ "Ref": "DeployMeAwsCliLayer5F9219E9"
+ }
+ ],
+ "Runtime": "python3.7",
+ "Timeout": 900
+ },
+ "DependsOn": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF",
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265"
+ ]
+ },
+ "InlineVpc2605A3C4": {
+ "Type": "AWS::EC2::VPC",
+ "Properties": {
+ "CidrBlock": "10.0.0.0/16",
+ "EnableDnsHostnames": true,
+ "EnableDnsSupport": true,
+ "InstanceTenancy": "default",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc"
+ }
+ ]
+ }
+ },
+ "InlineVpcPublicSubnet1Subnet2EDC574A": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.0.0/18",
+ "MapPublicIpOnLaunch": true,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Public"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Public"
+ },
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "InlineVpcPublicSubnet1RouteTable67856EA2": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "InlineVpcPublicSubnet1RouteTableAssociationDA9AACF2": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "InlineVpcPublicSubnet1RouteTable67856EA2"
+ },
+ "SubnetId": {
+ "Ref": "InlineVpcPublicSubnet1Subnet2EDC574A"
+ }
+ }
+ },
+ "InlineVpcPublicSubnet1DefaultRoute84A6786F": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "InlineVpcPublicSubnet1RouteTable67856EA2"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "GatewayId": {
+ "Ref": "InlineVpcIGW515300DC"
+ }
+ },
+ "DependsOn": [
+ "InlineVpcVPCGWE98B1862"
+ ]
+ },
+ "InlineVpcPublicSubnet1EIPCB8385DA": {
+ "Type": "AWS::EC2::EIP",
+ "Properties": {
+ "Domain": "vpc",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "InlineVpcPublicSubnet1NATGateway88242629": {
+ "Type": "AWS::EC2::NatGateway",
+ "Properties": {
+ "SubnetId": {
+ "Ref": "InlineVpcPublicSubnet1Subnet2EDC574A"
+ },
+ "AllocationId": {
+ "Fn::GetAtt": [
+ "InlineVpcPublicSubnet1EIPCB8385DA",
+ "AllocationId"
+ ]
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "InlineVpcPublicSubnet2SubnetAB52037C": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.64.0/18",
+ "MapPublicIpOnLaunch": true,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Public"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Public"
+ },
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "InlineVpcPublicSubnet2RouteTable053CA1F8": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "InlineVpcPublicSubnet2RouteTableAssociation3DB8A2E6": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "InlineVpcPublicSubnet2RouteTable053CA1F8"
+ },
+ "SubnetId": {
+ "Ref": "InlineVpcPublicSubnet2SubnetAB52037C"
+ }
+ }
+ },
+ "InlineVpcPublicSubnet2DefaultRoute9E9BF17A": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "InlineVpcPublicSubnet2RouteTable053CA1F8"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "GatewayId": {
+ "Ref": "InlineVpcIGW515300DC"
+ }
+ },
+ "DependsOn": [
+ "InlineVpcVPCGWE98B1862"
+ ]
+ },
+ "InlineVpcPublicSubnet2EIPFCFD7982": {
+ "Type": "AWS::EC2::EIP",
+ "Properties": {
+ "Domain": "vpc",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "InlineVpcPublicSubnet2NATGatewayB5A60DA8": {
+ "Type": "AWS::EC2::NatGateway",
+ "Properties": {
+ "SubnetId": {
+ "Ref": "InlineVpcPublicSubnet2SubnetAB52037C"
+ },
+ "AllocationId": {
+ "Fn::GetAtt": [
+ "InlineVpcPublicSubnet2EIPFCFD7982",
+ "AllocationId"
+ ]
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "InlineVpcPrivateSubnet1Subnet0EC98BAD": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.128.0/18",
+ "MapPublicIpOnLaunch": false,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Private"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Private"
+ },
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "InlineVpcPrivateSubnet1RouteTable19DB57E6": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "InlineVpcPrivateSubnet1RouteTableAssociation9D48EE22": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "InlineVpcPrivateSubnet1RouteTable19DB57E6"
+ },
+ "SubnetId": {
+ "Ref": "InlineVpcPrivateSubnet1Subnet0EC98BAD"
+ }
+ }
+ },
+ "InlineVpcPrivateSubnet1DefaultRouteC56CB768": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "InlineVpcPrivateSubnet1RouteTable19DB57E6"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "NatGatewayId": {
+ "Ref": "InlineVpcPublicSubnet1NATGateway88242629"
+ }
+ }
+ },
+ "InlineVpcPrivateSubnet2Subnet60DB7D03": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.192.0/18",
+ "MapPublicIpOnLaunch": false,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Private"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Private"
+ },
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "InlineVpcPrivateSubnet2RouteTableE3C67EFF": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "InlineVpcPrivateSubnet2RouteTableAssociation6D6562EB": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "InlineVpcPrivateSubnet2RouteTableE3C67EFF"
+ },
+ "SubnetId": {
+ "Ref": "InlineVpcPrivateSubnet2Subnet60DB7D03"
+ }
+ }
+ },
+ "InlineVpcPrivateSubnet2DefaultRouteA98D214A": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "InlineVpcPrivateSubnet2RouteTableE3C67EFF"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "NatGatewayId": {
+ "Ref": "InlineVpcPublicSubnet2NATGatewayB5A60DA8"
+ }
+ }
+ },
+ "InlineVpcIGW515300DC": {
+ "Type": "AWS::EC2::InternetGateway",
+ "Properties": {
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/InlineVpc"
+ }
+ ]
+ }
+ },
+ "InlineVpcVPCGWE98B1862": {
+ "Type": "AWS::EC2::VPCGatewayAttachment",
+ "Properties": {
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "InternetGatewayId": {
+ "Ref": "InlineVpcIGW515300DC"
+ }
+ }
+ },
+ "DeployMeWithEfsStorageAwsCliLayer1619A3EE": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Properties": {
+ "Content": {
+ "S3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Description": "/opt/awscli/aws"
+ },
+ "DependsOn": [
+ "InlineVpcIGW515300DC",
+ "InlineVpcPrivateSubnet1DefaultRouteC56CB768",
+ "InlineVpcPrivateSubnet1RouteTable19DB57E6",
+ "InlineVpcPrivateSubnet1RouteTableAssociation9D48EE22",
+ "InlineVpcPrivateSubnet1Subnet0EC98BAD",
+ "InlineVpcPrivateSubnet2DefaultRouteA98D214A",
+ "InlineVpcPrivateSubnet2RouteTableE3C67EFF",
+ "InlineVpcPrivateSubnet2RouteTableAssociation6D6562EB",
+ "InlineVpcPrivateSubnet2Subnet60DB7D03",
+ "InlineVpcPublicSubnet1DefaultRoute84A6786F",
+ "InlineVpcPublicSubnet1EIPCB8385DA",
+ "InlineVpcPublicSubnet1NATGateway88242629",
+ "InlineVpcPublicSubnet1RouteTable67856EA2",
+ "InlineVpcPublicSubnet1RouteTableAssociationDA9AACF2",
+ "InlineVpcPublicSubnet1Subnet2EDC574A",
+ "InlineVpcPublicSubnet2DefaultRoute9E9BF17A",
+ "InlineVpcPublicSubnet2EIPFCFD7982",
+ "InlineVpcPublicSubnet2NATGatewayB5A60DA8",
+ "InlineVpcPublicSubnet2RouteTable053CA1F8",
+ "InlineVpcPublicSubnet2RouteTableAssociation3DB8A2E6",
+ "InlineVpcPublicSubnet2SubnetAB52037C",
+ "InlineVpc2605A3C4",
+ "InlineVpcVPCGWE98B1862"
+ ]
+ },
+ "DeployMeWithEfsStorageCustomResourcec8e45d2d82aec23f89c7172e7e6f994ff3d9c444faC9646D53": {
+ "Type": "Custom::CDKBucketDeployment",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa03838EC0",
+ "Arn"
+ ]
+ },
+ "SourceBucketNames": [
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "SourceObjectKeys": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ "DestinationBucketName": {
+ "Ref": "Destination920A3C57"
+ },
+ "DestinationBucketKeyPrefix": "efs/",
+ "RetainOnDelete": false,
+ "Prune": true
+ },
+ "DependsOn": [
+ "InlineVpcIGW515300DC",
+ "InlineVpcPrivateSubnet1DefaultRouteC56CB768",
+ "InlineVpcPrivateSubnet1RouteTable19DB57E6",
+ "InlineVpcPrivateSubnet1RouteTableAssociation9D48EE22",
+ "InlineVpcPrivateSubnet1Subnet0EC98BAD",
+ "InlineVpcPrivateSubnet2DefaultRouteA98D214A",
+ "InlineVpcPrivateSubnet2RouteTableE3C67EFF",
+ "InlineVpcPrivateSubnet2RouteTableAssociation6D6562EB",
+ "InlineVpcPrivateSubnet2Subnet60DB7D03",
+ "InlineVpcPublicSubnet1DefaultRoute84A6786F",
+ "InlineVpcPublicSubnet1EIPCB8385DA",
+ "InlineVpcPublicSubnet1NATGateway88242629",
+ "InlineVpcPublicSubnet1RouteTable67856EA2",
+ "InlineVpcPublicSubnet1RouteTableAssociationDA9AACF2",
+ "InlineVpcPublicSubnet1Subnet2EDC574A",
+ "InlineVpcPublicSubnet2DefaultRoute9E9BF17A",
+ "InlineVpcPublicSubnet2EIPFCFD7982",
+ "InlineVpcPublicSubnet2NATGatewayB5A60DA8",
+ "InlineVpcPublicSubnet2RouteTable053CA1F8",
+ "InlineVpcPublicSubnet2RouteTableAssociation3DB8A2E6",
+ "InlineVpcPublicSubnet2SubnetAB52037C",
+ "InlineVpc2605A3C4",
+ "InlineVpcVPCGWE98B1862"
+ ],
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B": {
+ "Type": "AWS::EFS::FileSystem",
+ "Properties": {
+ "Encrypted": true,
+ "FileSystemTags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa"
+ }
+ ]
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroup8A6327B1": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Properties": {
+ "GroupDescription": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsSecurityGroup",
+ "SecurityGroupEgress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow all outbound traffic by default",
+ "IpProtocol": "-1"
+ }
+ ],
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa"
+ }
+ ],
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ }
+ }
+ },
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroupfromtestbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF20498CD714A7": {
+ "Type": "AWS::EC2::SecurityGroupIngress",
+ "Properties": {
+ "IpProtocol": "tcp",
+ "Description": "from testbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF:2049",
+ "FromPort": 2049,
+ "GroupId": {
+ "Fn::GetAtt": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroup8A6327B1",
+ "GroupId"
+ ]
+ },
+ "SourceSecurityGroupId": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupD7C1D75A",
+ "GroupId"
+ ]
+ },
+ "ToPort": 2049
+ }
+ },
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget140913EA1": {
+ "Type": "AWS::EFS::MountTarget",
+ "Properties": {
+ "FileSystemId": {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ },
+ "SecurityGroups": [
+ {
+ "Fn::GetAtt": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroup8A6327B1",
+ "GroupId"
+ ]
+ }
+ ],
+ "SubnetId": {
+ "Ref": "InlineVpcPrivateSubnet1Subnet0EC98BAD"
+ }
+ }
+ },
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget215F1A11A": {
+ "Type": "AWS::EFS::MountTarget",
+ "Properties": {
+ "FileSystemId": {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ },
+ "SecurityGroups": [
+ {
+ "Fn::GetAtt": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroup8A6327B1",
+ "GroupId"
+ ]
+ }
+ ],
+ "SubnetId": {
+ "Ref": "InlineVpcPrivateSubnet2Subnet60DB7D03"
+ }
+ }
+ },
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faAccessPoint657AFA25": {
+ "Type": "AWS::EFS::AccessPoint",
+ "Properties": {
+ "FileSystemId": {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ },
+ "PosixUser": {
+ "Gid": "1001",
+ "Uid": "1001"
+ },
+ "RootDirectory": {
+ "CreationInfo": {
+ "OwnerGid": "1001",
+ "OwnerUid": "1001",
+ "Permissions": "0777"
+ },
+ "Path": "/lambda"
+ }
+ },
+ "DependsOn": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget140913EA1",
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget215F1A11A"
+ ]
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRole1F2E85D4": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
+ ]
+ ]
+ }
+ ]
+ },
+ "DependsOn": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget140913EA1",
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget215F1A11A"
+ ]
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRoleDefaultPolicyDE2C8526": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "elasticfilesystem:ClientMount",
+ "Condition": {
+ "StringEquals": {
+ "elasticfilesystem:AccessPointArn": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":elasticfilesystem:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":access-point/",
+ {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faAccessPoint657AFA25"
+ }
+ ]
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Resource": "*"
+ },
+ {
+ "Action": "elasticfilesystem:ClientWrite",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":elasticfilesystem:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":file-system/",
+ {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ }
+ ]
+ ]
+ }
+ },
+ {
+ "Action": [
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Action": [
+ "s3:Abort*",
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "tomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRoleDefaultPolicyDE2C8526",
+ "Roles": [
+ {
+ "Ref": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRole1F2E85D4"
+ }
+ ]
+ },
+ "DependsOn": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget140913EA1",
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget215F1A11A"
+ ]
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupD7C1D75A": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Properties": {
+ "GroupDescription": "Automatic security group for Lambda Function testbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faB7A82630",
+ "SecurityGroupEgress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow all outbound traffic by default",
+ "IpProtocol": "-1"
+ }
+ ],
+ "VpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ }
+ },
+ "DependsOn": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget140913EA1",
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget215F1A11A"
+ ]
+ },
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa03838EC0": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "S3Bucket": {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRole1F2E85D4",
+ "Arn"
+ ]
+ },
+ "Environment": {
+ "Variables": {
+ "MOUNT_PATH": "/mnt/lambda"
+ }
+ },
+ "FileSystemConfigs": [
+ {
+ "Arn": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":elasticfilesystem:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":access-point/",
+ {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faAccessPoint657AFA25"
+ }
+ ]
+ ]
+ },
+ "LocalMountPath": "/mnt/lambda"
+ }
+ ],
+ "Handler": "index.handler",
+ "Layers": [
+ {
+ "Ref": "DeployMeWithEfsStorageAwsCliLayer1619A3EE"
+ }
+ ],
+ "Runtime": "python3.7",
+ "Timeout": 900,
+ "VpcConfig": {
+ "SecurityGroupIds": [
+ {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupD7C1D75A",
+ "GroupId"
+ ]
+ }
+ ],
+ "SubnetIds": [
+ {
+ "Ref": "InlineVpcPrivateSubnet1Subnet0EC98BAD"
+ },
+ {
+ "Ref": "InlineVpcPrivateSubnet2Subnet60DB7D03"
+ }
+ ]
+ }
+ },
+ "DependsOn": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget140913EA1",
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsMountTarget215F1A11A",
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroupfromtestbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF20498CD714A7",
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRoleDefaultPolicyDE2C8526",
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRole1F2E85D4"
+ ]
+ },
+ "Destination281A09BDF": {
+ "Type": "AWS::S3::Bucket",
+ "Properties": {
+ "Tags": [
+ {
+ "Key": "aws-cdk:auto-delete-objects",
+ "Value": "true"
+ },
+ {
+ "Key": "aws-cdk:cr-owned:deploy/here/:272e95d8",
+ "Value": "true"
+ }
+ ]
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Destination2PolicyA94CC138": {
+ "Type": "AWS::S3::BucketPolicy",
+ "Properties": {
+ "Bucket": {
+ "Ref": "Destination281A09BDF"
+ },
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ }
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination281A09BDF",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination281A09BDF",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "Destination2AutoDeleteObjectsCustomResource8A5BE3F7": {
+ "Type": "Custom::S3AutoDeleteObjects",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Destination281A09BDF"
+ }
+ },
+ "DependsOn": [
+ "Destination2PolicyA94CC138"
+ ],
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "DeployWithPrefixAwsCliLayerC9DDB597": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Properties": {
+ "Content": {
+ "S3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Description": "/opt/awscli/aws"
+ }
+ },
+ "DeployWithPrefixCustomResource9CF7C694": {
+ "Type": "Custom::CDKBucketDeployment",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536",
+ "Arn"
+ ]
+ },
+ "SourceBucketNames": [
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "SourceObjectKeys": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ "DestinationBucketName": {
+ "Ref": "Destination281A09BDF"
+ },
+ "DestinationBucketKeyPrefix": "deploy/here/",
+ "RetainOnDelete": false,
+ "Prune": true
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Destination3E3DC043D": {
+ "Type": "AWS::S3::Bucket",
+ "Properties": {
+ "Tags": [
+ {
+ "Key": "aws-cdk:auto-delete-objects",
+ "Value": "true"
+ },
+ {
+ "Key": "aws-cdk:cr-owned:9eca9fb3",
+ "Value": "true"
+ }
+ ]
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Destination3Policy685DA6C5": {
+ "Type": "AWS::S3::BucketPolicy",
+ "Properties": {
+ "Bucket": {
+ "Ref": "Destination3E3DC043D"
+ },
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ }
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "Destination3AutoDeleteObjectsCustomResourceC26EC7B7": {
+ "Type": "Custom::S3AutoDeleteObjects",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Destination3E3DC043D"
+ }
+ },
+ "DependsOn": [
+ "Destination3Policy685DA6C5"
+ ],
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "DeployWithMetadataAwsCliLayer2C774B41": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Properties": {
+ "Content": {
+ "S3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Description": "/opt/awscli/aws"
+ }
+ },
+ "DeployWithMetadataCustomResourceA73C95DC": {
+ "Type": "Custom::CDKBucketDeployment",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536",
+ "Arn"
+ ]
+ },
+ "SourceBucketNames": [
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "SourceObjectKeys": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ "DestinationBucketName": {
+ "Ref": "Destination3E3DC043D"
+ },
+ "RetainOnDelete": false,
+ "Prune": true,
+ "UserMetadata": {
+ "a": "aaa",
+ "b": "bbb",
+ "c": "ccc"
+ },
+ "SystemMetadata": {
+ "cache-control": "public, max-age=60",
+ "content-type": "text/html"
+ }
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "DeployMeWithoutDeletingFilesOnDestinationAwsCliLayer4D54C41C": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Properties": {
+ "Content": {
+ "S3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Description": "/opt/awscli/aws"
+ }
+ },
+ "DeployMeWithoutDeletingFilesOnDestinationCustomResourceA390B02B": {
+ "Type": "Custom::CDKBucketDeployment",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536",
+ "Arn"
+ ]
+ },
+ "SourceBucketNames": [
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "SourceObjectKeys": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ "DestinationBucketName": {
+ "Ref": "Destination920A3C57"
+ },
+ "RetainOnDelete": false,
+ "Prune": false
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "DeployMeWithExcludedFilesOnDestinationAwsCliLayer68F5E11D": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Properties": {
+ "Content": {
+ "S3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "S3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "Description": "/opt/awscli/aws"
+ }
+ },
+ "DeployMeWithExcludedFilesOnDestinationCustomResource48D69581": {
+ "Type": "Custom::CDKBucketDeployment",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536",
+ "Arn"
+ ]
+ },
+ "SourceBucketNames": [
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ],
+ "SourceObjectKeys": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ "DestinationBucketName": {
+ "Ref": "Destination920A3C57"
+ },
+ "RetainOnDelete": false,
+ "Prune": true,
+ "Exclude": [
+ "*.gif"
+ ]
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ }
+ },
+ "Parameters": {
+ "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232": {
+ "Type": "String",
+ "Description": "S3 bucket for asset \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\""
+ },
+ "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE": {
+ "Type": "String",
+ "Description": "S3 key for asset version \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\""
+ },
+ "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824ArtifactHash76F8FCF2": {
+ "Type": "String",
+ "Description": "Artifact hash for asset \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\""
+ },
+ "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4": {
+ "Type": "String",
+ "Description": "S3 bucket for asset \"01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476\""
+ },
+ "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0": {
+ "Type": "String",
+ "Description": "S3 key for asset version \"01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476\""
+ },
+ "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476ArtifactHash0FB7E57C": {
+ "Type": "String",
+ "Description": "Artifact hash for asset \"01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476\""
+ },
+ "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7": {
+ "Type": "String",
+ "Description": "S3 bucket for asset \"f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da\""
+ },
+ "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D": {
+ "Type": "String",
+ "Description": "S3 key for asset version \"f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da\""
+ },
+ "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daArtifactHashD85D28D8": {
+ "Type": "String",
+ "Description": "Artifact hash for asset \"f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da\""
+ },
+ "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A": {
+ "Type": "String",
+ "Description": "S3 bucket for asset \"fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e\""
+ },
+ "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3VersionKeyA58D380C": {
+ "Type": "String",
+ "Description": "S3 key for asset version \"fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e\""
+ },
+ "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eArtifactHash0E426313": {
+ "Type": "String",
+ "Description": "Artifact hash for asset \"fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e\""
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/tree.json b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/tree.json
new file mode 100644
index 0000000000000..5059cdfc81e2a
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.integ.snapshot/tree.json
@@ -0,0 +1,3040 @@
+{
+ "version": "tree-0.1",
+ "tree": {
+ "id": "App",
+ "path": "",
+ "children": {
+ "Tree": {
+ "id": "Tree",
+ "path": "Tree",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "test-bucket-deployments-2": {
+ "id": "test-bucket-deployments-2",
+ "path": "test-bucket-deployments-2",
+ "children": {
+ "Destination": {
+ "id": "Destination",
+ "path": "test-bucket-deployments-2/Destination",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Destination/Resource",
+ "attributes": {
+ "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:12c80047",
+ "value": "true"
+ },
+ {
+ "key": "aws-cdk:cr-owned:c06dfca0",
+ "value": "true"
+ },
+ {
+ "key": "aws-cdk:cr-owned:efs/:a01ecd3e",
+ "value": "true"
+ },
+ {
+ "key": "aws-cdk:cr-owned:f8ab5a69",
+ "value": "true"
+ }
+ ],
+ "websiteConfiguration": {
+ "indexDocument": "index.html"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "test-bucket-deployments-2/Destination/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Destination/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy",
+ "aws:cdk:cloudformation:props": {
+ "bucket": {
+ "Ref": "Destination920A3C57"
+ },
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ }
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketPolicy",
+ "version": "0.0.0"
+ }
+ },
+ "AutoDeleteObjectsCustomResource": {
+ "id": "AutoDeleteObjectsCustomResource",
+ "path": "test-bucket-deployments-2/Destination/AutoDeleteObjectsCustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/Destination/AutoDeleteObjectsCustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "Custom::S3AutoDeleteObjectsCustomResourceProvider": {
+ "id": "Custom::S3AutoDeleteObjectsCustomResourceProvider",
+ "path": "test-bucket-deployments-2/Custom::S3AutoDeleteObjectsCustomResourceProvider",
+ "children": {
+ "Staging": {
+ "id": "Staging",
+ "path": "test-bucket-deployments-2/Custom::S3AutoDeleteObjectsCustomResourceProvider/Staging",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "Role": {
+ "id": "Role",
+ "path": "test-bucket-deployments-2/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ },
+ "Handler": {
+ "id": "Handler",
+ "path": "test-bucket-deployments-2/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResourceProvider",
+ "version": "0.0.0"
+ }
+ },
+ "AssetParameters": {
+ "id": "AssetParameters",
+ "path": "test-bucket-deployments-2/AssetParameters",
+ "children": {
+ "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824": {
+ "id": "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "path": "test-bucket-deployments-2/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824",
+ "children": {
+ "S3Bucket": {
+ "id": "S3Bucket",
+ "path": "test-bucket-deployments-2/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/S3Bucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "S3VersionKey": {
+ "id": "S3VersionKey",
+ "path": "test-bucket-deployments-2/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/S3VersionKey",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "ArtifactHash": {
+ "id": "ArtifactHash",
+ "path": "test-bucket-deployments-2/AssetParameters/be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824/ArtifactHash",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476": {
+ "id": "01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476",
+ "path": "test-bucket-deployments-2/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476",
+ "children": {
+ "S3Bucket": {
+ "id": "S3Bucket",
+ "path": "test-bucket-deployments-2/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/S3Bucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "S3VersionKey": {
+ "id": "S3VersionKey",
+ "path": "test-bucket-deployments-2/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/S3VersionKey",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "ArtifactHash": {
+ "id": "ArtifactHash",
+ "path": "test-bucket-deployments-2/AssetParameters/01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476/ArtifactHash",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da": {
+ "id": "f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "path": "test-bucket-deployments-2/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da",
+ "children": {
+ "S3Bucket": {
+ "id": "S3Bucket",
+ "path": "test-bucket-deployments-2/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/S3Bucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "S3VersionKey": {
+ "id": "S3VersionKey",
+ "path": "test-bucket-deployments-2/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/S3VersionKey",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "ArtifactHash": {
+ "id": "ArtifactHash",
+ "path": "test-bucket-deployments-2/AssetParameters/f98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711da/ArtifactHash",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e": {
+ "id": "fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "path": "test-bucket-deployments-2/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e",
+ "children": {
+ "S3Bucket": {
+ "id": "S3Bucket",
+ "path": "test-bucket-deployments-2/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/S3Bucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "S3VersionKey": {
+ "id": "S3VersionKey",
+ "path": "test-bucket-deployments-2/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/S3VersionKey",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "ArtifactHash": {
+ "id": "ArtifactHash",
+ "path": "test-bucket-deployments-2/AssetParameters/fc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222e/ArtifactHash",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnParameter",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "DeployMe": {
+ "id": "DeployMe",
+ "path": "test-bucket-deployments-2/DeployMe",
+ "children": {
+ "AwsCliLayer": {
+ "id": "AwsCliLayer",
+ "path": "test-bucket-deployments-2/DeployMe/AwsCliLayer",
+ "children": {
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-2/DeployMe/AwsCliLayer/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployMe/AwsCliLayer/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployMe/AwsCliLayer/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/DeployMe/AwsCliLayer/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::LayerVersion",
+ "aws:cdk:cloudformation:props": {
+ "content": {
+ "s3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "description": "/opt/awscli/aws"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnLayerVersion",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/lambda-layer-awscli.AwsCliLayer",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourceHandler": {
+ "id": "CustomResourceHandler",
+ "path": "test-bucket-deployments-2/DeployMe/CustomResourceHandler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Asset1": {
+ "id": "Asset1",
+ "path": "test-bucket-deployments-2/DeployMe/Asset1",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployMe/Asset1/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployMe/Asset1/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResource": {
+ "id": "CustomResource",
+ "path": "test-bucket-deployments-2/DeployMe/CustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/DeployMe/CustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-deployment.BucketDeployment",
+ "version": "0.0.0"
+ }
+ },
+ "Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C": {
+ "id": "Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C",
+ "children": {
+ "ServiceRole": {
+ "id": "ServiceRole",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnRole",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultPolicy": {
+ "id": "DefaultPolicy",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/DefaultPolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole/DefaultPolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Action": [
+ "s3:Abort*",
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination281A09BDF",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination281A09BDF",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF",
+ "roles": [
+ {
+ "Ref": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Function",
+ "aws:cdk:cloudformation:props": {
+ "code": {
+ "s3Bucket": {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "role": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265",
+ "Arn"
+ ]
+ },
+ "handler": "index.handler",
+ "layers": [
+ {
+ "Ref": "DeployMeAwsCliLayer5F9219E9"
+ }
+ ],
+ "runtime": "python3.7",
+ "timeout": 900
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnFunction",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.Function",
+ "version": "0.0.0"
+ }
+ },
+ "InlineVpc": {
+ "id": "InlineVpc",
+ "path": "test-bucket-deployments-2/InlineVpc",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/InlineVpc/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::VPC",
+ "aws:cdk:cloudformation:props": {
+ "cidrBlock": "10.0.0.0/16",
+ "enableDnsHostnames": true,
+ "enableDnsSupport": true,
+ "instanceTenancy": "default",
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnVPC",
+ "version": "0.0.0"
+ }
+ },
+ "PublicSubnet1": {
+ "id": "PublicSubnet1",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet1",
+ "children": {
+ "Subnet": {
+ "id": "Subnet",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet1/Subnet",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Subnet",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "availabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "cidrBlock": "10.0.0.0/18",
+ "mapPublicIpOnLaunch": true,
+ "tags": [
+ {
+ "key": "aws-cdk:subnet-name",
+ "value": "Public"
+ },
+ {
+ "key": "aws-cdk:subnet-type",
+ "value": "Public"
+ },
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "Acl": {
+ "id": "Acl",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet1/Acl",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTable": {
+ "id": "RouteTable",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet1/RouteTable",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnRouteTable",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTableAssociation": {
+ "id": "RouteTableAssociation",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet1/RouteTableAssociation",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "InlineVpcPublicSubnet1RouteTable67856EA2"
+ },
+ "subnetId": {
+ "Ref": "InlineVpcPublicSubnet1Subnet2EDC574A"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultRoute": {
+ "id": "DefaultRoute",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet1/DefaultRoute",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "InlineVpcPublicSubnet1RouteTable67856EA2"
+ },
+ "destinationCidrBlock": "0.0.0.0/0",
+ "gatewayId": {
+ "Ref": "InlineVpcIGW515300DC"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnRoute",
+ "version": "0.0.0"
+ }
+ },
+ "EIP": {
+ "id": "EIP",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet1/EIP",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::EIP",
+ "aws:cdk:cloudformation:props": {
+ "domain": "vpc",
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnEIP",
+ "version": "0.0.0"
+ }
+ },
+ "NATGateway": {
+ "id": "NATGateway",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet1/NATGateway",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway",
+ "aws:cdk:cloudformation:props": {
+ "subnetId": {
+ "Ref": "InlineVpcPublicSubnet1Subnet2EDC574A"
+ },
+ "allocationId": {
+ "Fn::GetAtt": [
+ "InlineVpcPublicSubnet1EIPCB8385DA",
+ "AllocationId"
+ ]
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnNatGateway",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.PublicSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "PublicSubnet2": {
+ "id": "PublicSubnet2",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet2",
+ "children": {
+ "Subnet": {
+ "id": "Subnet",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet2/Subnet",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Subnet",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "availabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "cidrBlock": "10.0.64.0/18",
+ "mapPublicIpOnLaunch": true,
+ "tags": [
+ {
+ "key": "aws-cdk:subnet-name",
+ "value": "Public"
+ },
+ {
+ "key": "aws-cdk:subnet-type",
+ "value": "Public"
+ },
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "Acl": {
+ "id": "Acl",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet2/Acl",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTable": {
+ "id": "RouteTable",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet2/RouteTable",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnRouteTable",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTableAssociation": {
+ "id": "RouteTableAssociation",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet2/RouteTableAssociation",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "InlineVpcPublicSubnet2RouteTable053CA1F8"
+ },
+ "subnetId": {
+ "Ref": "InlineVpcPublicSubnet2SubnetAB52037C"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultRoute": {
+ "id": "DefaultRoute",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet2/DefaultRoute",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "InlineVpcPublicSubnet2RouteTable053CA1F8"
+ },
+ "destinationCidrBlock": "0.0.0.0/0",
+ "gatewayId": {
+ "Ref": "InlineVpcIGW515300DC"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnRoute",
+ "version": "0.0.0"
+ }
+ },
+ "EIP": {
+ "id": "EIP",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet2/EIP",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::EIP",
+ "aws:cdk:cloudformation:props": {
+ "domain": "vpc",
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnEIP",
+ "version": "0.0.0"
+ }
+ },
+ "NATGateway": {
+ "id": "NATGateway",
+ "path": "test-bucket-deployments-2/InlineVpc/PublicSubnet2/NATGateway",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway",
+ "aws:cdk:cloudformation:props": {
+ "subnetId": {
+ "Ref": "InlineVpcPublicSubnet2SubnetAB52037C"
+ },
+ "allocationId": {
+ "Fn::GetAtt": [
+ "InlineVpcPublicSubnet2EIPFCFD7982",
+ "AllocationId"
+ ]
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnNatGateway",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.PublicSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "PrivateSubnet1": {
+ "id": "PrivateSubnet1",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1",
+ "children": {
+ "Subnet": {
+ "id": "Subnet",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1/Subnet",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Subnet",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "availabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "cidrBlock": "10.0.128.0/18",
+ "mapPublicIpOnLaunch": false,
+ "tags": [
+ {
+ "key": "aws-cdk:subnet-name",
+ "value": "Private"
+ },
+ {
+ "key": "aws-cdk:subnet-type",
+ "value": "Private"
+ },
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "Acl": {
+ "id": "Acl",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1/Acl",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTable": {
+ "id": "RouteTable",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1/RouteTable",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnRouteTable",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTableAssociation": {
+ "id": "RouteTableAssociation",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1/RouteTableAssociation",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "InlineVpcPrivateSubnet1RouteTable19DB57E6"
+ },
+ "subnetId": {
+ "Ref": "InlineVpcPrivateSubnet1Subnet0EC98BAD"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultRoute": {
+ "id": "DefaultRoute",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet1/DefaultRoute",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "InlineVpcPrivateSubnet1RouteTable19DB57E6"
+ },
+ "destinationCidrBlock": "0.0.0.0/0",
+ "natGatewayId": {
+ "Ref": "InlineVpcPublicSubnet1NATGateway88242629"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnRoute",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.PrivateSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "PrivateSubnet2": {
+ "id": "PrivateSubnet2",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2",
+ "children": {
+ "Subnet": {
+ "id": "Subnet",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2/Subnet",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Subnet",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "availabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "cidrBlock": "10.0.192.0/18",
+ "mapPublicIpOnLaunch": false,
+ "tags": [
+ {
+ "key": "aws-cdk:subnet-name",
+ "value": "Private"
+ },
+ {
+ "key": "aws-cdk:subnet-type",
+ "value": "Private"
+ },
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "Acl": {
+ "id": "Acl",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2/Acl",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTable": {
+ "id": "RouteTable",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2/RouteTable",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnRouteTable",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTableAssociation": {
+ "id": "RouteTableAssociation",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2/RouteTableAssociation",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "InlineVpcPrivateSubnet2RouteTableE3C67EFF"
+ },
+ "subnetId": {
+ "Ref": "InlineVpcPrivateSubnet2Subnet60DB7D03"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultRoute": {
+ "id": "DefaultRoute",
+ "path": "test-bucket-deployments-2/InlineVpc/PrivateSubnet2/DefaultRoute",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "InlineVpcPrivateSubnet2RouteTableE3C67EFF"
+ },
+ "destinationCidrBlock": "0.0.0.0/0",
+ "natGatewayId": {
+ "Ref": "InlineVpcPublicSubnet2NATGatewayB5A60DA8"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnRoute",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.PrivateSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "IGW": {
+ "id": "IGW",
+ "path": "test-bucket-deployments-2/InlineVpc/IGW",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway",
+ "aws:cdk:cloudformation:props": {
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/InlineVpc"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnInternetGateway",
+ "version": "0.0.0"
+ }
+ },
+ "VPCGW": {
+ "id": "VPCGW",
+ "path": "test-bucket-deployments-2/InlineVpc/VPCGW",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ },
+ "internetGatewayId": {
+ "Ref": "InlineVpcIGW515300DC"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnVPCGatewayAttachment",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.Vpc",
+ "version": "0.0.0"
+ }
+ },
+ "DeployMeWithEfsStorage": {
+ "id": "DeployMeWithEfsStorage",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage",
+ "children": {
+ "AwsCliLayer": {
+ "id": "AwsCliLayer",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/AwsCliLayer",
+ "children": {
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/AwsCliLayer/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/AwsCliLayer/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/AwsCliLayer/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/AwsCliLayer/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::LayerVersion",
+ "aws:cdk:cloudformation:props": {
+ "content": {
+ "s3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "description": "/opt/awscli/aws"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnLayerVersion",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/lambda-layer-awscli.AwsCliLayer",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourceHandler": {
+ "id": "CustomResourceHandler",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/CustomResourceHandler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Asset1": {
+ "id": "Asset1",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/Asset1",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/Asset1/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/Asset1/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResource-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa": {
+ "id": "CustomResource-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/CustomResource-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/DeployMeWithEfsStorage/CustomResource-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-deployment.BucketDeployment",
+ "version": "0.0.0"
+ }
+ },
+ "BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa": {
+ "id": "BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EFS::FileSystem",
+ "aws:cdk:cloudformation:props": {
+ "encrypted": true,
+ "fileSystemTags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-efs.CfnFileSystem",
+ "version": "0.0.0"
+ }
+ },
+ "EfsSecurityGroup": {
+ "id": "EfsSecurityGroup",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsSecurityGroup",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsSecurityGroup/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup",
+ "aws:cdk:cloudformation:props": {
+ "groupDescription": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsSecurityGroup",
+ "securityGroupEgress": [
+ {
+ "cidrIp": "0.0.0.0/0",
+ "description": "Allow all outbound traffic by default",
+ "ipProtocol": "-1"
+ }
+ ],
+ "tags": [
+ {
+ "key": "Name",
+ "value": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa"
+ }
+ ],
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup",
+ "version": "0.0.0"
+ }
+ },
+ "from testbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF:2049": {
+ "id": "from testbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF:2049",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsSecurityGroup/from testbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF:2049",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroupIngress",
+ "aws:cdk:cloudformation:props": {
+ "ipProtocol": "tcp",
+ "description": "from testbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupBDC138BF:2049",
+ "fromPort": 2049,
+ "groupId": {
+ "Fn::GetAtt": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroup8A6327B1",
+ "GroupId"
+ ]
+ },
+ "sourceSecurityGroupId": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupD7C1D75A",
+ "GroupId"
+ ]
+ },
+ "toPort": 2049
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroupIngress",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.SecurityGroup",
+ "version": "0.0.0"
+ }
+ },
+ "EfsMountTarget1": {
+ "id": "EfsMountTarget1",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsMountTarget1",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EFS::MountTarget",
+ "aws:cdk:cloudformation:props": {
+ "fileSystemId": {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ },
+ "securityGroups": [
+ {
+ "Fn::GetAtt": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroup8A6327B1",
+ "GroupId"
+ ]
+ }
+ ],
+ "subnetId": {
+ "Ref": "InlineVpcPrivateSubnet1Subnet0EC98BAD"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-efs.CfnMountTarget",
+ "version": "0.0.0"
+ }
+ },
+ "EfsMountTarget2": {
+ "id": "EfsMountTarget2",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/EfsMountTarget2",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EFS::MountTarget",
+ "aws:cdk:cloudformation:props": {
+ "fileSystemId": {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ },
+ "securityGroups": [
+ {
+ "Fn::GetAtt": [
+ "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faEfsSecurityGroup8A6327B1",
+ "GroupId"
+ ]
+ }
+ ],
+ "subnetId": {
+ "Ref": "InlineVpcPrivateSubnet2Subnet60DB7D03"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-efs.CfnMountTarget",
+ "version": "0.0.0"
+ }
+ },
+ "AccessPoint": {
+ "id": "AccessPoint",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/AccessPoint",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/BucketDeploymentEFS-VPC-c8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/AccessPoint/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EFS::AccessPoint",
+ "aws:cdk:cloudformation:props": {
+ "fileSystemId": {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ },
+ "posixUser": {
+ "uid": "1001",
+ "gid": "1001"
+ },
+ "rootDirectory": {
+ "creationInfo": {
+ "ownerGid": "1001",
+ "ownerUid": "1001",
+ "permissions": "0777"
+ },
+ "path": "/lambda"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-efs.CfnAccessPoint",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-efs.AccessPoint",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-efs.FileSystem",
+ "version": "0.0.0"
+ }
+ },
+ "Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa": {
+ "id": "Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa",
+ "children": {
+ "ServiceRole": {
+ "id": "ServiceRole",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/ServiceRole",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/ServiceRole/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnRole",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultPolicy": {
+ "id": "DefaultPolicy",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/ServiceRole/DefaultPolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/ServiceRole/DefaultPolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "elasticfilesystem:ClientMount",
+ "Condition": {
+ "StringEquals": {
+ "elasticfilesystem:AccessPointArn": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":elasticfilesystem:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":access-point/",
+ {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faAccessPoint657AFA25"
+ }
+ ]
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Resource": "*"
+ },
+ {
+ "Action": "elasticfilesystem:ClientWrite",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":elasticfilesystem:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":file-system/",
+ {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faDE9EC34B"
+ }
+ ]
+ ]
+ }
+ },
+ {
+ "Action": [
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ },
+ "/*"
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A"
+ }
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Action": [
+ "s3:Abort*",
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:GetObject*",
+ "s3:List*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination920A3C57",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "tomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRoleDefaultPolicyDE2C8526",
+ "roles": [
+ {
+ "Ref": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRole1F2E85D4"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "SecurityGroup": {
+ "id": "SecurityGroup",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/SecurityGroup",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/SecurityGroup/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup",
+ "aws:cdk:cloudformation:props": {
+ "groupDescription": "Automatic security group for Lambda Function testbucketdeployments2CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faB7A82630",
+ "securityGroupEgress": [
+ {
+ "cidrIp": "0.0.0.0/0",
+ "description": "Allow all outbound traffic by default",
+ "ipProtocol": "-1"
+ }
+ ],
+ "vpcId": {
+ "Ref": "InlineVpc2605A3C4"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-ec2.SecurityGroup",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444fa/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Function",
+ "aws:cdk:cloudformation:props": {
+ "code": {
+ "s3Bucket": {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3BucketF23C0DE7"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParametersf98b78092dcdd31f5e6d47489beb5f804d4835ef86a8085d0a2053cb9ae711daS3VersionKey5E97B17D"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "role": {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faServiceRole1F2E85D4",
+ "Arn"
+ ]
+ },
+ "environment": {
+ "variables": {
+ "MOUNT_PATH": "/mnt/lambda"
+ }
+ },
+ "fileSystemConfigs": [
+ {
+ "arn": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":elasticfilesystem:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":access-point/",
+ {
+ "Ref": "BucketDeploymentEFSVPCc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faAccessPoint657AFA25"
+ }
+ ]
+ ]
+ },
+ "localMountPath": "/mnt/lambda"
+ }
+ ],
+ "handler": "index.handler",
+ "layers": [
+ {
+ "Ref": "DeployMeWithEfsStorageAwsCliLayer1619A3EE"
+ }
+ ],
+ "runtime": "python3.7",
+ "timeout": 900,
+ "vpcConfig": {
+ "subnetIds": [
+ {
+ "Ref": "InlineVpcPrivateSubnet1Subnet0EC98BAD"
+ },
+ {
+ "Ref": "InlineVpcPrivateSubnet2Subnet60DB7D03"
+ }
+ ],
+ "securityGroupIds": [
+ {
+ "Fn::GetAtt": [
+ "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756Cc8e45d2d82aec23f89c7172e7e6f994ff3d9c444faSecurityGroupD7C1D75A",
+ "GroupId"
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnFunction",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.Function",
+ "version": "0.0.0"
+ }
+ },
+ "Destination2": {
+ "id": "Destination2",
+ "path": "test-bucket-deployments-2/Destination2",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Destination2/Resource",
+ "attributes": {
+ "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:deploy/here/:272e95d8",
+ "value": "true"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "test-bucket-deployments-2/Destination2/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Destination2/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy",
+ "aws:cdk:cloudformation:props": {
+ "bucket": {
+ "Ref": "Destination281A09BDF"
+ },
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ }
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination281A09BDF",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination281A09BDF",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketPolicy",
+ "version": "0.0.0"
+ }
+ },
+ "AutoDeleteObjectsCustomResource": {
+ "id": "AutoDeleteObjectsCustomResource",
+ "path": "test-bucket-deployments-2/Destination2/AutoDeleteObjectsCustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/Destination2/AutoDeleteObjectsCustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "DeployWithPrefix": {
+ "id": "DeployWithPrefix",
+ "path": "test-bucket-deployments-2/DeployWithPrefix",
+ "children": {
+ "AwsCliLayer": {
+ "id": "AwsCliLayer",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/AwsCliLayer",
+ "children": {
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/AwsCliLayer/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/AwsCliLayer/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/AwsCliLayer/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/AwsCliLayer/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::LayerVersion",
+ "aws:cdk:cloudformation:props": {
+ "content": {
+ "s3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "description": "/opt/awscli/aws"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnLayerVersion",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/lambda-layer-awscli.AwsCliLayer",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourceHandler": {
+ "id": "CustomResourceHandler",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/CustomResourceHandler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Asset1": {
+ "id": "Asset1",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/Asset1",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/Asset1/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/Asset1/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResource": {
+ "id": "CustomResource",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/CustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/DeployWithPrefix/CustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-deployment.BucketDeployment",
+ "version": "0.0.0"
+ }
+ },
+ "Destination3": {
+ "id": "Destination3",
+ "path": "test-bucket-deployments-2/Destination3",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Destination3/Resource",
+ "attributes": {
+ "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:9eca9fb3",
+ "value": "true"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "test-bucket-deployments-2/Destination3/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/Destination3/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy",
+ "aws:cdk:cloudformation:props": {
+ "bucket": {
+ "Ref": "Destination3E3DC043D"
+ },
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject*",
+ "s3:GetBucket*",
+ "s3:List*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::GetAtt": [
+ "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092",
+ "Arn"
+ ]
+ }
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "Destination3E3DC043D",
+ "Arn"
+ ]
+ },
+ "/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ],
+ "Version": "2012-10-17"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketPolicy",
+ "version": "0.0.0"
+ }
+ },
+ "AutoDeleteObjectsCustomResource": {
+ "id": "AutoDeleteObjectsCustomResource",
+ "path": "test-bucket-deployments-2/Destination3/AutoDeleteObjectsCustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/Destination3/AutoDeleteObjectsCustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "DeployWithMetadata": {
+ "id": "DeployWithMetadata",
+ "path": "test-bucket-deployments-2/DeployWithMetadata",
+ "children": {
+ "AwsCliLayer": {
+ "id": "AwsCliLayer",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/AwsCliLayer",
+ "children": {
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/AwsCliLayer/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/AwsCliLayer/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/AwsCliLayer/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/AwsCliLayer/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::LayerVersion",
+ "aws:cdk:cloudformation:props": {
+ "content": {
+ "s3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "description": "/opt/awscli/aws"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnLayerVersion",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/lambda-layer-awscli.AwsCliLayer",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourceHandler": {
+ "id": "CustomResourceHandler",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/CustomResourceHandler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Asset1": {
+ "id": "Asset1",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/Asset1",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/Asset1/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/Asset1/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResource": {
+ "id": "CustomResource",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/CustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/DeployWithMetadata/CustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-deployment.BucketDeployment",
+ "version": "0.0.0"
+ }
+ },
+ "DeployMeWithoutDeletingFilesOnDestination": {
+ "id": "DeployMeWithoutDeletingFilesOnDestination",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination",
+ "children": {
+ "AwsCliLayer": {
+ "id": "AwsCliLayer",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/AwsCliLayer",
+ "children": {
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/AwsCliLayer/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/AwsCliLayer/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/AwsCliLayer/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/AwsCliLayer/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::LayerVersion",
+ "aws:cdk:cloudformation:props": {
+ "content": {
+ "s3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "description": "/opt/awscli/aws"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnLayerVersion",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/lambda-layer-awscli.AwsCliLayer",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourceHandler": {
+ "id": "CustomResourceHandler",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/CustomResourceHandler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Asset1": {
+ "id": "Asset1",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/Asset1",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/Asset1/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/Asset1/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResource": {
+ "id": "CustomResource",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/CustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/DeployMeWithoutDeletingFilesOnDestination/CustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-deployment.BucketDeployment",
+ "version": "0.0.0"
+ }
+ },
+ "DeployMeWithExcludedFilesOnDestination": {
+ "id": "DeployMeWithExcludedFilesOnDestination",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination",
+ "children": {
+ "AwsCliLayer": {
+ "id": "AwsCliLayer",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/AwsCliLayer",
+ "children": {
+ "Code": {
+ "id": "Code",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/AwsCliLayer/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/AwsCliLayer/Code/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/AwsCliLayer/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/AwsCliLayer/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::LayerVersion",
+ "aws:cdk:cloudformation:props": {
+ "content": {
+ "s3Bucket": {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3BucketC0D91AC4"
+ },
+ "s3Key": {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::Split": [
+ "||",
+ {
+ "Ref": "AssetParameters01e9cf93416a1f67b17dad851459445bdaaafcc2f3ab4390c03984fd57b2f476S3VersionKey26CFD1B0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "description": "/opt/awscli/aws"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnLayerVersion",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/lambda-layer-awscli.AwsCliLayer",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourceHandler": {
+ "id": "CustomResourceHandler",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/CustomResourceHandler",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Asset1": {
+ "id": "Asset1",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/Asset1",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/Asset1/Stage",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/Asset1/AssetBucket",
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResource": {
+ "id": "CustomResource",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/CustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "test-bucket-deployments-2/DeployMeWithExcludedFilesOnDestination/CustomResource/Default",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3-deployment.BucketDeployment",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Stack",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.App",
+ "version": "0.0.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts
index 9706f9d9d33f1..0aadf05e54f39 100644
--- a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts
+++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts
@@ -714,9 +714,7 @@ test('memoryLimit can be used to specify the memory limit for the deployment res
const bucket = new s3.Bucket(stack, 'Dest');
// WHEN
-
// we define 3 deployments with 2 different memory configurations
-
new s3deploy.BucketDeployment(stack, 'Deploy256-1', {
sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website'))],
destinationBucket: bucket,
@@ -736,14 +734,52 @@ test('memoryLimit can be used to specify the memory limit for the deployment res
});
// THEN
-
// we expect to find only two handlers, one for each configuration
-
Template.fromStack(stack).resourceCountIs('AWS::Lambda::Function', 2);
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { MemorySize: 256 });
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { MemorySize: 1024 });
});
+test('ephemeralStorageSize can be used to specify the storage size for the deployment resource handler', () => {
+ // GIVEN
+ const stack = new cdk.Stack();
+ const bucket = new s3.Bucket(stack, 'Dest');
+
+ // WHEN
+ // we define 3 deployments with 2 different memory configurations
+ new s3deploy.BucketDeployment(stack, 'Deploy256-1', {
+ sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website'))],
+ destinationBucket: bucket,
+ ephemeralStorageSize: cdk.Size.mebibytes(512),
+ });
+
+ new s3deploy.BucketDeployment(stack, 'Deploy256-2', {
+ sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website'))],
+ destinationBucket: bucket,
+ ephemeralStorageSize: cdk.Size.mebibytes(512),
+ });
+
+ new s3deploy.BucketDeployment(stack, 'Deploy1024', {
+ sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website'))],
+ destinationBucket: bucket,
+ ephemeralStorageSize: cdk.Size.mebibytes(1024),
+ });
+
+ // THEN
+ // we expect to find only two handlers, one for each configuration
+ Template.fromStack(stack).resourceCountIs('AWS::Lambda::Function', 2);
+ Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', {
+ EphemeralStorage: {
+ Size: 512,
+ },
+ });
+ Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', {
+ EphemeralStorage: {
+ Size: 1024,
+ },
+ });
+});
+
test('deployment allows custom role to be supplied', () => {
// GIVEN
diff --git a/packages/@aws-cdk/aws-s3-notifications/.gitignore b/packages/@aws-cdk/aws-s3-notifications/.gitignore
index 147448f7df4fe..19f2079a2453d 100644
--- a/packages/@aws-cdk/aws-s3-notifications/.gitignore
+++ b/packages/@aws-cdk/aws-s3-notifications/.gitignore
@@ -16,4 +16,8 @@ nyc.config.js
!.eslintrc.js
!jest.config.js
-junit.xml
\ No newline at end of file
+junit.xml
+!**/*.integ.snapshot/**/asset.*/*.js
+!**/*.integ.snapshot/**/asset.*/*.d.ts
+
+!**/*.integ.snapshot/**/asset.*/**
diff --git a/packages/@aws-cdk/aws-s3-notifications/.npmignore b/packages/@aws-cdk/aws-s3-notifications/.npmignore
index aaabf1df59065..9d8e2428a5273 100644
--- a/packages/@aws-cdk/aws-s3-notifications/.npmignore
+++ b/packages/@aws-cdk/aws-s3-notifications/.npmignore
@@ -25,4 +25,6 @@ jest.config.js
**/cdk.out
junit.xml
test/
-!*.lit.ts
\ No newline at end of file
+!*.lit.ts
+**/*.integ.snapshot
+**/*.integ.snapshot
diff --git a/packages/@aws-cdk/aws-s3-notifications/package.json b/packages/@aws-cdk/aws-s3-notifications/package.json
index 32738cd1b0d93..345169af57ee9 100644
--- a/packages/@aws-cdk/aws-s3-notifications/package.json
+++ b/packages/@aws-cdk/aws-s3-notifications/package.json
@@ -47,7 +47,7 @@
"watch": "cdk-watch",
"lint": "cdk-lint",
"test": "cdk-test",
- "integ": "cdk-integ",
+ "integ": "integ-runner",
"pkglint": "pkglint -f",
"package": "cdk-package",
"awslint": "cdk-awslint",
@@ -73,7 +73,7 @@
"devDependencies": {
"@aws-cdk/assertions": "0.0.0",
"@aws-cdk/cdk-build-tools": "0.0.0",
- "@aws-cdk/cdk-integ-tools": "0.0.0",
+ "@aws-cdk/integ-runner": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^27.4.1",
"jest": "^27.5.1"
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.expected.json b/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.expected.json
index 472b3b55a72b7..0e0162c3837ea 100644
--- a/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.expected.json
+++ b/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.expected.json
@@ -159,7 +159,7 @@
},
":s3:::",
{
- "Ref": "Bucket25524B414"
+ "Ref": "Bucket3CFB7F7D7"
}
]
]
@@ -245,7 +245,7 @@
"Properties": {
"Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
"Code": {
- "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n\n # find external notifications\n external_notifications = find_external_notifications(bucket, stack_id)\n\n # if delete, that's all we need\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n # otherwise, merge external with incoming config and augment with id\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n return notifications\n\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n # if the notification was created by us, we know what id to expect\n # so we can filter by it.\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n return external_notifications\n\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
+ "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nEVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n external_notifications = find_external_notifications(bucket, stack_id)\n\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n\n if EVENTBRIDGE_CONFIGURATION in notification_configuration:\n notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]\n elif EVENTBRIDGE_CONFIGURATION in external_notifications:\n notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return notifications\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n if EVENTBRIDGE_CONFIGURATION in existing_notifications:\n external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return external_notifications\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
},
"Handler": "index.handler",
"Role": {
@@ -312,7 +312,12 @@
"Topic3DEAE47A7"
]
},
- "Bucket3NotificationsAFEFF359": {
+ "Bucket3CFB7F7D7": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Bucket3ImportedNotificationsB1625F39": {
"Type": "Custom::S3BucketNotifications",
"Properties": {
"ServiceToken": {
@@ -322,7 +327,7 @@
]
},
"BucketName": {
- "Ref": "Bucket25524B414"
+ "Ref": "Bucket3CFB7F7D7"
},
"NotificationConfiguration": {
"TopicConfigurations": [
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.ts b/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.ts
index 5e1f11d42a6ef..b4fd7c3ac604f 100644
--- a/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.ts
+++ b/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.ts
@@ -21,7 +21,11 @@ const bucket2 = new s3.Bucket(stack, 'Bucket2', {
});
bucket2.addObjectRemovedNotification(new s3n.SnsDestination(topic3), { prefix: 'foo' }, { suffix: 'foo/bar' });
-const bucket3 = s3.Bucket.fromBucketName(stack, 'Bucket3', bucket2.bucketName);
-bucket3.addEventNotification(s3.EventType.OBJECT_CREATED_COPY, new s3n.SnsDestination(topic3));
+const bucket3 = new s3.Bucket(stack, 'Bucket3', {
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
+});
+
+const importedBucket3 = s3.Bucket.fromBucketName(stack, 'Bucket3Imported', bucket3.bucketName);
+importedBucket3.addEventNotification(s3.EventType.OBJECT_CREATED_COPY, new s3n.SnsDestination(topic3));
app.synth();
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/cdk.out
new file mode 100644
index 0000000000000..90bef2e09ad39
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/cdk.out
@@ -0,0 +1 @@
+{"version":"17.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/integ.json b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/integ.json
new file mode 100644
index 0000000000000..182c9390e376e
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/integ.json
@@ -0,0 +1,14 @@
+{
+ "version": "18.0.0",
+ "testCases": {
+ "aws-s3-notifications/test/lambda/integ.bucket-notifications": {
+ "stacks": [
+ "lambda-bucket-notifications"
+ ],
+ "diffAssets": false,
+ "stackUpdateWorkflow": true
+ }
+ },
+ "synthContext": {},
+ "enableLookups": false
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/lambda-bucket-notifications.template.json b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/lambda-bucket-notifications.template.json
new file mode 100644
index 0000000000000..dcf281bcc0322
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/lambda-bucket-notifications.template.json
@@ -0,0 +1,258 @@
+{
+ "Resources": {
+ "MyBucketF68F3FF0": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "MyBucketNotifications46AC0CD2": {
+ "Type": "Custom::S3BucketNotifications",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "MyBucketF68F3FF0"
+ },
+ "NotificationConfiguration": {
+ "LambdaFunctionConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectCreated:*"
+ ],
+ "Filter": {
+ "Key": {
+ "FilterRules": [
+ {
+ "Name": "suffix",
+ "Value": ".png"
+ }
+ ]
+ }
+ },
+ "LambdaFunctionArn": {
+ "Fn::GetAtt": [
+ "MyFunction3BAA72D1",
+ "Arn"
+ ]
+ }
+ }
+ ]
+ },
+ "Managed": true
+ },
+ "DependsOn": [
+ "MyBucketAllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C1BF13476"
+ ]
+ },
+ "MyBucketAllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C1BF13476": {
+ "Type": "AWS::Lambda::Permission",
+ "Properties": {
+ "Action": "lambda:InvokeFunction",
+ "FunctionName": {
+ "Fn::GetAtt": [
+ "MyFunction3BAA72D1",
+ "Arn"
+ ]
+ },
+ "Principal": "s3.amazonaws.com",
+ "SourceAccount": {
+ "Ref": "AWS::AccountId"
+ },
+ "SourceArn": {
+ "Fn::GetAtt": [
+ "MyBucketF68F3FF0",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "MyFunctionServiceRole3C357FF2": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "MyFunction3BAA72D1": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback(null, event);\n}"
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "MyFunctionServiceRole3C357FF2",
+ "Arn"
+ ]
+ },
+ "Handler": "index.handler",
+ "Runtime": "nodejs14.x"
+ },
+ "DependsOn": [
+ "MyFunctionServiceRole3C357FF2"
+ ]
+ },
+ "YourBucketC6A57364": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "YourBucketNotifications8D39901A": {
+ "Type": "Custom::S3BucketNotifications",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "YourBucketC6A57364"
+ },
+ "NotificationConfiguration": {
+ "LambdaFunctionConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectRemoved:*"
+ ],
+ "LambdaFunctionArn": {
+ "Fn::GetAtt": [
+ "MyFunction3BAA72D1",
+ "Arn"
+ ]
+ }
+ }
+ ]
+ },
+ "Managed": true
+ },
+ "DependsOn": [
+ "YourBucketAllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C8FE2B89D"
+ ]
+ },
+ "YourBucketAllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C8FE2B89D": {
+ "Type": "AWS::Lambda::Permission",
+ "Properties": {
+ "Action": "lambda:InvokeFunction",
+ "FunctionName": {
+ "Fn::GetAtt": [
+ "MyFunction3BAA72D1",
+ "Arn"
+ ]
+ },
+ "Principal": "s3.amazonaws.com",
+ "SourceAccount": {
+ "Ref": "AWS::AccountId"
+ },
+ "SourceArn": {
+ "Fn::GetAtt": [
+ "YourBucketC6A57364",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "s3:PutBucketNotification",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "Roles": [
+ {
+ "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
+ "Code": {
+ "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nEVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n external_notifications = find_external_notifications(bucket, stack_id)\n\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n\n if EVENTBRIDGE_CONFIGURATION in notification_configuration:\n notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]\n elif EVENTBRIDGE_CONFIGURATION in external_notifications:\n notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return notifications\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n if EVENTBRIDGE_CONFIGURATION in existing_notifications:\n external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return external_notifications\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
+ },
+ "Handler": "index.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC",
+ "Arn"
+ ]
+ },
+ "Runtime": "python3.7",
+ "Timeout": 300
+ },
+ "DependsOn": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/manifest.json
new file mode 100644
index 0000000000000..c5c6b3fdc08ad
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/manifest.json
@@ -0,0 +1,88 @@
+{
+ "version": "17.0.0",
+ "artifacts": {
+ "Tree": {
+ "type": "cdk:tree",
+ "properties": {
+ "file": "tree.json"
+ }
+ },
+ "lambda-bucket-notifications": {
+ "type": "aws:cloudformation:stack",
+ "environment": "aws://unknown-account/unknown-region",
+ "properties": {
+ "templateFile": "lambda-bucket-notifications.template.json",
+ "validateOnSynth": false
+ },
+ "metadata": {
+ "/lambda-bucket-notifications/MyBucket/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyBucketF68F3FF0"
+ }
+ ],
+ "/lambda-bucket-notifications/MyBucket/Notifications/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyBucketNotifications46AC0CD2"
+ }
+ ],
+ "/lambda-bucket-notifications/MyBucket/AllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyBucketAllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C1BF13476"
+ }
+ ],
+ "/lambda-bucket-notifications/MyFunction/ServiceRole/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyFunctionServiceRole3C357FF2"
+ }
+ ],
+ "/lambda-bucket-notifications/MyFunction/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyFunction3BAA72D1"
+ }
+ ],
+ "/lambda-bucket-notifications/YourBucket/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "YourBucketC6A57364"
+ }
+ ],
+ "/lambda-bucket-notifications/YourBucket/Notifications/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "YourBucketNotifications8D39901A"
+ }
+ ],
+ "/lambda-bucket-notifications/YourBucket/AllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "YourBucketAllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C8FE2B89D"
+ }
+ ],
+ "/lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ],
+ "/lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36"
+ }
+ ],
+ "/lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691"
+ }
+ ]
+ },
+ "displayName": "lambda-bucket-notifications"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/tree.json b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/tree.json
new file mode 100644
index 0000000000000..c5aff47f10b5a
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/bucket-notifications.integ.snapshot/tree.json
@@ -0,0 +1,360 @@
+{
+ "version": "tree-0.1",
+ "tree": {
+ "id": "App",
+ "path": "",
+ "children": {
+ "Tree": {
+ "id": "Tree",
+ "path": "Tree",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "lambda-bucket-notifications": {
+ "id": "lambda-bucket-notifications",
+ "path": "lambda-bucket-notifications",
+ "children": {
+ "MyBucket": {
+ "id": "MyBucket",
+ "path": "lambda-bucket-notifications/MyBucket",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/MyBucket/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::Bucket",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Notifications": {
+ "id": "Notifications",
+ "path": "lambda-bucket-notifications/MyBucket/Notifications",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/MyBucket/Notifications/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "AllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C": {
+ "id": "AllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C",
+ "path": "lambda-bucket-notifications/MyBucket/AllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Permission",
+ "aws:cdk:cloudformation:props": {
+ "action": "lambda:InvokeFunction",
+ "functionName": {
+ "Fn::GetAtt": [
+ "MyFunction3BAA72D1",
+ "Arn"
+ ]
+ },
+ "principal": "s3.amazonaws.com",
+ "sourceAccount": {
+ "Ref": "AWS::AccountId"
+ },
+ "sourceArn": {
+ "Fn::GetAtt": [
+ "MyBucketF68F3FF0",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnPermission",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "MyFunction": {
+ "id": "MyFunction",
+ "path": "lambda-bucket-notifications/MyFunction",
+ "children": {
+ "ServiceRole": {
+ "id": "ServiceRole",
+ "path": "lambda-bucket-notifications/MyFunction/ServiceRole",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/MyFunction/ServiceRole/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnRole",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/MyFunction/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Function",
+ "aws:cdk:cloudformation:props": {
+ "code": {
+ "zipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback(null, event);\n}"
+ },
+ "role": {
+ "Fn::GetAtt": [
+ "MyFunctionServiceRole3C357FF2",
+ "Arn"
+ ]
+ },
+ "handler": "index.handler",
+ "runtime": "nodejs14.x"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnFunction",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.Function",
+ "version": "0.0.0"
+ }
+ },
+ "YourBucket": {
+ "id": "YourBucket",
+ "path": "lambda-bucket-notifications/YourBucket",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/YourBucket/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::Bucket",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Notifications": {
+ "id": "Notifications",
+ "path": "lambda-bucket-notifications/YourBucket/Notifications",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/YourBucket/Notifications/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "AllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C": {
+ "id": "AllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C",
+ "path": "lambda-bucket-notifications/YourBucket/AllowBucketNotificationsTolambdabucketnotificationsMyFunction4086861C",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Permission",
+ "aws:cdk:cloudformation:props": {
+ "action": "lambda:InvokeFunction",
+ "functionName": {
+ "Fn::GetAtt": [
+ "MyFunction3BAA72D1",
+ "Arn"
+ ]
+ },
+ "principal": "s3.amazonaws.com",
+ "sourceAccount": {
+ "Ref": "AWS::AccountId"
+ },
+ "sourceArn": {
+ "Fn::GetAtt": [
+ "YourBucketC6A57364",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-lambda.CfnPermission",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834": {
+ "id": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834",
+ "path": "lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834",
+ "children": {
+ "Role": {
+ "id": "Role",
+ "path": "lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnRole",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultPolicy": {
+ "id": "DefaultPolicy",
+ "path": "lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "s3:PutBucketNotification",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "roles": [
+ {
+ "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "lambda-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Stack",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.App",
+ "version": "0.0.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.expected.json b/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.expected.json
index 731effea95a53..8cc9c00a4fe29 100644
--- a/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.expected.json
+++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.expected.json
@@ -114,7 +114,7 @@
]
},
"Handler": "index.handler",
- "Runtime": "nodejs10.x"
+ "Runtime": "nodejs14.x"
},
"DependsOn": [
"MyFunctionServiceRole3C357FF2"
@@ -237,7 +237,7 @@
"Properties": {
"Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
"Code": {
- "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n\n # find external notifications\n external_notifications = find_external_notifications(bucket, stack_id)\n\n # if delete, that's all we need\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n # otherwise, merge external with incoming config and augment with id\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n return notifications\n\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n # if the notification was created by us, we know what id to expect\n # so we can filter by it.\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n return external_notifications\n\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
+ "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nEVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n external_notifications = find_external_notifications(bucket, stack_id)\n\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n\n if EVENTBRIDGE_CONFIGURATION in notification_configuration:\n notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]\n elif EVENTBRIDGE_CONFIGURATION in external_notifications:\n notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return notifications\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n if EVENTBRIDGE_CONFIGURATION in existing_notifications:\n external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return external_notifications\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
},
"Handler": "index.handler",
"Role": {
@@ -255,4 +255,4 @@
]
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.ts b/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.ts
index c237b24e896e3..1493e29176362 100644
--- a/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.ts
+++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.ts
@@ -12,7 +12,7 @@ const bucketA = new s3.Bucket(stack, 'MyBucket', {
});
const fn = new lambda.Function(stack, 'MyFunction', {
- runtime: lambda.Runtime.NODEJS_10_X,
+ runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
code: lambda.Code.fromInline(`exports.handler = ${handler.toString()}`),
});
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/cdk.out
new file mode 100644
index 0000000000000..90bef2e09ad39
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/cdk.out
@@ -0,0 +1 @@
+{"version":"17.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/integ.json b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/integ.json
new file mode 100644
index 0000000000000..13034c3f6f59c
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/integ.json
@@ -0,0 +1,14 @@
+{
+ "version": "18.0.0",
+ "testCases": {
+ "aws-s3-notifications/test/integ.notifications": {
+ "stacks": [
+ "test-3"
+ ],
+ "diffAssets": false,
+ "stackUpdateWorkflow": true
+ }
+ },
+ "synthContext": {},
+ "enableLookups": false
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/manifest.json
new file mode 100644
index 0000000000000..2afbc416c96bb
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/manifest.json
@@ -0,0 +1,100 @@
+{
+ "version": "17.0.0",
+ "artifacts": {
+ "Tree": {
+ "type": "cdk:tree",
+ "properties": {
+ "file": "tree.json"
+ }
+ },
+ "test-3": {
+ "type": "aws:cloudformation:stack",
+ "environment": "aws://unknown-account/unknown-region",
+ "properties": {
+ "templateFile": "test-3.template.json",
+ "validateOnSynth": false
+ },
+ "metadata": {
+ "/test-3/Bucket/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket83908E77"
+ }
+ ],
+ "/test-3/Bucket/Notifications/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotifications8F2E257D"
+ }
+ ],
+ "/test-3/Topic/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "TopicBFC7AF6E"
+ }
+ ],
+ "/test-3/Topic/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "TopicPolicyA1747468"
+ }
+ ],
+ "/test-3/Topic3/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Topic3DEAE47A7"
+ }
+ ],
+ "/test-3/Topic3/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Topic3Policy49BDDFBD"
+ }
+ ],
+ "/test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ],
+ "/test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36"
+ }
+ ],
+ "/test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691"
+ }
+ ],
+ "/test-3/Bucket2/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket25524B414"
+ }
+ ],
+ "/test-3/Bucket2/Notifications/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket2NotificationsD9BA2A77"
+ }
+ ],
+ "/test-3/Bucket3/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket3CFB7F7D7"
+ }
+ ],
+ "/test-3/Bucket3Imported/Notifications/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket3ImportedNotificationsB1625F39"
+ }
+ ]
+ },
+ "displayName": "test-3"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/test-3.template.json b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/test-3.template.json
new file mode 100644
index 0000000000000..fb9e75c91aa1d
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/test-3.template.json
@@ -0,0 +1,352 @@
+{
+ "Resources": {
+ "Bucket83908E77": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "BucketNotifications8F2E257D": {
+ "Type": "Custom::S3BucketNotifications",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Bucket83908E77"
+ },
+ "NotificationConfiguration": {
+ "TopicConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectCreated:Put"
+ ],
+ "TopicArn": {
+ "Ref": "TopicBFC7AF6E"
+ }
+ },
+ {
+ "Events": [
+ "s3:ObjectRemoved:*"
+ ],
+ "Filter": {
+ "Key": {
+ "FilterRules": [
+ {
+ "Name": "prefix",
+ "Value": "home/myusername/"
+ }
+ ]
+ }
+ },
+ "TopicArn": {
+ "Ref": "Topic3DEAE47A7"
+ }
+ }
+ ]
+ },
+ "Managed": true
+ },
+ "DependsOn": [
+ "TopicPolicyA1747468",
+ "TopicBFC7AF6E",
+ "Topic3Policy49BDDFBD",
+ "Topic3DEAE47A7"
+ ]
+ },
+ "TopicBFC7AF6E": {
+ "Type": "AWS::SNS::Topic"
+ },
+ "TopicPolicyA1747468": {
+ "Type": "AWS::SNS::TopicPolicy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket83908E77",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "TopicBFC7AF6E"
+ },
+ "Sid": "0"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "Topics": [
+ {
+ "Ref": "TopicBFC7AF6E"
+ }
+ ]
+ }
+ },
+ "Topic3DEAE47A7": {
+ "Type": "AWS::SNS::Topic"
+ },
+ "Topic3Policy49BDDFBD": {
+ "Type": "AWS::SNS::TopicPolicy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket83908E77",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "Topic3DEAE47A7"
+ },
+ "Sid": "0"
+ },
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket25524B414",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "Topic3DEAE47A7"
+ },
+ "Sid": "1"
+ },
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "Bucket3CFB7F7D7"
+ }
+ ]
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "Topic3DEAE47A7"
+ },
+ "Sid": "2"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "Topics": [
+ {
+ "Ref": "Topic3DEAE47A7"
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:GetBucketNotification",
+ "s3:PutBucketNotification"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "Roles": [
+ {
+ "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
+ "Code": {
+ "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nEVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n external_notifications = find_external_notifications(bucket, stack_id)\n\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n\n if EVENTBRIDGE_CONFIGURATION in notification_configuration:\n notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]\n elif EVENTBRIDGE_CONFIGURATION in external_notifications:\n notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return notifications\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n if EVENTBRIDGE_CONFIGURATION in existing_notifications:\n external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return external_notifications\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
+ },
+ "Handler": "index.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC",
+ "Arn"
+ ]
+ },
+ "Runtime": "python3.7",
+ "Timeout": 300
+ },
+ "DependsOn": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ ]
+ },
+ "Bucket25524B414": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Bucket2NotificationsD9BA2A77": {
+ "Type": "Custom::S3BucketNotifications",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Bucket25524B414"
+ },
+ "NotificationConfiguration": {
+ "TopicConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectRemoved:*"
+ ],
+ "Filter": {
+ "Key": {
+ "FilterRules": [
+ {
+ "Name": "prefix",
+ "Value": "foo"
+ },
+ {
+ "Name": "suffix",
+ "Value": "foo/bar"
+ }
+ ]
+ }
+ },
+ "TopicArn": {
+ "Ref": "Topic3DEAE47A7"
+ }
+ }
+ ]
+ },
+ "Managed": true
+ },
+ "DependsOn": [
+ "Topic3Policy49BDDFBD",
+ "Topic3DEAE47A7"
+ ]
+ },
+ "Bucket3CFB7F7D7": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Bucket3ImportedNotificationsB1625F39": {
+ "Type": "Custom::S3BucketNotifications",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Bucket3CFB7F7D7"
+ },
+ "NotificationConfiguration": {
+ "TopicConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectCreated:Copy"
+ ],
+ "TopicArn": {
+ "Ref": "Topic3DEAE47A7"
+ }
+ }
+ ]
+ },
+ "Managed": false
+ },
+ "DependsOn": [
+ "Topic3Policy49BDDFBD",
+ "Topic3DEAE47A7"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/tree.json b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/tree.json
new file mode 100644
index 0000000000000..43697b3564b78
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/notifications.integ.snapshot/tree.json
@@ -0,0 +1,473 @@
+{
+ "version": "tree-0.1",
+ "tree": {
+ "id": "App",
+ "path": "",
+ "children": {
+ "Tree": {
+ "id": "Tree",
+ "path": "Tree",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "test-3": {
+ "id": "test-3",
+ "path": "test-3",
+ "children": {
+ "Bucket": {
+ "id": "Bucket",
+ "path": "test-3/Bucket",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Bucket/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::Bucket",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Notifications": {
+ "id": "Notifications",
+ "path": "test-3/Bucket/Notifications",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Bucket/Notifications/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "Topic": {
+ "id": "Topic",
+ "path": "test-3/Topic",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Topic/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SNS::Topic",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.CfnTopic",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "test-3/Topic/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Topic/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SNS::TopicPolicy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket83908E77",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "TopicBFC7AF6E"
+ },
+ "Sid": "0"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "topics": [
+ {
+ "Ref": "TopicBFC7AF6E"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.CfnTopicPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.TopicPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.Topic",
+ "version": "0.0.0"
+ }
+ },
+ "Topic3": {
+ "id": "Topic3",
+ "path": "test-3/Topic3",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Topic3/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SNS::Topic",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.CfnTopic",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "test-3/Topic3/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Topic3/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SNS::TopicPolicy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket83908E77",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "Topic3DEAE47A7"
+ },
+ "Sid": "0"
+ },
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket25524B414",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "Topic3DEAE47A7"
+ },
+ "Sid": "1"
+ },
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":s3:::",
+ {
+ "Ref": "Bucket3CFB7F7D7"
+ }
+ ]
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "Topic3DEAE47A7"
+ },
+ "Sid": "2"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "topics": [
+ {
+ "Ref": "Topic3DEAE47A7"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.CfnTopicPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.TopicPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.Topic",
+ "version": "0.0.0"
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834": {
+ "id": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834",
+ "path": "test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834",
+ "children": {
+ "Role": {
+ "id": "Role",
+ "path": "test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnRole",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultPolicy": {
+ "id": "DefaultPolicy",
+ "path": "test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:GetBucketNotification",
+ "s3:PutBucketNotification"
+ ],
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "roles": [
+ {
+ "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "Bucket2": {
+ "id": "Bucket2",
+ "path": "test-3/Bucket2",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Bucket2/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::Bucket",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Notifications": {
+ "id": "Notifications",
+ "path": "test-3/Bucket2/Notifications",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Bucket2/Notifications/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "Bucket3": {
+ "id": "Bucket3",
+ "path": "test-3/Bucket3",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Bucket3/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::Bucket",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "Bucket3Imported": {
+ "id": "Bucket3Imported",
+ "path": "test-3/Bucket3Imported",
+ "children": {
+ "Notifications": {
+ "id": "Notifications",
+ "path": "test-3/Bucket3Imported/Notifications",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "test-3/Bucket3Imported/Notifications/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Stack",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.App",
+ "version": "0.0.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.expected.json b/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.expected.json
index 47f2a8ea6e0ce..fce3f59e27d78 100644
--- a/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.expected.json
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.expected.json
@@ -195,7 +195,7 @@
"Properties": {
"Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
"Code": {
- "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n\n # find external notifications\n external_notifications = find_external_notifications(bucket, stack_id)\n\n # if delete, that's all we need\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n # otherwise, merge external with incoming config and augment with id\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n return notifications\n\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n # if the notification was created by us, we know what id to expect\n # so we can filter by it.\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n return external_notifications\n\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
+ "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nEVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n external_notifications = find_external_notifications(bucket, stack_id)\n\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n\n if EVENTBRIDGE_CONFIGURATION in notification_configuration:\n notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]\n elif EVENTBRIDGE_CONFIGURATION in external_notifications:\n notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return notifications\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n if EVENTBRIDGE_CONFIGURATION in existing_notifications:\n external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return external_notifications\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
},
"Handler": "index.handler",
"Role": {
@@ -213,4 +213,4 @@
]
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/cdk.out
new file mode 100644
index 0000000000000..90bef2e09ad39
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/cdk.out
@@ -0,0 +1 @@
+{"version":"17.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/integ.json b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/integ.json
new file mode 100644
index 0000000000000..f2ec494d1bd7b
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/integ.json
@@ -0,0 +1,14 @@
+{
+ "version": "18.0.0",
+ "testCases": {
+ "aws-s3-notifications/test/sns/integ.sns-bucket-notifications": {
+ "stacks": [
+ "sns-bucket-notifications"
+ ],
+ "diffAssets": false,
+ "stackUpdateWorkflow": true
+ }
+ },
+ "synthContext": {},
+ "enableLookups": false
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/manifest.json
new file mode 100644
index 0000000000000..68a56ced1dc46
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/manifest.json
@@ -0,0 +1,76 @@
+{
+ "version": "17.0.0",
+ "artifacts": {
+ "Tree": {
+ "type": "cdk:tree",
+ "properties": {
+ "file": "tree.json"
+ }
+ },
+ "sns-bucket-notifications": {
+ "type": "aws:cloudformation:stack",
+ "environment": "aws://unknown-account/unknown-region",
+ "properties": {
+ "templateFile": "sns-bucket-notifications.template.json",
+ "validateOnSynth": false
+ },
+ "metadata": {
+ "/sns-bucket-notifications/ObjectCreatedTopic/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ObjectCreatedTopic92F47E19"
+ }
+ ],
+ "/sns-bucket-notifications/ObjectCreatedTopic/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ObjectCreatedTopicPolicyA938ECFC"
+ }
+ ],
+ "/sns-bucket-notifications/ObjectDeletedTopic/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ObjectDeletedTopic2A914EC0"
+ }
+ ],
+ "/sns-bucket-notifications/ObjectDeletedTopic/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ObjectDeletedTopicPolicy026B02E6"
+ }
+ ],
+ "/sns-bucket-notifications/MyBucket/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyBucketF68F3FF0"
+ }
+ ],
+ "/sns-bucket-notifications/MyBucket/Notifications/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyBucketNotifications46AC0CD2"
+ }
+ ],
+ "/sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ],
+ "/sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36"
+ }
+ ],
+ "/sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691"
+ }
+ ]
+ },
+ "displayName": "sns-bucket-notifications"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/sns-bucket-notifications.template.json b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/sns-bucket-notifications.template.json
new file mode 100644
index 0000000000000..a30019f0261de
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/sns-bucket-notifications.template.json
@@ -0,0 +1,216 @@
+{
+ "Resources": {
+ "ObjectCreatedTopic92F47E19": {
+ "Type": "AWS::SNS::Topic"
+ },
+ "ObjectCreatedTopicPolicyA938ECFC": {
+ "Type": "AWS::SNS::TopicPolicy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "MyBucketF68F3FF0",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "ObjectCreatedTopic92F47E19"
+ },
+ "Sid": "0"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "Topics": [
+ {
+ "Ref": "ObjectCreatedTopic92F47E19"
+ }
+ ]
+ }
+ },
+ "ObjectDeletedTopic2A914EC0": {
+ "Type": "AWS::SNS::Topic"
+ },
+ "ObjectDeletedTopicPolicy026B02E6": {
+ "Type": "AWS::SNS::TopicPolicy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "MyBucketF68F3FF0",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "ObjectDeletedTopic2A914EC0"
+ },
+ "Sid": "0"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "Topics": [
+ {
+ "Ref": "ObjectDeletedTopic2A914EC0"
+ }
+ ]
+ }
+ },
+ "MyBucketF68F3FF0": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "MyBucketNotifications46AC0CD2": {
+ "Type": "Custom::S3BucketNotifications",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "MyBucketF68F3FF0"
+ },
+ "NotificationConfiguration": {
+ "TopicConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectCreated:*"
+ ],
+ "TopicArn": {
+ "Ref": "ObjectCreatedTopic92F47E19"
+ }
+ },
+ {
+ "Events": [
+ "s3:ObjectRemoved:*"
+ ],
+ "Filter": {
+ "Key": {
+ "FilterRules": [
+ {
+ "Name": "suffix",
+ "Value": ".txt"
+ },
+ {
+ "Name": "prefix",
+ "Value": "foo/"
+ }
+ ]
+ }
+ },
+ "TopicArn": {
+ "Ref": "ObjectDeletedTopic2A914EC0"
+ }
+ }
+ ]
+ },
+ "Managed": true
+ },
+ "DependsOn": [
+ "ObjectCreatedTopicPolicyA938ECFC",
+ "ObjectCreatedTopic92F47E19",
+ "ObjectDeletedTopicPolicy026B02E6",
+ "ObjectDeletedTopic2A914EC0"
+ ]
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "s3:PutBucketNotification",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "Roles": [
+ {
+ "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
+ "Code": {
+ "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nEVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n external_notifications = find_external_notifications(bucket, stack_id)\n\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n\n if EVENTBRIDGE_CONFIGURATION in notification_configuration:\n notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]\n elif EVENTBRIDGE_CONFIGURATION in external_notifications:\n notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return notifications\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n if EVENTBRIDGE_CONFIGURATION in existing_notifications:\n external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return external_notifications\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
+ },
+ "Handler": "index.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC",
+ "Arn"
+ ]
+ },
+ "Runtime": "python3.7",
+ "Timeout": 300
+ },
+ "DependsOn": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/tree.json b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/tree.json
new file mode 100644
index 0000000000000..8c283db542855
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sns/sns-bucket-notifications.integ.snapshot/tree.json
@@ -0,0 +1,329 @@
+{
+ "version": "tree-0.1",
+ "tree": {
+ "id": "App",
+ "path": "",
+ "children": {
+ "Tree": {
+ "id": "Tree",
+ "path": "Tree",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "sns-bucket-notifications": {
+ "id": "sns-bucket-notifications",
+ "path": "sns-bucket-notifications",
+ "children": {
+ "ObjectCreatedTopic": {
+ "id": "ObjectCreatedTopic",
+ "path": "sns-bucket-notifications/ObjectCreatedTopic",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/ObjectCreatedTopic/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SNS::Topic",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.CfnTopic",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "sns-bucket-notifications/ObjectCreatedTopic/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/ObjectCreatedTopic/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SNS::TopicPolicy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "MyBucketF68F3FF0",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "ObjectCreatedTopic92F47E19"
+ },
+ "Sid": "0"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "topics": [
+ {
+ "Ref": "ObjectCreatedTopic92F47E19"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.CfnTopicPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.TopicPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.Topic",
+ "version": "0.0.0"
+ }
+ },
+ "ObjectDeletedTopic": {
+ "id": "ObjectDeletedTopic",
+ "path": "sns-bucket-notifications/ObjectDeletedTopic",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/ObjectDeletedTopic/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SNS::Topic",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.CfnTopic",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "sns-bucket-notifications/ObjectDeletedTopic/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/ObjectDeletedTopic/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SNS::TopicPolicy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "sns:Publish",
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "MyBucketF68F3FF0",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Ref": "ObjectDeletedTopic2A914EC0"
+ },
+ "Sid": "0"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "topics": [
+ {
+ "Ref": "ObjectDeletedTopic2A914EC0"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.CfnTopicPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.TopicPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sns.Topic",
+ "version": "0.0.0"
+ }
+ },
+ "MyBucket": {
+ "id": "MyBucket",
+ "path": "sns-bucket-notifications/MyBucket",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/MyBucket/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::Bucket",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Notifications": {
+ "id": "Notifications",
+ "path": "sns-bucket-notifications/MyBucket/Notifications",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/MyBucket/Notifications/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834": {
+ "id": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834",
+ "path": "sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834",
+ "children": {
+ "Role": {
+ "id": "Role",
+ "path": "sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnRole",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultPolicy": {
+ "id": "DefaultPolicy",
+ "path": "sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "s3:PutBucketNotification",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "roles": [
+ {
+ "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "sns-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Stack",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.App",
+ "version": "0.0.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/cdk.out
new file mode 100644
index 0000000000000..90bef2e09ad39
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/cdk.out
@@ -0,0 +1 @@
+{"version":"17.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/integ.json b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/integ.json
new file mode 100644
index 0000000000000..e044f450fdb09
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/integ.json
@@ -0,0 +1,14 @@
+{
+ "version": "18.0.0",
+ "testCases": {
+ "aws-s3-notifications/test/sqs/integ.bucket-notifications": {
+ "stacks": [
+ "sqs-bucket-notifications"
+ ],
+ "diffAssets": false,
+ "stackUpdateWorkflow": true
+ }
+ },
+ "synthContext": {},
+ "enableLookups": false
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/manifest.json
new file mode 100644
index 0000000000000..c1d306e65b188
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/manifest.json
@@ -0,0 +1,94 @@
+{
+ "version": "17.0.0",
+ "artifacts": {
+ "Tree": {
+ "type": "cdk:tree",
+ "properties": {
+ "file": "tree.json"
+ }
+ },
+ "sqs-bucket-notifications": {
+ "type": "aws:cloudformation:stack",
+ "environment": "aws://unknown-account/unknown-region",
+ "properties": {
+ "templateFile": "sqs-bucket-notifications.template.json",
+ "validateOnSynth": false
+ },
+ "metadata": {
+ "/sqs-bucket-notifications/Bucket1/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket12520700A"
+ }
+ ],
+ "/sqs-bucket-notifications/Bucket1/Notifications/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket1NotificationsBC5D9A45"
+ }
+ ],
+ "/sqs-bucket-notifications/MyQueue/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyQueueE6CA6235"
+ }
+ ],
+ "/sqs-bucket-notifications/MyQueue/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "MyQueuePolicy6BBEDDAC"
+ }
+ ],
+ "/sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ],
+ "/sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36"
+ }
+ ],
+ "/sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691"
+ }
+ ],
+ "/sqs-bucket-notifications/Bucket2/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket25524B414"
+ }
+ ],
+ "/sqs-bucket-notifications/Bucket2/Notifications/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Bucket2NotificationsD9BA2A77"
+ }
+ ],
+ "/sqs-bucket-notifications/EncryptedQueue/Key/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "EncryptedQueueKey6F4FD304"
+ }
+ ],
+ "/sqs-bucket-notifications/EncryptedQueue/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "EncryptedQueue0428C61A"
+ }
+ ],
+ "/sqs-bucket-notifications/EncryptedQueue/Policy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "EncryptedQueuePolicy8AEB1708"
+ }
+ ]
+ },
+ "displayName": "sqs-bucket-notifications"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/sqs-bucket-notifications.template.json b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/sqs-bucket-notifications.template.json
new file mode 100644
index 0000000000000..152e018b95135
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/sqs-bucket-notifications.template.json
@@ -0,0 +1,379 @@
+{
+ "Resources": {
+ "Bucket12520700A": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Bucket1NotificationsBC5D9A45": {
+ "Type": "Custom::S3BucketNotifications",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Bucket12520700A"
+ },
+ "NotificationConfiguration": {
+ "QueueConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectCreated:*"
+ ],
+ "QueueArn": {
+ "Fn::GetAtt": [
+ "MyQueueE6CA6235",
+ "Arn"
+ ]
+ }
+ },
+ {
+ "Events": [
+ "s3:ObjectRemoved:*"
+ ],
+ "QueueArn": {
+ "Fn::GetAtt": [
+ "EncryptedQueue0428C61A",
+ "Arn"
+ ]
+ }
+ }
+ ]
+ },
+ "Managed": true
+ },
+ "DependsOn": [
+ "EncryptedQueueKey6F4FD304",
+ "EncryptedQueuePolicy8AEB1708",
+ "EncryptedQueue0428C61A",
+ "MyQueuePolicy6BBEDDAC",
+ "MyQueueE6CA6235"
+ ]
+ },
+ "MyQueueE6CA6235": {
+ "Type": "AWS::SQS::Queue",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "MyQueuePolicy6BBEDDAC": {
+ "Type": "AWS::SQS::QueuePolicy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "sqs:GetQueueAttributes",
+ "sqs:GetQueueUrl",
+ "sqs:SendMessage"
+ ],
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket12520700A",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Fn::GetAtt": [
+ "MyQueueE6CA6235",
+ "Arn"
+ ]
+ }
+ },
+ {
+ "Action": [
+ "sqs:GetQueueAttributes",
+ "sqs:GetQueueUrl",
+ "sqs:SendMessage"
+ ],
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket25524B414",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Fn::GetAtt": [
+ "MyQueueE6CA6235",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "Queues": [
+ {
+ "Ref": "MyQueueE6CA6235"
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "s3:PutBucketNotification",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "Roles": [
+ {
+ "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ]
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
+ "Code": {
+ "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nEVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n external_notifications = find_external_notifications(bucket, stack_id)\n\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n\n if EVENTBRIDGE_CONFIGURATION in notification_configuration:\n notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]\n elif EVENTBRIDGE_CONFIGURATION in external_notifications:\n notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return notifications\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n if EVENTBRIDGE_CONFIGURATION in existing_notifications:\n external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return external_notifications\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
+ },
+ "Handler": "index.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC",
+ "Arn"
+ ]
+ },
+ "Runtime": "python3.7",
+ "Timeout": 300
+ },
+ "DependsOn": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ ]
+ },
+ "Bucket25524B414": {
+ "Type": "AWS::S3::Bucket",
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "Bucket2NotificationsD9BA2A77": {
+ "Type": "Custom::S3BucketNotifications",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
+ "Arn"
+ ]
+ },
+ "BucketName": {
+ "Ref": "Bucket25524B414"
+ },
+ "NotificationConfiguration": {
+ "QueueConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectCreated:*"
+ ],
+ "Filter": {
+ "Key": {
+ "FilterRules": [
+ {
+ "Name": "suffix",
+ "Value": ".png"
+ }
+ ]
+ }
+ },
+ "QueueArn": {
+ "Fn::GetAtt": [
+ "MyQueueE6CA6235",
+ "Arn"
+ ]
+ }
+ }
+ ]
+ },
+ "Managed": true
+ },
+ "DependsOn": [
+ "MyQueuePolicy6BBEDDAC",
+ "MyQueueE6CA6235"
+ ]
+ },
+ "EncryptedQueueKey6F4FD304": {
+ "Type": "AWS::KMS::Key",
+ "Properties": {
+ "KeyPolicy": {
+ "Statement": [
+ {
+ "Action": "kms:*",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":root"
+ ]
+ ]
+ }
+ },
+ "Resource": "*"
+ },
+ {
+ "Action": [
+ "kms:Decrypt",
+ "kms:Encrypt",
+ "kms:GenerateDataKey*",
+ "kms:ReEncrypt*"
+ ],
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket12520700A",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": "*"
+ },
+ {
+ "Action": [
+ "kms:Decrypt",
+ "kms:GenerateDataKey*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "Description": "Created by sqs-bucket-notifications/EncryptedQueue"
+ },
+ "UpdateReplacePolicy": "Retain",
+ "DeletionPolicy": "Retain"
+ },
+ "EncryptedQueue0428C61A": {
+ "Type": "AWS::SQS::Queue",
+ "Properties": {
+ "KmsMasterKeyId": {
+ "Fn::GetAtt": [
+ "EncryptedQueueKey6F4FD304",
+ "Arn"
+ ]
+ }
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "EncryptedQueuePolicy8AEB1708": {
+ "Type": "AWS::SQS::QueuePolicy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "sqs:GetQueueAttributes",
+ "sqs:GetQueueUrl",
+ "sqs:SendMessage"
+ ],
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket12520700A",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Fn::GetAtt": [
+ "EncryptedQueue0428C61A",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "Queues": [
+ {
+ "Ref": "EncryptedQueue0428C61A"
+ }
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/tree.json b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/tree.json
new file mode 100644
index 0000000000000..528c8cf9c9015
--- /dev/null
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sqs/bucket-notifications.integ.snapshot/tree.json
@@ -0,0 +1,501 @@
+{
+ "version": "tree-0.1",
+ "tree": {
+ "id": "App",
+ "path": "",
+ "children": {
+ "Tree": {
+ "id": "Tree",
+ "path": "Tree",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "sqs-bucket-notifications": {
+ "id": "sqs-bucket-notifications",
+ "path": "sqs-bucket-notifications",
+ "children": {
+ "Bucket1": {
+ "id": "Bucket1",
+ "path": "sqs-bucket-notifications/Bucket1",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/Bucket1/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::Bucket",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Notifications": {
+ "id": "Notifications",
+ "path": "sqs-bucket-notifications/Bucket1/Notifications",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/Bucket1/Notifications/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "MyQueue": {
+ "id": "MyQueue",
+ "path": "sqs-bucket-notifications/MyQueue",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/MyQueue/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SQS::Queue",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sqs.CfnQueue",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "sqs-bucket-notifications/MyQueue/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/MyQueue/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SQS::QueuePolicy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "sqs:GetQueueAttributes",
+ "sqs:GetQueueUrl",
+ "sqs:SendMessage"
+ ],
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket12520700A",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Fn::GetAtt": [
+ "MyQueueE6CA6235",
+ "Arn"
+ ]
+ }
+ },
+ {
+ "Action": [
+ "sqs:GetQueueAttributes",
+ "sqs:GetQueueUrl",
+ "sqs:SendMessage"
+ ],
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket25524B414",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Fn::GetAtt": [
+ "MyQueueE6CA6235",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "queues": [
+ {
+ "Ref": "MyQueueE6CA6235"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sqs.CfnQueuePolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sqs.QueuePolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sqs.Queue",
+ "version": "0.0.0"
+ }
+ },
+ "BucketNotificationsHandler050a0587b7544547bf325f094a3db834": {
+ "id": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834",
+ "path": "sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834",
+ "children": {
+ "Role": {
+ "id": "Role",
+ "path": "sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnRole",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultPolicy": {
+ "id": "DefaultPolicy",
+ "path": "sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role/DefaultPolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "s3:PutBucketNotification",
+ "Effect": "Allow",
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
+ "roles": [
+ {
+ "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ },
+ "Bucket2": {
+ "id": "Bucket2",
+ "path": "sqs-bucket-notifications/Bucket2",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/Bucket2/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::S3::Bucket",
+ "aws:cdk:cloudformation:props": {}
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.CfnBucket",
+ "version": "0.0.0"
+ }
+ },
+ "Notifications": {
+ "id": "Notifications",
+ "path": "sqs-bucket-notifications/Bucket2/Notifications",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/Bucket2/Notifications/Resource",
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Construct",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-s3.Bucket",
+ "version": "0.0.0"
+ }
+ },
+ "EncryptedQueue": {
+ "id": "EncryptedQueue",
+ "path": "sqs-bucket-notifications/EncryptedQueue",
+ "children": {
+ "Key": {
+ "id": "Key",
+ "path": "sqs-bucket-notifications/EncryptedQueue/Key",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/EncryptedQueue/Key/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::KMS::Key",
+ "aws:cdk:cloudformation:props": {
+ "keyPolicy": {
+ "Statement": [
+ {
+ "Action": "kms:*",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":root"
+ ]
+ ]
+ }
+ },
+ "Resource": "*"
+ },
+ {
+ "Action": [
+ "kms:Decrypt",
+ "kms:Encrypt",
+ "kms:GenerateDataKey*",
+ "kms:ReEncrypt*"
+ ],
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket12520700A",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": "*"
+ },
+ {
+ "Action": [
+ "kms:Decrypt",
+ "kms:GenerateDataKey*"
+ ],
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": "*"
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "description": "Created by sqs-bucket-notifications/EncryptedQueue"
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-kms.CfnKey",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-kms.Key",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/EncryptedQueue/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SQS::Queue",
+ "aws:cdk:cloudformation:props": {
+ "kmsMasterKeyId": {
+ "Fn::GetAtt": [
+ "EncryptedQueueKey6F4FD304",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sqs.CfnQueue",
+ "version": "0.0.0"
+ }
+ },
+ "Policy": {
+ "id": "Policy",
+ "path": "sqs-bucket-notifications/EncryptedQueue/Policy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "sqs-bucket-notifications/EncryptedQueue/Policy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::SQS::QueuePolicy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "sqs:GetQueueAttributes",
+ "sqs:GetQueueUrl",
+ "sqs:SendMessage"
+ ],
+ "Condition": {
+ "ArnLike": {
+ "aws:SourceArn": {
+ "Fn::GetAtt": [
+ "Bucket12520700A",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "s3.amazonaws.com"
+ },
+ "Resource": {
+ "Fn::GetAtt": [
+ "EncryptedQueue0428C61A",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "queues": [
+ {
+ "Ref": "EncryptedQueue0428C61A"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sqs.CfnQueuePolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sqs.QueuePolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/aws-sqs.Queue",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.Stack",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/core.App",
+ "version": "0.0.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.expected.json b/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.expected.json
index de109b272d9bb..1421e22410918 100644
--- a/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.expected.json
+++ b/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.expected.json
@@ -184,7 +184,7 @@
"Properties": {
"Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
"Code": {
- "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n\n # find external notifications\n external_notifications = find_external_notifications(bucket, stack_id)\n\n # if delete, that's all we need\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n # otherwise, merge external with incoming config and augment with id\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n return notifications\n\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n # if the notification was created by us, we know what id to expect\n # so we can filter by it.\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n return external_notifications\n\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
+ "ZipFile": "import boto3 # type: ignore\nimport json\nimport logging\nimport urllib.request\n\ns3 = boto3.client(\"s3\")\n\nEVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'\n\nCONFIGURATION_TYPES = [\"TopicConfigurations\", \"QueueConfigurations\", \"LambdaFunctionConfigurations\"]\n\ndef handler(event: dict, context):\n response_status = \"SUCCESS\"\n error_message = \"\"\n try:\n props = event[\"ResourceProperties\"]\n bucket = props[\"BucketName\"]\n notification_configuration = props[\"NotificationConfiguration\"]\n request_type = event[\"RequestType\"]\n managed = props.get('Managed', 'true').lower() == 'true'\n stack_id = event['StackId']\n\n if managed:\n config = handle_managed(request_type, notification_configuration)\n else:\n config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)\n\n put_bucket_notification_configuration(bucket, config)\n except Exception as e:\n logging.exception(\"Failed to put bucket notification configuration\")\n response_status = \"FAILED\"\n error_message = f\"Error: {str(e)}. \"\n finally:\n submit_response(event, context, response_status, error_message)\n\ndef handle_managed(request_type, notification_configuration):\n if request_type == 'Delete':\n return {}\n return notification_configuration\n\ndef handle_unmanaged(bucket, stack_id, request_type, notification_configuration):\n external_notifications = find_external_notifications(bucket, stack_id)\n\n if request_type == 'Delete':\n return external_notifications\n\n def with_id(notification):\n notification['Id'] = f\"{stack_id}-{hash(json.dumps(notification, sort_keys=True))}\"\n return notification\n\n notifications = {}\n for t in CONFIGURATION_TYPES:\n external = external_notifications.get(t, [])\n incoming = [with_id(n) for n in notification_configuration.get(t, [])]\n notifications[t] = external + incoming\n\n if EVENTBRIDGE_CONFIGURATION in notification_configuration:\n notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]\n elif EVENTBRIDGE_CONFIGURATION in external_notifications:\n notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return notifications\n\ndef find_external_notifications(bucket, stack_id):\n existing_notifications = get_bucket_notification_configuration(bucket)\n external_notifications = {}\n for t in CONFIGURATION_TYPES:\n external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f\"{stack_id}-\")]\n\n if EVENTBRIDGE_CONFIGURATION in existing_notifications:\n external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]\n\n return external_notifications\n\ndef get_bucket_notification_configuration(bucket):\n return s3.get_bucket_notification_configuration(Bucket=bucket)\n\ndef put_bucket_notification_configuration(bucket, notification_configuration):\n s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)\n\ndef submit_response(event: dict, context, response_status: str, error_message: str):\n response_body = json.dumps(\n {\n \"Status\": response_status,\n \"Reason\": f\"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}\",\n \"PhysicalResourceId\": event.get(\"PhysicalResourceId\") or event[\"LogicalResourceId\"],\n \"StackId\": event[\"StackId\"],\n \"RequestId\": event[\"RequestId\"],\n \"LogicalResourceId\": event[\"LogicalResourceId\"],\n \"NoEcho\": False,\n }\n ).encode(\"utf-8\")\n headers = {\"content-type\": \"\", \"content-length\": str(len(response_body))}\n try:\n req = urllib.request.Request(url=event[\"ResponseURL\"], headers=headers, data=response_body, method=\"PUT\")\n with urllib.request.urlopen(req) as response:\n print(response.read().decode(\"utf-8\"))\n print(\"Status code: \" + response.reason)\n except Exception as e:\n print(\"send(..) failed executing request.urlopen(..): \" + str(e))\n"
},
"Handler": "index.handler",
"Role": {
@@ -376,4 +376,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/@aws-cdk/aws-s3/.gitignore b/packages/@aws-cdk/aws-s3/.gitignore
index 17a41566f0002..691432920bfe5 100644
--- a/packages/@aws-cdk/aws-s3/.gitignore
+++ b/packages/@aws-cdk/aws-s3/.gitignore
@@ -16,4 +16,8 @@ nyc.config.js
!.eslintrc.js
junit.xml
-!jest.config.js
\ No newline at end of file
+!jest.config.js
+!**/*.integ.snapshot/**/asset.*/*.js
+!**/*.integ.snapshot/**/asset.*/*.d.ts
+
+!**/*.integ.snapshot/**/asset.*/**
diff --git a/packages/@aws-cdk/aws-s3/.npmignore b/packages/@aws-cdk/aws-s3/.npmignore
index 52ca12195912c..3ca26867c3157 100644
--- a/packages/@aws-cdk/aws-s3/.npmignore
+++ b/packages/@aws-cdk/aws-s3/.npmignore
@@ -25,4 +25,6 @@ tsconfig.json
junit.xml
test/
jest.config.js
-!*.lit.ts
\ No newline at end of file
+!*.lit.ts
+**/*.integ.snapshot
+**/*.integ.snapshot
diff --git a/packages/@aws-cdk/aws-s3/README.md b/packages/@aws-cdk/aws-s3/README.md
index 47138a3d30ec6..26a62df2d9f41 100644
--- a/packages/@aws-cdk/aws-s3/README.md
+++ b/packages/@aws-cdk/aws-s3/README.md
@@ -279,6 +279,21 @@ const importedRole = iam.Role.fromRoleArn(this, 'role', 'arn:aws:iam::1234567890
[S3 Bucket Notifications]: https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html
+### EventBridge notifications
+
+Amazon S3 can send events to Amazon EventBridge whenever certain events happen in your bucket.
+Unlike other destinations, you don't need to select which event types you want to deliver.
+
+The following example will enable EventBridge notifications:
+
+```ts
+const bucket = new s3.Bucket(this, 'MyEventBridgeBucket', {
+ eventBridgeEnabled: true,
+});
+```
+
+[S3 EventBridge notifications]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventBridge.html
+
## Block Public Access
Use `blockPublicAccess` to specify [block public access settings] on the bucket.
diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts
index 321f65603c14c..4b299a1749f70 100644
--- a/packages/@aws-cdk/aws-s3/lib/bucket.ts
+++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts
@@ -878,6 +878,10 @@ export abstract class BucketBase extends Resource implements IBucket {
return this.addEventNotification(EventType.OBJECT_REMOVED, dest, ...filters);
}
+ protected enableEventBridgeNotification() {
+ this.withNotifications(notifications => notifications.enableEventBridgeNotification());
+ }
+
private get writeActions(): string[] {
return [
...perms.BUCKET_DELETE_ACTIONS,
@@ -1354,6 +1358,13 @@ export interface BucketProps {
*/
readonly versioned?: boolean;
+ /**
+ * Whether this bucket should send notifications to Amazon EventBridge or not.
+ *
+ * @default false
+ */
+ readonly eventBridgeEnabled?: boolean;
+
/**
* Rules that define how Amazon S3 manages objects during their lifetime.
*
@@ -1642,6 +1653,7 @@ export class Bucket extends BucketBase {
private accessControl?: BucketAccessControl;
private readonly lifecycleRules: LifecycleRule[] = [];
private readonly versioned?: boolean;
+ private readonly eventBridgeEnabled?: boolean;
private readonly metrics: BucketMetrics[] = [];
private readonly cors: CorsRule[] = [];
private readonly inventories: Inventory[] = [];
@@ -1683,6 +1695,7 @@ export class Bucket extends BucketBase {
this.versioned = props.versioned;
this.encryptionKey = encryptionKey;
+ this.eventBridgeEnabled = props.eventBridgeEnabled;
this.bucketName = this.getResourceNameAttribute(resource.ref);
this.bucketArn = this.getResourceArnAttribute(resource.attrArn, {
@@ -1733,6 +1746,10 @@ export class Bucket extends BucketBase {
this.enableAutoDeleteObjects();
}
+
+ if (this.eventBridgeEnabled) {
+ this.enableEventBridgeNotification();
+ }
}
/**
diff --git a/packages/@aws-cdk/aws-s3/lib/notifications-resource/lambda/index.py b/packages/@aws-cdk/aws-s3/lib/notifications-resource/lambda/index.py
index 2551398d74958..12d584c290cc1 100644
--- a/packages/@aws-cdk/aws-s3/lib/notifications-resource/lambda/index.py
+++ b/packages/@aws-cdk/aws-s3/lib/notifications-resource/lambda/index.py
@@ -5,41 +5,40 @@
s3 = boto3.client("s3")
+EVENTBRIDGE_CONFIGURATION = 'EventBridgeConfiguration'
+
CONFIGURATION_TYPES = ["TopicConfigurations", "QueueConfigurations", "LambdaFunctionConfigurations"]
def handler(event: dict, context):
- response_status = "SUCCESS"
- error_message = ""
- try:
- props = event["ResourceProperties"]
- bucket = props["BucketName"]
- notification_configuration = props["NotificationConfiguration"]
- request_type = event["RequestType"]
- managed = props.get('Managed', 'true').lower() == 'true'
- stack_id = event['StackId']
-
- if managed:
- config = handle_managed(request_type, notification_configuration)
- else:
- config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)
-
- put_bucket_notification_configuration(bucket, config)
- except Exception as e:
- logging.exception("Failed to put bucket notification configuration")
- response_status = "FAILED"
- error_message = f"Error: {str(e)}. "
- finally:
- submit_response(event, context, response_status, error_message)
-
+ response_status = "SUCCESS"
+ error_message = ""
+ try:
+ props = event["ResourceProperties"]
+ bucket = props["BucketName"]
+ notification_configuration = props["NotificationConfiguration"]
+ request_type = event["RequestType"]
+ managed = props.get('Managed', 'true').lower() == 'true'
+ stack_id = event['StackId']
+
+ if managed:
+ config = handle_managed(request_type, notification_configuration)
+ else:
+ config = handle_unmanaged(bucket, stack_id, request_type, notification_configuration)
+
+ put_bucket_notification_configuration(bucket, config)
+ except Exception as e:
+ logging.exception("Failed to put bucket notification configuration")
+ response_status = "FAILED"
+ error_message = f"Error: {str(e)}. "
+ finally:
+ submit_response(event, context, response_status, error_message)
def handle_managed(request_type, notification_configuration):
if request_type == 'Delete':
return {}
return notification_configuration
-
def handle_unmanaged(bucket, stack_id, request_type, notification_configuration):
-
# find external notifications
external_notifications = find_external_notifications(bucket, stack_id)
@@ -57,8 +56,14 @@ def with_id(notification):
external = external_notifications.get(t, [])
incoming = [with_id(n) for n in notification_configuration.get(t, [])]
notifications[t] = external + incoming
- return notifications
+ # EventBridge configuration is a special case because it's just an empty object if it exists
+ if EVENTBRIDGE_CONFIGURATION in notification_configuration:
+ notifications[EVENTBRIDGE_CONFIGURATION] = notification_configuration[EVENTBRIDGE_CONFIGURATION]
+ elif EVENTBRIDGE_CONFIGURATION in external_notifications:
+ notifications[EVENTBRIDGE_CONFIGURATION] = external_notifications[EVENTBRIDGE_CONFIGURATION]
+
+ return notifications
def find_external_notifications(bucket, stack_id):
existing_notifications = get_bucket_notification_configuration(bucket)
@@ -68,34 +73,36 @@ def find_external_notifications(bucket, stack_id):
# so we can filter by it.
external_notifications[t] = [n for n in existing_notifications.get(t, []) if not n['Id'].startswith(f"{stack_id}-")]
- return external_notifications
+ # always treat EventBridge configuration as an external config if it already exists
+ # as there is no way to determine whether it's managed by us or not
+ if EVENTBRIDGE_CONFIGURATION in existing_notifications:
+ external_notifications[EVENTBRIDGE_CONFIGURATION] = existing_notifications[EVENTBRIDGE_CONFIGURATION]
+ return external_notifications
def get_bucket_notification_configuration(bucket):
return s3.get_bucket_notification_configuration(Bucket=bucket)
-
def put_bucket_notification_configuration(bucket, notification_configuration):
s3.put_bucket_notification_configuration(Bucket=bucket, NotificationConfiguration=notification_configuration)
-
def submit_response(event: dict, context, response_status: str, error_message: str):
- response_body = json.dumps(
- {
- "Status": response_status,
- "Reason": f"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}",
- "PhysicalResourceId": event.get("PhysicalResourceId") or event["LogicalResourceId"],
- "StackId": event["StackId"],
- "RequestId": event["RequestId"],
- "LogicalResourceId": event["LogicalResourceId"],
- "NoEcho": False,
- }
- ).encode("utf-8")
- headers = {"content-type": "", "content-length": str(len(response_body))}
- try:
- req = urllib.request.Request(url=event["ResponseURL"], headers=headers, data=response_body, method="PUT")
- with urllib.request.urlopen(req) as response:
- print(response.read().decode("utf-8"))
- print("Status code: " + response.reason)
- except Exception as e:
- print("send(..) failed executing request.urlopen(..): " + str(e))
+ response_body = json.dumps(
+ {
+ "Status": response_status,
+ "Reason": f"{error_message}See the details in CloudWatch Log Stream: {context.log_stream_name}",
+ "PhysicalResourceId": event.get("PhysicalResourceId") or event["LogicalResourceId"],
+ "StackId": event["StackId"],
+ "RequestId": event["RequestId"],
+ "LogicalResourceId": event["LogicalResourceId"],
+ "NoEcho": False,
+ }
+ ).encode("utf-8")
+ headers = {"content-type": "", "content-length": str(len(response_body))}
+ try:
+ req = urllib.request.Request(url=event["ResponseURL"], headers=headers, data=response_body, method="PUT")
+ with urllib.request.urlopen(req) as response:
+ print(response.read().decode("utf-8"))
+ print("Status code: " + response.reason)
+ except Exception as e:
+ print("send(..) failed executing request.urlopen(..): " + str(e))
diff --git a/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource-handler.ts b/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource-handler.ts
index 76edb141a3cd0..a6ea51209bc83 100644
--- a/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource-handler.ts
+++ b/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource-handler.ts
@@ -86,15 +86,19 @@ export class NotificationsResourceHandler extends Construct {
}
const handlerSource = fs.readFileSync(path.join(__dirname, 'lambda/index.py'), 'utf8');
- if (handlerSource.length > 4096) {
- throw new Error(`Source of Notifications Resource Handler is too large (${handlerSource.length} > 4096)`);
+
+ // Removing lines that starts with '#' (comment lines) in order to fit the 4096 limit
+ const handlerSourceWithoutComments = handlerSource.replace(/^ *#.*\n?/gm, '');
+
+ if (handlerSourceWithoutComments.length > 4096) {
+ throw new Error(`Source of Notifications Resource Handler is too large (${handlerSourceWithoutComments.length} > 4096)`);
}
const resource = new InLineLambda(this, 'Resource', {
type: resourceType,
properties: {
Description: 'AWS CloudFormation handler for "Custom::S3BucketNotifications" resources (@aws-cdk/aws-s3)',
- Code: { ZipFile: handlerSource },
+ Code: { ZipFile: handlerSourceWithoutComments },
Handler: 'index.handler',
Role: this.role.roleArn,
Runtime: 'python3.7',
diff --git a/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource.ts b/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource.ts
index 6bc50ec5b6064..6b1b240b776a0 100644
--- a/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource.ts
+++ b/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource.ts
@@ -36,6 +36,7 @@ interface NotificationsProps {
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-notificationconfig.html
*/
export class BucketNotifications extends Construct {
+ private eventBridgeEnabled = false;
private readonly lambdaNotifications = new ArrayAutomatedUpdateDate
and when the UpdateStatus
is in the PENDING_UPDATE
state. DomainName
to see which limits you can modify. DomainName
to get all upgrade-compatible versions of OpenSearch/Elasticsearch for that specific domain. AcceptInboundConnection
operation. InboundConnection
of the accepted inbound connection. AcceptInboundConnection
operation. Contains details about the accepted inbound connection. OptionStatus
for the status information that's included. ARN
of the domain you want to add tags to. Tag
to add to the domain. AddTags
operation. Specifies the tags to attach to the domain. InstanceRole
etc.
Attributes and their details:
ESPartitionInstanceType
can support as master node. ESPartitionInstanceType
up to which you don't need any master nodes to govern them.
Value for a given AdditionalLimit$LimitName
.
List of limits that are specific to a given InstanceType and for each of its InstanceRole
.
Exposes select native OpenSearch configuration values from opensearch.yml
. Currently, the following advanced options are available:
false
when configuring access to individual sub-resources. By default, the value is true
. See Advanced cluster parameters for more information. For more information, see Advanced cluster parameters.
" - }, - "AdvancedOptionsStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"AdvancedOptions", - "documentation":"The status of advanced options for the specified domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The OptionStatus
for advanced options for the specified domain.
Status of the advanced options for the specified domain. Currently, the following advanced options are available:
false
when configuring access to individual sub-resources. By default, the value is true
. See Advanced cluster parameters for more information. For more information, see Advanced cluster parameters.
" - }, - "AdvancedSecurityOptions":{ - "type":"structure", - "members":{ - "Enabled":{ - "shape":"Boolean", - "documentation":"True if advanced security is enabled.
" - }, - "InternalUserDatabaseEnabled":{ - "shape":"Boolean", - "documentation":"True if the internal user database is enabled.
" - }, - "SAMLOptions":{ - "shape":"SAMLOptionsOutput", - "documentation":"Describes the SAML application configured for a domain.
" - } - }, - "documentation":"The advanced security configuration: whether advanced security is enabled, whether the internal database option is enabled.
" - }, - "AdvancedSecurityOptionsInput":{ - "type":"structure", - "members":{ - "Enabled":{ - "shape":"Boolean", - "documentation":"True if advanced security is enabled.
" - }, - "InternalUserDatabaseEnabled":{ - "shape":"Boolean", - "documentation":"True if the internal user database is enabled.
" - }, - "MasterUserOptions":{ - "shape":"MasterUserOptions", - "documentation":"Credentials for the master user: username and password, ARN, or both.
" - }, - "SAMLOptions":{ - "shape":"SAMLOptionsInput", - "documentation":"The SAML application configuration for the domain.
" - } - }, - "documentation":"The advanced security configuration: whether advanced security is enabled, whether the internal database option is enabled, master username and password (if internal database is enabled), and master user ARN (if IAM is enabled).
" - }, - "AdvancedSecurityOptionsStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"AdvancedSecurityOptions", - "documentation":"Advanced security options for the specified domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"Status of the advanced security options for the specified domain.
" - } - }, - "documentation":"The status of advanced security options for the specified domain.
" - }, - "AssociatePackageRequest":{ - "type":"structure", - "required":[ - "PackageID", - "DomainName" - ], - "members":{ - "PackageID":{ - "shape":"PackageID", - "documentation":"Internal ID of the package to associate with a domain. Use DescribePackages
to find this value.
The name of the domain to associate the package with.
", - "location":"uri", - "locationName":"DomainName" - } - }, - "documentation":" Container for the request parameters to the AssociatePackage
operation.
DomainPackageDetails
Container for the response returned by AssociatePackage
operation.
Specifies the Auto-Tune type. Valid value is SCHEDULED_ACTION.
" - }, - "AutoTuneDetails":{ - "shape":"AutoTuneDetails", - "documentation":"Specifies details about the Auto-Tune action. See Auto-Tune for Amazon OpenSearch Service for more information.
" - } - }, - "documentation":"Specifies the Auto-Tune type and Auto-Tune action details.
" - }, - "AutoTuneDate":{ - "type":"timestamp", - "documentation":"The timestamp of the Auto-Tune action scheduled for the domain.
" - }, - "AutoTuneDesiredState":{ - "type":"string", - "documentation":"The Auto-Tune desired state. Valid values are ENABLED and DISABLED.
", - "enum":[ - "ENABLED", - "DISABLED" - ] - }, - "AutoTuneDetails":{ - "type":"structure", - "members":{ - "ScheduledAutoTuneDetails":{"shape":"ScheduledAutoTuneDetails"} - }, - "documentation":"Specifies details about the Auto-Tune action. See Auto-Tune for Amazon OpenSearch Service for more information.
" - }, - "AutoTuneList":{ - "type":"list", - "member":{"shape":"AutoTune"} - }, - "AutoTuneMaintenanceSchedule":{ - "type":"structure", - "members":{ - "StartAt":{ - "shape":"StartAt", - "documentation":"The timestamp at which the Auto-Tune maintenance schedule starts.
" - }, - "Duration":{ - "shape":"Duration", - "documentation":"Specifies maintenance schedule duration: duration value and duration unit. See Auto-Tune for Amazon OpenSearch Service for more information.
" - }, - "CronExpressionForRecurrence":{ - "shape":"String", - "documentation":"A cron expression for a recurring maintenance schedule. See Auto-Tune for Amazon OpenSearch Service for more information.
" - } - }, - "documentation":"Specifies the Auto-Tune maintenance schedule. See Auto-Tune for Amazon OpenSearch Service for more information.
" - }, - "AutoTuneMaintenanceScheduleList":{ - "type":"list", - "member":{"shape":"AutoTuneMaintenanceSchedule"}, - "max":100 - }, - "AutoTuneOptions":{ - "type":"structure", - "members":{ - "DesiredState":{ - "shape":"AutoTuneDesiredState", - "documentation":"The Auto-Tune desired state. Valid values are ENABLED and DISABLED.
" - }, - "RollbackOnDisable":{ - "shape":"RollbackOnDisable", - "documentation":"The rollback state while disabling Auto-Tune for the domain. Valid values are NO_ROLLBACK and DEFAULT_ROLLBACK.
" - }, - "MaintenanceSchedules":{ - "shape":"AutoTuneMaintenanceScheduleList", - "documentation":"A list of maintenance schedules. See Auto-Tune for Amazon OpenSearch Service for more information.
" - } - }, - "documentation":"The Auto-Tune options: the Auto-Tune desired state for the domain, rollback state when disabling Auto-Tune options and list of maintenance schedules.
" - }, - "AutoTuneOptionsInput":{ - "type":"structure", - "members":{ - "DesiredState":{ - "shape":"AutoTuneDesiredState", - "documentation":"The Auto-Tune desired state. Valid values are ENABLED and DISABLED.
" - }, - "MaintenanceSchedules":{ - "shape":"AutoTuneMaintenanceScheduleList", - "documentation":"A list of maintenance schedules. See Auto-Tune for Amazon OpenSearch Service for more information.
" - } - }, - "documentation":"The Auto-Tune options: the Auto-Tune desired state for the domain and list of maintenance schedules.
" - }, - "AutoTuneOptionsOutput":{ - "type":"structure", - "members":{ - "State":{ - "shape":"AutoTuneState", - "documentation":"The AutoTuneState
for the domain.
The error message while enabling or disabling Auto-Tune.
" - } - }, - "documentation":"The Auto-Tune options: the Auto-Tune desired state for the domain and list of maintenance schedules.
" - }, - "AutoTuneOptionsStatus":{ - "type":"structure", - "members":{ - "Options":{ - "shape":"AutoTuneOptions", - "documentation":"Specifies Auto-Tune options for the domain.
" - }, - "Status":{ - "shape":"AutoTuneStatus", - "documentation":"The status of the Auto-Tune options for the domain.
" - } - }, - "documentation":"The Auto-Tune status for the domain.
" - }, - "AutoTuneState":{ - "type":"string", - "documentation":"The Auto-Tune state for the domain. For valid states see Auto-Tune for Amazon OpenSearch Service.
", - "enum":[ - "ENABLED", - "DISABLED", - "ENABLE_IN_PROGRESS", - "DISABLE_IN_PROGRESS", - "DISABLED_AND_ROLLBACK_SCHEDULED", - "DISABLED_AND_ROLLBACK_IN_PROGRESS", - "DISABLED_AND_ROLLBACK_COMPLETE", - "DISABLED_AND_ROLLBACK_ERROR", - "ERROR" - ] - }, - "AutoTuneStatus":{ - "type":"structure", - "required":[ - "CreationDate", - "UpdateDate", - "State" - ], - "members":{ - "CreationDate":{ - "shape":"UpdateTimestamp", - "documentation":"The timestamp of the Auto-Tune options creation date.
" - }, - "UpdateDate":{ - "shape":"UpdateTimestamp", - "documentation":"The timestamp of when the Auto-Tune options were last updated.
" - }, - "UpdateVersion":{ - "shape":"UIntValue", - "documentation":"The latest version of the Auto-Tune options.
" - }, - "State":{ - "shape":"AutoTuneState", - "documentation":"The AutoTuneState
for the domain.
The error message while enabling or disabling Auto-Tune.
" - }, - "PendingDeletion":{ - "shape":"Boolean", - "documentation":"Indicates whether the domain is being deleted.
" - } - }, - "documentation":"Provides the current Auto-Tune status for the domain.
" - }, - "AutoTuneType":{ - "type":"string", - "documentation":"Specifies the Auto-Tune type. Valid value is SCHEDULED_ACTION.
", - "enum":["SCHEDULED_ACTION"] - }, - "BackendRole":{ - "type":"string", - "max":256, - "min":1 - }, - "Boolean":{"type":"boolean"}, - "CancelServiceSoftwareUpdateRequest":{ - "type":"structure", - "required":["DomainName"], - "members":{ - "DomainName":{ - "shape":"DomainName", - "documentation":"The name of the domain that you want to stop the latest service software update on.
" - } - }, - "documentation":"Container for the parameters to the CancelServiceSoftwareUpdate
operation. Specifies the name of the domain that you wish to cancel a service software update on.
The current status of the OpenSearch service software update.
" - } - }, - "documentation":"The result of a CancelServiceSoftwareUpdate
operation. Contains the status of the update.
ARN of the Cloudwatch log group to publish logs to.
", - "max":2048, - "min":20, - "pattern":".*" - }, - "ClusterConfig":{ - "type":"structure", - "members":{ - "InstanceType":{ - "shape":"OpenSearchPartitionInstanceType", - "documentation":"The instance type for an OpenSearch cluster. UltraWarm instance types are not supported for data instances.
" - }, - "InstanceCount":{ - "shape":"IntegerClass", - "documentation":"The number of instances in the specified domain cluster.
" - }, - "DedicatedMasterEnabled":{ - "shape":"Boolean", - "documentation":"A boolean value to indicate whether a dedicated master node is enabled. See Dedicated master nodes in Amazon OpenSearch Service for more information.
" - }, - "ZoneAwarenessEnabled":{ - "shape":"Boolean", - "documentation":"A boolean value to indicate whether zone awareness is enabled. See Configuring a multi-AZ domain in Amazon OpenSearch Service for more information.
" - }, - "ZoneAwarenessConfig":{ - "shape":"ZoneAwarenessConfig", - "documentation":"The zone awareness configuration for a domain when zone awareness is enabled.
" - }, - "DedicatedMasterType":{ - "shape":"OpenSearchPartitionInstanceType", - "documentation":"The instance type for a dedicated master node.
" - }, - "DedicatedMasterCount":{ - "shape":"IntegerClass", - "documentation":"Total number of dedicated master nodes, active and on standby, for the cluster.
" - }, - "WarmEnabled":{ - "shape":"Boolean", - "documentation":"True to enable UltraWarm storage.
" - }, - "WarmType":{ - "shape":"OpenSearchWarmPartitionInstanceType", - "documentation":"The instance type for the OpenSearch cluster's warm nodes.
" - }, - "WarmCount":{ - "shape":"IntegerClass", - "documentation":"The number of UltraWarm nodes in the cluster.
" - }, - "ColdStorageOptions":{"shape":"ColdStorageOptions"} - }, - "documentation":"The configuration for the domain cluster, such as the type and number of instances.
" - }, - "ClusterConfigStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"ClusterConfig", - "documentation":"The cluster configuration for the specified domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The cluster configuration status for the specified domain.
" - } - }, - "documentation":"The configuration status for the specified domain.
" - }, - "CognitoOptions":{ - "type":"structure", - "members":{ - "Enabled":{ - "shape":"Boolean", - "documentation":"The option to enable Cognito for OpenSearch Dashboards authentication.
" - }, - "UserPoolId":{ - "shape":"UserPoolId", - "documentation":"The Cognito user pool ID for OpenSearch Dashboards authentication.
" - }, - "IdentityPoolId":{ - "shape":"IdentityPoolId", - "documentation":"The Cognito identity pool ID for OpenSearch Dashboards authentication.
" - }, - "RoleArn":{ - "shape":"RoleArn", - "documentation":"The role ARN that provides OpenSearch permissions for accessing Cognito resources.
" - } - }, - "documentation":"Options to specify the Cognito user and identity pools for OpenSearch Dashboards authentication. For more information, see Configuring Amazon Cognito authentication for OpenSearch Dashboards.
" - }, - "CognitoOptionsStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"CognitoOptions", - "documentation":"Cognito options for the specified domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of the Cognito options for the specified domain.
" - } - }, - "documentation":"The status of the Cognito options for the specified domain.
" - }, - "ColdStorageOptions":{ - "type":"structure", - "required":["Enabled"], - "members":{ - "Enabled":{"shape":"Boolean"} - } - }, - "CommitMessage":{ - "type":"string", - "max":160 - }, - "CompatibleVersionsList":{ - "type":"list", - "member":{"shape":"CompatibleVersionsMap"} - }, - "CompatibleVersionsMap":{ - "type":"structure", - "members":{ - "SourceVersion":{ - "shape":"VersionString", - "documentation":"The current version of OpenSearch a domain is on.
" - }, - "TargetVersions":{"shape":"VersionList"} - }, - "documentation":" A map from an EngineVersion
to a list of compatible EngineVersion
s to which the domain can be upgraded.
The name of the Amazon OpenSearch Service domain you're creating. Domain names are unique across the domains owned by an account within an AWS region. Domain names must start with a lowercase letter and can contain the following characters: a-z (lowercase), 0-9, and - (hyphen).
" - }, - "EngineVersion":{ - "shape":"VersionString", - "documentation":"String of format Elasticsearch_X.Y or OpenSearch_X.Y to specify the engine version for the Amazon OpenSearch Service domain. For example, \"OpenSearch_1.0\" or \"Elasticsearch_7.9\". For more information, see Creating and managing Amazon OpenSearch Service domains .
" - }, - "ClusterConfig":{ - "shape":"ClusterConfig", - "documentation":"Configuration options for a domain. Specifies the instance type and number of instances in the domain.
" - }, - "EBSOptions":{ - "shape":"EBSOptions", - "documentation":"Options to enable, disable, and specify the type and size of EBS storage volumes.
" - }, - "AccessPolicies":{ - "shape":"PolicyDocument", - "documentation":"IAM access policy as a JSON-formatted string.
" - }, - "SnapshotOptions":{ - "shape":"SnapshotOptions", - "documentation":"Option to set time, in UTC format, of the daily automated snapshot. Default value is 0 hours.
" - }, - "VPCOptions":{ - "shape":"VPCOptions", - "documentation":"Options to specify the subnets and security groups for a VPC endpoint. For more information, see Launching your Amazon OpenSearch Service domains using a VPC .
" - }, - "CognitoOptions":{ - "shape":"CognitoOptions", - "documentation":"Options to specify the Cognito user and identity pools for OpenSearch Dashboards authentication. For more information, see Configuring Amazon Cognito authentication for OpenSearch Dashboards.
" - }, - "EncryptionAtRestOptions":{ - "shape":"EncryptionAtRestOptions", - "documentation":"Options for encryption of data at rest.
" - }, - "NodeToNodeEncryptionOptions":{ - "shape":"NodeToNodeEncryptionOptions", - "documentation":"Node-to-node encryption options.
" - }, - "AdvancedOptions":{ - "shape":"AdvancedOptions", - "documentation":"Option to allow references to indices in an HTTP request body. Must be false
when configuring access to individual sub-resources. By default, the value is true
. See Advanced cluster parameters for more information.
Map of LogType
and LogPublishingOption
, each containing options to publish a given type of OpenSearch log.
Options to specify configurations that will be applied to the domain endpoint.
" - }, - "AdvancedSecurityOptions":{ - "shape":"AdvancedSecurityOptionsInput", - "documentation":"Specifies advanced security options.
" - }, - "TagList":{ - "shape":"TagList", - "documentation":"A list of Tag
added during domain creation.
Specifies Auto-Tune options.
" - } - } - }, - "CreateDomainResponse":{ - "type":"structure", - "members":{ - "DomainStatus":{ - "shape":"DomainStatus", - "documentation":"The status of the newly created domain.
" - } - }, - "documentation":"The result of a CreateDomain
operation. Contains the status of the newly created Amazon OpenSearch Service domain.
The AWSDomainInformation
for the local OpenSearch domain.
The AWSDomainInformation
for the remote OpenSearch domain.
The connection alias used used by the customer for this cross-cluster connection.
" - } - }, - "documentation":"Container for the parameters to the CreateOutboundConnection
operation.
The AWSDomainInformation
for the local OpenSearch domain.
The AWSDomainInformation
for the remote OpenSearch domain.
The connection alias provided during the create connection request.
" - }, - "ConnectionStatus":{ - "shape":"OutboundConnectionStatus", - "documentation":"The OutboundConnectionStatus
for the newly created connection.
The unique ID for the created outbound connection, which is used for subsequent operations on the connection.
" - } - }, - "documentation":"The result of a CreateOutboundConnection
request. Contains the details about the newly created cross-cluster connection.
Unique identifier for the package.
" - }, - "PackageType":{ - "shape":"PackageType", - "documentation":"Type of package. Currently supports only TXT-DICTIONARY.
" - }, - "PackageDescription":{ - "shape":"PackageDescription", - "documentation":"Description of the package.
" - }, - "PackageSource":{ - "shape":"PackageSource", - "documentation":"The Amazon S3 location from which to import the package.
" - } - }, - "documentation":" Container for request parameters to the CreatePackage
operation.
Information about the package.
" - } - }, - "documentation":" Container for the response returned by the CreatePackage
operation.
The name of the domain you want to permanently delete.
", - "location":"uri", - "locationName":"DomainName" - } - }, - "documentation":"Container for the parameters to the DeleteDomain
operation. Specifies the name of the domain you want to delete.
The status of the domain being deleted.
" - } - }, - "documentation":"The result of a DeleteDomain
request. Contains the status of the pending deletion, or a \"domain not found\" error if the domain and all of its resources have been deleted.
The ID of the inbound connection to permanently delete.
", - "location":"uri", - "locationName":"ConnectionId" - } - }, - "documentation":"Container for the parameters to the DeleteInboundConnection
operation.
The InboundConnection
of the deleted inbound connection.
The result of a DeleteInboundConnection
operation. Contains details about the deleted inbound connection.
The ID of the outbound connection you want to permanently delete.
", - "location":"uri", - "locationName":"ConnectionId" - } - }, - "documentation":"Container for the parameters to the DeleteOutboundConnection
operation.
The OutboundConnection
of the deleted outbound connection.
The result of a DeleteOutboundConnection
operation. Contains details about the deleted outbound connection.
The internal ID of the package you want to delete. Use DescribePackages
to find this value.
Container for the request parameters to the DeletePackage
operation.
PackageDetails
Container for the response parameters to the DeletePackage
operation.
The domain name for which you want Auto-Tune action details.
", - "location":"uri", - "locationName":"DomainName" - }, - "MaxResults":{ - "shape":"MaxResults", - "documentation":"Set this value to limit the number of results returned. If not specified, defaults to 100.
" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"NextToken is sent in case the earlier API call results contain the NextToken. Used for pagination.
" - } - }, - "documentation":"Container for the parameters to the DescribeDomainAutoTunes
operation.
The list of setting adjustments that Auto-Tune has made to the domain. See Auto-Tune for Amazon OpenSearch Service for more information.
" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"An identifier to allow retrieval of paginated results.
" - } - }, - "documentation":"The result of a DescribeDomainAutoTunes
request. See Auto-Tune for Amazon OpenSearch Service for more information.
The domain you want to get information about.
", - "location":"uri", - "locationName":"DomainName" - } - }, - "documentation":"Container for the parameters to the DescribeDomainConfig
operation. Specifies the domain name for which you want configuration information.
The configuration information of the domain requested in the DescribeDomainConfig
request.
The result of a DescribeDomainConfig
request. Contains the configuration information of the requested domain.
The name of the domain for which you want information.
", - "location":"uri", - "locationName":"DomainName" - } - }, - "documentation":"Container for the parameters to the DescribeDomain
operation.
The current status of the domain.
" - } - }, - "documentation":"The result of a DescribeDomain
request. Contains the status of the domain specified in the request.
The domains for which you want information.
" - } - }, - "documentation":"Container for the parameters to the DescribeDomains
operation. By default, the API returns the status of all domains.
The status of the domains requested in the DescribeDomains
request.
The result of a DescribeDomains
request. Contains the status of the specified domains or all domains owned by the account.
A list of filters used to match properties for inbound cross-cluster connections. Available Filter
values are:
Set this value to limit the number of results returned. If not specified, defaults to 100.
" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"If more results are available and NextToken is present, make the next request to the same API with the received NextToken to paginate the remaining results.
" - } - }, - "documentation":"Container for the parameters to the DescribeInboundConnections
operation.
A list of InboundConnection
matching the specified filter criteria.
If more results are available and NextToken is present, make the next request to the same API with the received NextToken to paginate the remaining results.
" - } - }, - "documentation":"The result of a DescribeInboundConnections
request. Contains a list of connections matching the filter criteria.
The name of the domain you want to modify. Only include this value if you're querying OpenSearch Limits
for an existing domain.
The instance type for an OpenSearch cluster for which OpenSearch Limits
are needed.
Version of OpenSearch for which Limits
are needed.
Container for the parameters to the DescribeInstanceTypeLimits
operation.
Container for the parameters received from the DescribeInstanceTypeLimits
operation.
A list of filters used to match properties for outbound cross-cluster connections. Available Filter
names for this operation are:
Set this value to limit the number of results returned. If not specified, defaults to 100.
" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"NextToken is sent in case the earlier API call results contain the NextToken parameter. Used for pagination.
" - } - }, - "documentation":"Container for the parameters to the DescribeOutboundConnections
operation.
A list of OutboundConnection
matching the specified filter criteria.
If more results are available and NextToken is present, make the next request to the same API with the received NextToken to paginate the remaining results.
" - } - }, - "documentation":"The result of a DescribeOutboundConnections
request. Contains the list of connections matching the filter criteria.
Any field from PackageDetails
.
A list of values for the specified field.
" - } - }, - "documentation":"A filter to apply to the DescribePackage
response.
A list of DescribePackagesFilter
to filter the packages included in a DescribePackages
response.
Only returns packages that match the DescribePackagesFilterList
values.
Limits results to a maximum number of packages.
" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"Used for pagination. Only necessary if a previous API call includes a non-null NextToken value. If provided, returns results for the next page.
" - } - }, - "documentation":" Container for the request parameters to the DescribePackage
operation.
List of PackageDetails
objects.
Container for the response returned by the DescribePackages
operation.
The offering identifier filter value. Use this parameter to show only the available offering that matches the specified reservation identifier.
", - "location":"querystring", - "locationName":"offeringId" - }, - "MaxResults":{ - "shape":"MaxResults", - "documentation":"Set this value to limit the number of results returned. If not specified, defaults to 100.
", - "location":"querystring", - "locationName":"maxResults" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"Provides an identifier to allow retrieval of paginated results.
", - "location":"querystring", - "locationName":"nextToken" - } - }, - "documentation":"Container for parameters to DescribeReservedInstanceOfferings
Provides an identifier to allow retrieval of paginated results.
" - }, - "ReservedInstanceOfferings":{ - "shape":"ReservedInstanceOfferingList", - "documentation":"List of reserved OpenSearch instance offerings
" - } - }, - "documentation":"Container for results from DescribeReservedInstanceOfferings
The reserved instance identifier filter value. Use this parameter to show only the reservation that matches the specified reserved OpenSearch instance ID.
", - "location":"querystring", - "locationName":"reservationId" - }, - "MaxResults":{ - "shape":"MaxResults", - "documentation":"Set this value to limit the number of results returned. If not specified, defaults to 100.
", - "location":"querystring", - "locationName":"maxResults" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"Provides an identifier to allow retrieval of paginated results.
", - "location":"querystring", - "locationName":"nextToken" - } - }, - "documentation":"Container for parameters to DescribeReservedInstances
Provides an identifier to allow retrieval of paginated results.
" - }, - "ReservedInstances":{ - "shape":"ReservedInstanceList", - "documentation":"List of reserved OpenSearch instances.
" - } - }, - "documentation":"Container for results from DescribeReservedInstances
The internal ID of the package to associate with a domain. Use DescribePackages
to find this value.
The name of the domain to associate the package with.
", - "location":"uri", - "locationName":"DomainName" - } - }, - "documentation":" Container for the request parameters to the DissociatePackage
operation.
DomainPackageDetails
Container for the response returned by DissociatePackage
operation.
String of format Elasticsearch_X.Y or OpenSearch_X.Y to specify the engine version for the OpenSearch or Elasticsearch domain.
" - }, - "ClusterConfig":{ - "shape":"ClusterConfigStatus", - "documentation":"The ClusterConfig
for the domain.
The EBSOptions
for the domain.
IAM access policy as a JSON-formatted string.
" - }, - "SnapshotOptions":{ - "shape":"SnapshotOptionsStatus", - "documentation":"The SnapshotOptions
for the domain.
The VPCOptions
for the specified domain. For more information, see Launching your Amazon OpenSearch Service domains using a VPC.
The CognitoOptions
for the specified domain. For more information, see Configuring Amazon Cognito authentication for OpenSearch Dashboards.
The EncryptionAtRestOptions
for the domain.
The NodeToNodeEncryptionOptions
for the domain.
The AdvancedOptions
for the domain. See Advanced options for more information.
Log publishing options for the given domain.
" - }, - "DomainEndpointOptions":{ - "shape":"DomainEndpointOptionsStatus", - "documentation":"The DomainEndpointOptions
for the domain.
Specifies AdvancedSecurityOptions
for the domain.
Specifies AutoTuneOptions
for the domain.
The configuration of a domain.
" - }, - "DomainEndpointOptions":{ - "type":"structure", - "members":{ - "EnforceHTTPS":{ - "shape":"Boolean", - "documentation":"Whether only HTTPS endpoint should be enabled for the domain.
" - }, - "TLSSecurityPolicy":{ - "shape":"TLSSecurityPolicy", - "documentation":"Specify the TLS security policy to apply to the HTTPS endpoint of the domain.
Can be one of the following values:
Whether to enable a custom endpoint for the domain.
" - }, - "CustomEndpoint":{ - "shape":"DomainNameFqdn", - "documentation":"The fully qualified domain for your custom endpoint.
" - }, - "CustomEndpointCertificateArn":{ - "shape":"ARN", - "documentation":"The ACM certificate ARN for your custom endpoint.
" - } - }, - "documentation":"Options to configure the endpoint for the domain.
" - }, - "DomainEndpointOptionsStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"DomainEndpointOptions", - "documentation":"Options to configure the endpoint for the domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of the endpoint options for the domain. See OptionStatus
for the status information that's included.
The configured endpoint options for the domain and their current status.
" - }, - "DomainId":{ - "type":"string", - "documentation":"Unique identifier for the domain.
", - "max":64, - "min":1 - }, - "DomainInfo":{ - "type":"structure", - "members":{ - "DomainName":{ - "shape":"DomainName", - "documentation":"The DomainName
.
Contains the list of domain information.
" - }, - "DomainInformationContainer":{ - "type":"structure", - "members":{ - "AWSDomainInformation":{"shape":"AWSDomainInformation"} - } - }, - "DomainName":{ - "type":"string", - "documentation":"The name of an domain. Domain names are unique across the domains owned by an account within an AWS region. Domain names start with a letter or number and can contain the following characters: a-z (lowercase), 0-9, and - (hyphen).
", - "max":28, - "min":3, - "pattern":"[a-z][a-z0-9\\-]+" - }, - "DomainNameFqdn":{ - "type":"string", - "max":255, - "min":1, - "pattern":"^(((?!-)[A-Za-z0-9-]{0,62}[A-Za-z0-9])\\.)+((?!-)[A-Za-z0-9-]{1,62}[A-Za-z0-9])$" - }, - "DomainNameList":{ - "type":"list", - "member":{"shape":"DomainName"}, - "documentation":"A list of domain names.
" - }, - "DomainPackageDetails":{ - "type":"structure", - "members":{ - "PackageID":{ - "shape":"PackageID", - "documentation":"The internal ID of the package.
" - }, - "PackageName":{ - "shape":"PackageName", - "documentation":"User-specified name of the package.
" - }, - "PackageType":{ - "shape":"PackageType", - "documentation":"Currently supports only TXT-DICTIONARY.
" - }, - "LastUpdated":{ - "shape":"LastUpdated", - "documentation":"The timestamp of the most recent update to the package association status.
" - }, - "DomainName":{ - "shape":"DomainName", - "documentation":"The name of the domain you've associated a package with.
" - }, - "DomainPackageStatus":{ - "shape":"DomainPackageStatus", - "documentation":"State of the association. Values are ASSOCIATING, ASSOCIATION_FAILED, ACTIVE, DISSOCIATING, and DISSOCIATION_FAILED.
" - }, - "PackageVersion":{"shape":"PackageVersion"}, - "ReferencePath":{ - "shape":"ReferencePath", - "documentation":"The relative path on Amazon OpenSearch Service nodes, which can be used as synonym_path when the package is a synonym file.
" - }, - "ErrorDetails":{ - "shape":"ErrorDetails", - "documentation":"Additional information if the package is in an error state. Null otherwise.
" - } - }, - "documentation":"Information on a package associated with a domain.
" - }, - "DomainPackageDetailsList":{ - "type":"list", - "member":{"shape":"DomainPackageDetails"} - }, - "DomainPackageStatus":{ - "type":"string", - "enum":[ - "ASSOCIATING", - "ASSOCIATION_FAILED", - "ACTIVE", - "DISSOCIATING", - "DISSOCIATION_FAILED" - ] - }, - "DomainStatus":{ - "type":"structure", - "required":[ - "DomainId", - "DomainName", - "ARN", - "ClusterConfig" - ], - "members":{ - "DomainId":{ - "shape":"DomainId", - "documentation":"The unique identifier for the specified domain.
" - }, - "DomainName":{ - "shape":"DomainName", - "documentation":"The name of a domain. Domain names are unique across the domains owned by an account within an AWS region. Domain names start with a letter or number and can contain the following characters: a-z (lowercase), 0-9, and - (hyphen).
" - }, - "ARN":{ - "shape":"ARN", - "documentation":"The Amazon Resource Name (ARN) of a domain. See IAM identifiers in the AWS Identity and Access Management User Guide for more information.
" - }, - "Created":{ - "shape":"Boolean", - "documentation":"The domain creation status. True
if the creation of a domain is complete. False
if domain creation is still in progress.
The domain deletion status. True
if a delete request has been received for the domain but resource cleanup is still in progress. False
if the domain has not been deleted. Once domain deletion is complete, the status of the domain is no longer returned.
The domain endpoint that you use to submit index and search requests.
" - }, - "Endpoints":{ - "shape":"EndpointsMap", - "documentation":"Map containing the domain endpoints used to submit index and search requests. Example key, value
: 'vpc','vpc-endpoint-h2dsd34efgyghrtguk5gt6j2foh4.us-east-1.es.amazonaws.com'
.
The status of the domain configuration. True
if Amazon OpenSearch Service is processing configuration changes. False
if the configuration is active.
The status of a domain version upgrade. True
if Amazon OpenSearch Service is undergoing a version upgrade. False
if the configuration is active.
The type and number of instances in the domain.
" - }, - "EBSOptions":{ - "shape":"EBSOptions", - "documentation":"The EBSOptions
for the specified domain.
IAM access policy as a JSON-formatted string.
" - }, - "SnapshotOptions":{ - "shape":"SnapshotOptions", - "documentation":"The status of the SnapshotOptions
.
The VPCOptions
for the specified domain. For more information, see Launching your Amazon OpenSearch Service domains using a VPC.
The CognitoOptions
for the specified domain. For more information, see Configuring Amazon Cognito authentication for OpenSearch Dashboards.
The status of the EncryptionAtRestOptions
.
The status of the NodeToNodeEncryptionOptions
.
The status of the AdvancedOptions
.
Log publishing options for the given domain.
" - }, - "ServiceSoftwareOptions":{ - "shape":"ServiceSoftwareOptions", - "documentation":"The current status of the domain's service software.
" - }, - "DomainEndpointOptions":{ - "shape":"DomainEndpointOptions", - "documentation":"The current status of the domain's endpoint options.
" - }, - "AdvancedSecurityOptions":{ - "shape":"AdvancedSecurityOptions", - "documentation":"The current status of the domain's advanced security options.
" - }, - "AutoTuneOptions":{ - "shape":"AutoTuneOptionsOutput", - "documentation":"The current status of the domain's Auto-Tune options.
" - } - }, - "documentation":"The current status of a domain.
" - }, - "DomainStatusList":{ - "type":"list", - "member":{"shape":"DomainStatus"}, - "documentation":"A list that contains the status of each requested domain.
" - }, - "Double":{"type":"double"}, - "Duration":{ - "type":"structure", - "members":{ - "Value":{ - "shape":"DurationValue", - "documentation":"Integer to specify the value of a maintenance schedule duration. See Auto-Tune for Amazon OpenSearch Service for more information.
" - }, - "Unit":{ - "shape":"TimeUnit", - "documentation":"The unit of a maintenance schedule duration. Valid value is HOURS. See Auto-Tune for Amazon OpenSearch Service for more information.
" - } - }, - "documentation":"The maintenance schedule duration: duration value and duration unit. See Auto-Tune for Amazon OpenSearch Service for more information.
" - }, - "DurationValue":{ - "type":"long", - "documentation":"Integer to specify the value of a maintenance schedule duration. See Auto-Tune for Amazon OpenSearch Service for more information.
", - "max":24, - "min":1 - }, - "EBSOptions":{ - "type":"structure", - "members":{ - "EBSEnabled":{ - "shape":"Boolean", - "documentation":"Whether EBS-based storage is enabled.
" - }, - "VolumeType":{ - "shape":"VolumeType", - "documentation":"The volume type for EBS-based storage.
" - }, - "VolumeSize":{ - "shape":"IntegerClass", - "documentation":"Integer to specify the size of an EBS volume.
" - }, - "Iops":{ - "shape":"IntegerClass", - "documentation":"The IOPD for a Provisioned IOPS EBS volume (SSD).
" - } - }, - "documentation":"Options to enable, disable, and specify the properties of EBS storage volumes.
" - }, - "EBSOptionsStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"EBSOptions", - "documentation":"The EBS options for the specified domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of the EBS options for the specified domain.
" - } - }, - "documentation":"Status of the EBS options for the specified domain.
" - }, - "EncryptionAtRestOptions":{ - "type":"structure", - "members":{ - "Enabled":{ - "shape":"Boolean", - "documentation":"The option to enable encryption at rest.
" - }, - "KmsKeyId":{ - "shape":"KmsKeyId", - "documentation":"The KMS key ID for encryption at rest options.
" - } - }, - "documentation":"Specifies encryption at rest options.
" - }, - "EncryptionAtRestOptionsStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"EncryptionAtRestOptions", - "documentation":"The Encryption At Rest options for the specified domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of the Encryption At Rest options for the specified domain.
" - } - }, - "documentation":"Status of the encryption At Rest options for the specified domain.
" - }, - "EndpointsMap":{ - "type":"map", - "key":{"shape":"String"}, - "value":{"shape":"ServiceUrl"} - }, - "ErrorDetails":{ - "type":"structure", - "members":{ - "ErrorType":{"shape":"ErrorType"}, - "ErrorMessage":{"shape":"ErrorMessage"} - } - }, - "ErrorMessage":{"type":"string"}, - "ErrorType":{"type":"string"}, - "Filter":{ - "type":"structure", - "members":{ - "Name":{ - "shape":"NonEmptyString", - "documentation":"The name of the filter.
" - }, - "Values":{ - "shape":"ValueStringList", - "documentation":"Contains one or more values for the filter.
" - } - }, - "documentation":"A filter used to limit results when describing inbound or outbound cross-cluster connections. Multiple values can be specified per filter. A cross-cluster connection must match at least one of the specified values for it to be returned from an operation.
" - }, - "FilterList":{ - "type":"list", - "member":{"shape":"Filter"} - }, - "GUID":{ - "type":"string", - "max":36, - "min":36, - "pattern":"\\p{XDigit}{8}-\\p{XDigit}{4}-\\p{XDigit}{4}-\\p{XDigit}{4}-\\p{XDigit}{12}" - }, - "GetCompatibleVersionsRequest":{ - "type":"structure", - "members":{ - "DomainName":{ - "shape":"DomainName", - "location":"querystring", - "locationName":"domainName" - } - }, - "documentation":" Container for the request parameters to GetCompatibleVersions
operation.
A map of compatible OpenSearch versions returned as part of the GetCompatibleVersions
operation.
Container for the response returned by the GetCompatibleVersions
operation.
Returns an audit history of package versions.
", - "location":"uri", - "locationName":"PackageID" - }, - "MaxResults":{ - "shape":"MaxResults", - "documentation":"Limits results to a maximum number of package versions.
", - "location":"querystring", - "locationName":"maxResults" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"Used for pagination. Only necessary if a previous API call includes a non-null NextToken value. If provided, returns results for the next page.
", - "location":"querystring", - "locationName":"nextToken" - } - }, - "documentation":" Container for the request parameters to the GetPackageVersionHistory
operation.
List of PackageVersionHistory
objects.
Container for response returned by GetPackageVersionHistory
operation.
Container for the request parameters to the GetUpgradeHistory
operation.
A list of UpgradeHistory
objects corresponding to each upgrade or upgrade eligibility check performed on a domain returned as part of the GetUpgradeHistoryResponse
object.
Pagination token that needs to be supplied to the next call to get the next page of results.
" - } - }, - "documentation":" Container for the response returned by the GetUpgradeHistory
operation.
Container for the request parameters to the GetUpgradeStatus
operation.
One of three steps an upgrade or upgrade eligibility check goes through:
One of four statuses an upgrade have, returned as part of the GetUpgradeStatusResponse
object. The status can take one of the following values:
A string that briefly describes the update.
" - } - }, - "documentation":" Container for the response returned by the GetUpgradeStatus
operation.
The AWSDomainInformation
for the local OpenSearch domain.
The AWSDomainInformation
for the remote OpenSearch domain.
The connection ID for the inbound cross-cluster connection.
" - }, - "ConnectionStatus":{ - "shape":"InboundConnectionStatus", - "documentation":"The InboundConnectionStatus
for the outbound connection.
Details of an inbound connection.
" - }, - "InboundConnectionStatus":{ - "type":"structure", - "members":{ - "StatusCode":{ - "shape":"InboundConnectionStatusCode", - "documentation":"The state code for the inbound connection. Can be one of the following:
Verbose information for the inbound connection status.
" - } - }, - "documentation":"The connection status of an inbound cross-cluster connection.
" - }, - "InboundConnectionStatusCode":{ - "type":"string", - "enum":[ - "PENDING_ACCEPTANCE", - "APPROVED", - "PROVISIONING", - "ACTIVE", - "REJECTING", - "REJECTED", - "DELETING", - "DELETED" - ] - }, - "InboundConnections":{ - "type":"list", - "member":{"shape":"InboundConnection"} - }, - "InstanceCount":{ - "type":"integer", - "documentation":"The number of EC2 instances in the domain.
", - "min":1 - }, - "InstanceCountLimits":{ - "type":"structure", - "members":{ - "MinimumInstanceCount":{"shape":"MinimumInstanceCount"}, - "MaximumInstanceCount":{"shape":"MaximumInstanceCount"} - }, - "documentation":"InstanceCountLimits represents the limits on the number of instances that can be created in Amazon OpenSearch Service for a given InstanceType.
" - }, - "InstanceLimits":{ - "type":"structure", - "members":{ - "InstanceCountLimits":{"shape":"InstanceCountLimits"} - }, - "documentation":"InstanceLimits represents the list of instance-related attributes that are available for a given InstanceType.
" - }, - "InstanceRole":{"type":"string"}, - "InstanceRoleList":{ - "type":"list", - "member":{"shape":"InstanceRole"} - }, - "InstanceTypeDetails":{ - "type":"structure", - "members":{ - "InstanceType":{"shape":"OpenSearchPartitionInstanceType"}, - "EncryptionEnabled":{"shape":"Boolean"}, - "CognitoEnabled":{"shape":"Boolean"}, - "AppLogsEnabled":{"shape":"Boolean"}, - "AdvancedSecurityEnabled":{"shape":"Boolean"}, - "WarmEnabled":{"shape":"Boolean"}, - "InstanceRole":{"shape":"InstanceRoleList"} - } - }, - "InstanceTypeDetailsList":{ - "type":"list", - "member":{"shape":"InstanceTypeDetails"} - }, - "Integer":{"type":"integer"}, - "IntegerClass":{"type":"integer"}, - "Issue":{"type":"string"}, - "Issues":{ - "type":"list", - "member":{"shape":"Issue"} - }, - "KmsKeyId":{ - "type":"string", - "max":500, - "min":1, - "pattern":".*" - }, - "LastUpdated":{"type":"timestamp"}, - "LimitName":{"type":"string"}, - "LimitValue":{"type":"string"}, - "LimitValueList":{ - "type":"list", - "member":{"shape":"LimitValue"} - }, - "Limits":{ - "type":"structure", - "members":{ - "StorageTypes":{ - "shape":"StorageTypeList", - "documentation":"Storage-related types and attributes that are available for a given InstanceType.
" - }, - "InstanceLimits":{"shape":"InstanceLimits"}, - "AdditionalLimits":{ - "shape":"AdditionalLimitList", - "documentation":" List of additional limits that are specific to a given InstanceType and for each of its InstanceRole
.
Limits for a given InstanceType and for each of its roles.
Limits contains the following: StorageTypes
, InstanceLimits
, and AdditionalLimits
The role of a given instance and all applicable limits. The role performed by a given OpenSearch instance can be one of the following:
List of domain names.
" - } - }, - "documentation":"The result of a ListDomainNames
operation. Contains the names of all domains owned by this account.
The package for which to list associated domains.
", - "location":"uri", - "locationName":"PackageID" - }, - "MaxResults":{ - "shape":"MaxResults", - "documentation":"Limits the results to a maximum number of domains.
", - "location":"querystring", - "locationName":"maxResults" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"Used for pagination. Only necessary if a previous API call includes a non-null NextToken value. If provided, returns results for the next page.
", - "location":"querystring", - "locationName":"nextToken" - } - }, - "documentation":" Container for the request parameters to the ListDomainsForPackage
operation.
List of DomainPackageDetails
objects.
Container for the response parameters to the ListDomainsForPackage
operation.
The name of the domain for which you want to list associated packages.
", - "location":"uri", - "locationName":"DomainName" - }, - "MaxResults":{ - "shape":"MaxResults", - "documentation":"Limits results to a maximum number of packages.
", - "location":"querystring", - "locationName":"maxResults" - }, - "NextToken":{ - "shape":"NextToken", - "documentation":"Used for pagination. Only necessary if a previous API call includes a non-null NextToken value. If provided, returns results for the next page.
", - "location":"querystring", - "locationName":"nextToken" - } - }, - "documentation":" Container for the request parameters to the ListPackagesForDomain
operation.
List of DomainPackageDetails
objects.
Pagination token to supply to the next call to get the next page of results.
" - } - }, - "documentation":" Container for the response parameters to the ListPackagesForDomain
operation.
Specify the ARN
of the domain that the tags you want to view are attached to.
Container for the parameters to the ListTags
operation. Specify the ARN
of the domain that the tags you want to view are attached to.
List of Tag
for the requested domain.
The result of a ListTags
operation. Contains tags for all requested domains.
Set this value to limit the number of results returned. Value must be greater than 10 or it won't be honored.
", - "location":"querystring", - "locationName":"maxResults" - }, - "NextToken":{ - "shape":"NextToken", - "location":"querystring", - "locationName":"nextToken" - } - }, - "documentation":" Container for the parameters to the ListVersions
operation.
Use MaxResults
to control the maximum number of results to retrieve in a single call.
Use NextToken
in response to retrieve more results. If the received response does not contain a NextToken, there are no more results to retrieve.
Container for the parameters for response received from the ListVersions
operation.
Whether the given log publishing option is enabled or not.
" - } - }, - "documentation":"Log Publishing option that is set for a given domain.
Attributes and their details:
The log publishing options configured for the domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of the log publishing options for the domain. See OptionStatus
for the status information that's included.
The configured log publishing options for the domain and their current status.
" - }, - "LogType":{ - "type":"string", - "documentation":"Type of log file. Can be one of the following:
ARN for the master user (if IAM is enabled).
" - }, - "MasterUserName":{ - "shape":"Username", - "documentation":"The master user's username, which is stored in the Amazon OpenSearch Service domain's internal database.
" - }, - "MasterUserPassword":{ - "shape":"Password", - "documentation":"The master user's password, which is stored in the Amazon OpenSearch Service domain's internal database.
" - } - }, - "documentation":"Credentials for the master user: username and password, ARN, or both.
" - }, - "MaxResults":{ - "type":"integer", - "documentation":"Set this value to limit the number of results returned.
", - "max":100 - }, - "MaximumInstanceCount":{ - "type":"integer", - "documentation":"Maximum number of instances that can be instantiated for a given InstanceType.
" - }, - "MinimumInstanceCount":{ - "type":"integer", - "documentation":"Minimum number of instances that can be instantiated for a given InstanceType.
" - }, - "NextToken":{ - "type":"string", - "documentation":"Paginated APIs accept the NextToken input to return the next page of results and provide a NextToken output in the response, which you can use to retrieve more results.
" - }, - "NodeToNodeEncryptionOptions":{ - "type":"structure", - "members":{ - "Enabled":{ - "shape":"Boolean", - "documentation":"True to enable node-to-node encryption.
" - } - }, - "documentation":"The node-to-node encryption options.
" - }, - "NodeToNodeEncryptionOptionsStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"NodeToNodeEncryptionOptions", - "documentation":"The node-to-node encryption options for the specified domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of the node-to-node encryption options for the specified domain.
" - } - }, - "documentation":"Status of the node-to-node encryption options for the specified domain.
" - }, - "NonEmptyString":{ - "type":"string", - "max":100, - "min":1, - "pattern":"[a-zA-Z0-9\\-\\_\\.]+" - }, - "OpenSearchPartitionInstanceType":{ - "type":"string", - "enum":[ - "m3.medium.search", - "m3.large.search", - "m3.xlarge.search", - "m3.2xlarge.search", - "m4.large.search", - "m4.xlarge.search", - "m4.2xlarge.search", - "m4.4xlarge.search", - "m4.10xlarge.search", - "m5.large.search", - "m5.xlarge.search", - "m5.2xlarge.search", - "m5.4xlarge.search", - "m5.12xlarge.search", - "m5.24xlarge.search", - "r5.large.search", - "r5.xlarge.search", - "r5.2xlarge.search", - "r5.4xlarge.search", - "r5.12xlarge.search", - "r5.24xlarge.search", - "c5.large.search", - "c5.xlarge.search", - "c5.2xlarge.search", - "c5.4xlarge.search", - "c5.9xlarge.search", - "c5.18xlarge.search", - "t3.nano.search", - "t3.micro.search", - "t3.small.search", - "t3.medium.search", - "t3.large.search", - "t3.xlarge.search", - "t3.2xlarge.search", - "ultrawarm1.medium.search", - "ultrawarm1.large.search", - "ultrawarm1.xlarge.search", - "t2.micro.search", - "t2.small.search", - "t2.medium.search", - "r3.large.search", - "r3.xlarge.search", - "r3.2xlarge.search", - "r3.4xlarge.search", - "r3.8xlarge.search", - "i2.xlarge.search", - "i2.2xlarge.search", - "d2.xlarge.search", - "d2.2xlarge.search", - "d2.4xlarge.search", - "d2.8xlarge.search", - "c4.large.search", - "c4.xlarge.search", - "c4.2xlarge.search", - "c4.4xlarge.search", - "c4.8xlarge.search", - "r4.large.search", - "r4.xlarge.search", - "r4.2xlarge.search", - "r4.4xlarge.search", - "r4.8xlarge.search", - "r4.16xlarge.search", - "i3.large.search", - "i3.xlarge.search", - "i3.2xlarge.search", - "i3.4xlarge.search", - "i3.8xlarge.search", - "i3.16xlarge.search", - "r6g.large.search", - "r6g.xlarge.search", - "r6g.2xlarge.search", - "r6g.4xlarge.search", - "r6g.8xlarge.search", - "r6g.12xlarge.search", - "m6g.large.search", - "m6g.xlarge.search", - "m6g.2xlarge.search", - "m6g.4xlarge.search", - "m6g.8xlarge.search", - "m6g.12xlarge.search", - "c6g.large.search", - "c6g.xlarge.search", - "c6g.2xlarge.search", - "c6g.4xlarge.search", - "c6g.8xlarge.search", - "c6g.12xlarge.search", - "r6gd.large.search", - "r6gd.xlarge.search", - "r6gd.2xlarge.search", - "r6gd.4xlarge.search", - "r6gd.8xlarge.search", - "r6gd.12xlarge.search", - "r6gd.16xlarge.search", - "t4g.small.search", - "t4g.medium.search" - ] - }, - "OpenSearchWarmPartitionInstanceType":{ - "type":"string", - "enum":[ - "ultrawarm1.medium.search", - "ultrawarm1.large.search", - "ultrawarm1.xlarge.search" - ] - }, - "OptionState":{ - "type":"string", - "documentation":"The state of a requested change. One of the following:
The timestamp of when the entity was created.
" - }, - "UpdateDate":{ - "shape":"UpdateTimestamp", - "documentation":"The timestamp of the last time the entity was updated.
" - }, - "UpdateVersion":{ - "shape":"UIntValue", - "documentation":"The latest version of the entity.
" - }, - "State":{ - "shape":"OptionState", - "documentation":"Provides the OptionState
for the domain.
Indicates whether the domain is being deleted.
" - } - }, - "documentation":"Provides the current status of the entity.
" - }, - "OutboundConnection":{ - "type":"structure", - "members":{ - "LocalDomainInfo":{ - "shape":"DomainInformationContainer", - "documentation":"The DomainInformation
for the local OpenSearch domain.
The DomainInformation
for the remote OpenSearch domain.
The connection ID for the outbound cross-cluster connection.
" - }, - "ConnectionAlias":{ - "shape":"ConnectionAlias", - "documentation":"The connection alias for the outbound cross-cluster connection.
" - }, - "ConnectionStatus":{ - "shape":"OutboundConnectionStatus", - "documentation":"The OutboundConnectionStatus
for the outbound connection.
Specifies details about an outbound connection.
" - }, - "OutboundConnectionStatus":{ - "type":"structure", - "members":{ - "StatusCode":{ - "shape":"OutboundConnectionStatusCode", - "documentation":"The state code for the outbound connection. Can be one of the following:
Verbose information for the outbound connection status.
" - } - }, - "documentation":"The connection status of an outbound cross-cluster connection.
" - }, - "OutboundConnectionStatusCode":{ - "type":"string", - "enum":[ - "VALIDATING", - "VALIDATION_FAILED", - "PENDING_ACCEPTANCE", - "APPROVED", - "PROVISIONING", - "ACTIVE", - "REJECTING", - "REJECTED", - "DELETING", - "DELETED" - ] - }, - "OutboundConnections":{ - "type":"list", - "member":{"shape":"OutboundConnection"} - }, - "OwnerId":{ - "type":"string", - "max":12, - "min":12, - "pattern":"[0-9]+" - }, - "PackageDescription":{ - "type":"string", - "max":1024 - }, - "PackageDetails":{ - "type":"structure", - "members":{ - "PackageID":{ - "shape":"PackageID", - "documentation":"Internal ID of the package.
" - }, - "PackageName":{ - "shape":"PackageName", - "documentation":"User-specified name of the package.
" - }, - "PackageType":{ - "shape":"PackageType", - "documentation":"Currently supports only TXT-DICTIONARY.
" - }, - "PackageDescription":{ - "shape":"PackageDescription", - "documentation":"User-specified description of the package.
" - }, - "PackageStatus":{ - "shape":"PackageStatus", - "documentation":"Current state of the package. Values are COPYING, COPY_FAILED, AVAILABLE, DELETING, and DELETE_FAILED.
" - }, - "CreatedAt":{ - "shape":"CreatedAt", - "documentation":"The timestamp of when the package was created.
" - }, - "LastUpdatedAt":{"shape":"LastUpdated"}, - "AvailablePackageVersion":{"shape":"PackageVersion"}, - "ErrorDetails":{ - "shape":"ErrorDetails", - "documentation":"Additional information if the package is in an error state. Null otherwise.
" - } - }, - "documentation":"Basic information about a package.
" - }, - "PackageDetailsList":{ - "type":"list", - "member":{"shape":"PackageDetails"} - }, - "PackageID":{"type":"string"}, - "PackageName":{ - "type":"string", - "max":28, - "min":3, - "pattern":"[a-z][a-z0-9\\-]+" - }, - "PackageSource":{ - "type":"structure", - "members":{ - "S3BucketName":{ - "shape":"S3BucketName", - "documentation":"The name of the Amazon S3 bucket containing the package.
" - }, - "S3Key":{ - "shape":"S3Key", - "documentation":"Key (file name) of the package.
" - } - }, - "documentation":"The Amazon S3 location for importing the package specified as S3BucketName
and S3Key
The package version.
" - }, - "CommitMessage":{ - "shape":"CommitMessage", - "documentation":"A message associated with the package version.
" - }, - "CreatedAt":{ - "shape":"CreatedAt", - "documentation":"The timestamp of when the package was created.
" - } - }, - "documentation":"Details of a package version.
" - }, - "PackageVersionHistoryList":{ - "type":"list", - "member":{"shape":"PackageVersionHistory"} - }, - "Password":{ - "type":"string", - "max":128, - "min":8, - "pattern":".*", - "sensitive":true - }, - "PolicyDocument":{ - "type":"string", - "documentation":"Access policy rules for a domain service endpoints. For more information, see Configuring access policies . The maximum size of a policy document is 100 KB.
", - "max":102400, - "min":0, - "pattern":".*" - }, - "PurchaseReservedInstanceOfferingRequest":{ - "type":"structure", - "required":[ - "ReservedInstanceOfferingId", - "ReservationName" - ], - "members":{ - "ReservedInstanceOfferingId":{ - "shape":"GUID", - "documentation":"The ID of the reserved OpenSearch instance offering to purchase.
" - }, - "ReservationName":{ - "shape":"ReservationToken", - "documentation":"A customer-specified identifier to track this reservation.
" - }, - "InstanceCount":{ - "shape":"InstanceCount", - "documentation":"The number of OpenSearch instances to reserve.
" - } - }, - "documentation":"Container for parameters to PurchaseReservedInstanceOffering
Details of the reserved OpenSearch instance which was purchased.
" - }, - "ReservationName":{ - "shape":"ReservationToken", - "documentation":"The customer-specified identifier used to track this reservation.
" - } - }, - "documentation":"Represents the output of a PurchaseReservedInstanceOffering
operation.
The monetary amount of the recurring charge.
" - }, - "RecurringChargeFrequency":{ - "shape":"String", - "documentation":"The frequency of the recurring charge.
" - } - }, - "documentation":"Contains the specific price and frequency of a recurring charges for a reserved OpenSearch instance, or for a reserved OpenSearch instance offering.
" - }, - "RecurringChargeList":{ - "type":"list", - "member":{"shape":"RecurringCharge"} - }, - "ReferencePath":{"type":"string"}, - "Region":{ - "type":"string", - "max":30, - "min":5, - "pattern":"[a-z][a-z0-9\\-]+" - }, - "RejectInboundConnectionRequest":{ - "type":"structure", - "required":["ConnectionId"], - "members":{ - "ConnectionId":{ - "shape":"ConnectionId", - "documentation":"The ID of the inbound connection to reject.
", - "location":"uri", - "locationName":"ConnectionId" - } - }, - "documentation":"Container for the parameters to the RejectInboundConnection
operation.
The InboundConnection
of the rejected inbound connection.
The result of a RejectInboundConnection
operation. Contains details about the rejected inbound connection.
The ARN
of the domain from which you want to delete the specified tags.
The TagKey
list you want to remove from the domain.
Container for the parameters to the RemoveTags
operation. Specify the ARN
for the domain from which you want to remove the specified TagKey
.
The customer-specified identifier to track this reservation.
" - }, - "ReservedInstanceId":{ - "shape":"GUID", - "documentation":"The unique identifier for the reservation.
" - }, - "BillingSubscriptionId":{"shape":"Long"}, - "ReservedInstanceOfferingId":{ - "shape":"String", - "documentation":"The offering identifier.
" - }, - "InstanceType":{ - "shape":"OpenSearchPartitionInstanceType", - "documentation":"The OpenSearch instance type offered by the reserved instance offering.
" - }, - "StartTime":{ - "shape":"UpdateTimestamp", - "documentation":"The time the reservation started.
" - }, - "Duration":{ - "shape":"Integer", - "documentation":"The duration, in seconds, for which the OpenSearch instance is reserved.
" - }, - "FixedPrice":{ - "shape":"Double", - "documentation":"The upfront fixed charge you will paid to purchase the specific reserved OpenSearch instance offering.
" - }, - "UsagePrice":{ - "shape":"Double", - "documentation":"The rate you are charged for each hour for the domain that is using this reserved instance.
" - }, - "CurrencyCode":{ - "shape":"String", - "documentation":"The currency code for the reserved OpenSearch instance offering.
" - }, - "InstanceCount":{ - "shape":"Integer", - "documentation":"The number of OpenSearch instances that have been reserved.
" - }, - "State":{ - "shape":"String", - "documentation":"The state of the reserved OpenSearch instance.
" - }, - "PaymentOption":{ - "shape":"ReservedInstancePaymentOption", - "documentation":"The payment option as defined in the reserved OpenSearch instance offering.
" - }, - "RecurringCharges":{ - "shape":"RecurringChargeList", - "documentation":"The charge to your account regardless of whether you are creating any domains using the instance offering.
" - } - }, - "documentation":"Details of a reserved OpenSearch instance.
" - }, - "ReservedInstanceList":{ - "type":"list", - "member":{"shape":"ReservedInstance"} - }, - "ReservedInstanceOffering":{ - "type":"structure", - "members":{ - "ReservedInstanceOfferingId":{ - "shape":"GUID", - "documentation":"The OpenSearch reserved instance offering identifier.
" - }, - "InstanceType":{ - "shape":"OpenSearchPartitionInstanceType", - "documentation":"The OpenSearch instance type offered by the reserved instance offering.
" - }, - "Duration":{ - "shape":"Integer", - "documentation":"The duration, in seconds, for which the offering will reserve the OpenSearch instance.
" - }, - "FixedPrice":{ - "shape":"Double", - "documentation":"The upfront fixed charge you will pay to purchase the specific reserved OpenSearch instance offering.
" - }, - "UsagePrice":{ - "shape":"Double", - "documentation":"The rate you are charged for each hour the domain that is using the offering is running.
" - }, - "CurrencyCode":{ - "shape":"String", - "documentation":"The currency code for the reserved OpenSearch instance offering.
" - }, - "PaymentOption":{ - "shape":"ReservedInstancePaymentOption", - "documentation":"Payment option for the reserved OpenSearch instance offering
" - }, - "RecurringCharges":{ - "shape":"RecurringChargeList", - "documentation":"The charge to your account regardless of whether you are creating any domains using the instance offering.
" - } - }, - "documentation":"Details of a reserved OpenSearch instance offering.
" - }, - "ReservedInstanceOfferingList":{ - "type":"list", - "member":{"shape":"ReservedInstanceOffering"} - }, - "ReservedInstancePaymentOption":{ - "type":"string", - "enum":[ - "ALL_UPFRONT", - "PARTIAL_UPFRONT", - "NO_UPFRONT" - ] - }, - "RoleArn":{ - "type":"string", - "max":2048, - "min":20, - "pattern":"arn:(aws|aws\\-cn|aws\\-us\\-gov|aws\\-iso|aws\\-iso\\-b):iam::[0-9]+:role\\/.*" - }, - "RollbackOnDisable":{ - "type":"string", - "documentation":"The rollback state while disabling Auto-Tune for the domain. Valid values are NO_ROLLBACK and DEFAULT_ROLLBACK.
", - "enum":[ - "NO_ROLLBACK", - "DEFAULT_ROLLBACK" - ] - }, - "S3BucketName":{ - "type":"string", - "max":63, - "min":3 - }, - "S3Key":{ - "type":"string", - "max":1024, - "min":1 - }, - "SAMLEntityId":{ - "type":"string", - "max":512, - "min":8 - }, - "SAMLIdp":{ - "type":"structure", - "required":[ - "MetadataContent", - "EntityId" - ], - "members":{ - "MetadataContent":{ - "shape":"SAMLMetadata", - "documentation":"The metadata of the SAML application in XML format.
" - }, - "EntityId":{ - "shape":"SAMLEntityId", - "documentation":"The unique entity ID of the application in SAML identity provider.
" - } - }, - "documentation":"The SAML identity povider's information.
" - }, - "SAMLMetadata":{ - "type":"string", - "max":1048576, - "min":1 - }, - "SAMLOptionsInput":{ - "type":"structure", - "members":{ - "Enabled":{ - "shape":"Boolean", - "documentation":"True if SAML is enabled.
" - }, - "Idp":{ - "shape":"SAMLIdp", - "documentation":"The SAML Identity Provider's information.
" - }, - "MasterUserName":{ - "shape":"Username", - "documentation":"The SAML master username, which is stored in the Amazon OpenSearch Service domain's internal database.
" - }, - "MasterBackendRole":{ - "shape":"BackendRole", - "documentation":"The backend role that the SAML master user is mapped to.
" - }, - "SubjectKey":{ - "shape":"String", - "documentation":"Element of the SAML assertion to use for username. Default is NameID.
" - }, - "RolesKey":{ - "shape":"String", - "documentation":"Element of the SAML assertion to use for backend roles. Default is roles.
" - }, - "SessionTimeoutMinutes":{ - "shape":"IntegerClass", - "documentation":"The duration, in minutes, after which a user session becomes inactive. Acceptable values are between 1 and 1440, and the default value is 60.
" - } - }, - "documentation":"The SAML application configuration for the domain.
" - }, - "SAMLOptionsOutput":{ - "type":"structure", - "members":{ - "Enabled":{ - "shape":"Boolean", - "documentation":"True if SAML is enabled.
" - }, - "Idp":{ - "shape":"SAMLIdp", - "documentation":"Describes the SAML identity provider's information.
" - }, - "SubjectKey":{ - "shape":"String", - "documentation":"The key used for matching the SAML subject attribute.
" - }, - "RolesKey":{ - "shape":"String", - "documentation":"The key used for matching the SAML roles attribute.
" - }, - "SessionTimeoutMinutes":{ - "shape":"IntegerClass", - "documentation":"The duration, in minutes, after which a user session becomes inactive.
" - } - }, - "documentation":"Describes the SAML application configured for the domain.
" - }, - "ScheduledAutoTuneActionType":{ - "type":"string", - "documentation":"The Auto-Tune action type. Valid values are JVM_HEAP_SIZE_TUNING, and JVM_YOUNG_GEN_TUNING.
", - "enum":[ - "JVM_HEAP_SIZE_TUNING", - "JVM_YOUNG_GEN_TUNING" - ] - }, - "ScheduledAutoTuneDescription":{ - "type":"string", - "documentation":"The Auto-Tune action description.
" - }, - "ScheduledAutoTuneDetails":{ - "type":"structure", - "members":{ - "Date":{ - "shape":"AutoTuneDate", - "documentation":"The timestamp of the Auto-Tune action scheduled for the domain.
" - }, - "ActionType":{ - "shape":"ScheduledAutoTuneActionType", - "documentation":"The Auto-Tune action type. Valid values are JVM_HEAP_SIZE_TUNING and JVM_YOUNG_GEN_TUNING.
" - }, - "Action":{ - "shape":"ScheduledAutoTuneDescription", - "documentation":"The Auto-Tune action description.
" - }, - "Severity":{ - "shape":"ScheduledAutoTuneSeverityType", - "documentation":"The Auto-Tune action severity. Valid values are LOW, MEDIUM, and HIGH.
" - } - }, - "documentation":"Specifies details about the scheduled Auto-Tune action. See Auto-Tune for Amazon OpenSearch Service for more information.
" - }, - "ScheduledAutoTuneSeverityType":{ - "type":"string", - "documentation":"The Auto-Tune action severity. Valid values are LOW, MEDIUM, and HIGH.
", - "enum":[ - "LOW", - "MEDIUM", - "HIGH" - ] - }, - "ServiceSoftwareOptions":{ - "type":"structure", - "members":{ - "CurrentVersion":{ - "shape":"String", - "documentation":"The current service software version present on the domain.
" - }, - "NewVersion":{ - "shape":"String", - "documentation":"The new service software version if one is available.
" - }, - "UpdateAvailable":{ - "shape":"Boolean", - "documentation":" True
if you're able to update your service software version. False
if you can't update your service software version.
True
if you're able to cancel your service software version update. False
if you can't cancel your service software update.
The status of your service software update. This field can take the following values: ELIGIBLE
, PENDING_UPDATE
, IN_PROGRESS
, COMPLETED
, and NOT_ELIGIBLE
.
The description of the UpdateStatus
.
The timestamp, in Epoch time, until which you can manually request a service software update. After this date, we automatically update your service software.
" - }, - "OptionalDeployment":{ - "shape":"Boolean", - "documentation":" True
if a service software is never automatically updated. False
if a service software is automatically updated after AutomatedUpdateDate
.
The current options of an domain service software options.
" - }, - "ServiceUrl":{ - "type":"string", - "documentation":"The endpoint to which service requests are submitted. For example, search-imdb-movies-oopcnjfn6ugofer3zx5iadxxca.eu-west-1.es.amazonaws.com
or doc-imdb-movies-oopcnjfn6ugofer3zx5iadxxca.eu-west-1.es.amazonaws.com
.
The time, in UTC format, when the service takes a daily automated snapshot of the specified domain. Default is 0
hours.
The time, in UTC format, when the service takes a daily automated snapshot of the specified domain. Default is 0
hours.
The daily snapshot options specified for the domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of a daily automated snapshot.
" - } - }, - "documentation":"Status of a daily automated snapshot.
" - }, - "StartAt":{"type":"timestamp"}, - "StartServiceSoftwareUpdateRequest":{ - "type":"structure", - "required":["DomainName"], - "members":{ - "DomainName":{ - "shape":"DomainName", - "documentation":"The name of the domain that you want to update to the latest service software.
" - } - }, - "documentation":"Container for the parameters to the StartServiceSoftwareUpdate
operation. Specifies the name of the domain to schedule a service software update for.
The current status of the OpenSearch service software update.
" - } - }, - "documentation":"The result of a StartServiceSoftwareUpdate
operation. Contains the status of the update.
Sub-type of the given storage type. List of available sub-storage options: \"instance\" storageType has no storageSubType. \"ebs\" storageType has the following valid storageSubTypes:
VolumeType
for more information regarding each EBS storage option. "
- },
- "StorageType":{
- "type":"structure",
- "members":{
- "StorageTypeName":{"shape":"StorageTypeName"},
- "StorageSubTypeName":{"shape":"StorageSubTypeName"},
- "StorageTypeLimits":{
- "shape":"StorageTypeLimitList",
- "documentation":"Limits that are applicable for the given storage type.
" - } - }, - "documentation":"StorageTypes represents the list of storage-related types and their attributes that are available for a given InstanceType.
" - }, - "StorageTypeLimit":{ - "type":"structure", - "members":{ - "LimitName":{ - "shape":"LimitName", - "documentation":" Name of storage limits that are applicable for the given storage type. If StorageType
is \"ebs\", the following storage options are applicable:
Values for the StorageTypeLimit$LimitName
.
Limits that are applicable for the given storage type.
" - }, - "StorageTypeLimitList":{ - "type":"list", - "member":{"shape":"StorageTypeLimit"} - }, - "StorageTypeList":{ - "type":"list", - "member":{"shape":"StorageType"} - }, - "StorageTypeName":{ - "type":"string", - "documentation":"Type of storage. List of available storage options:
The TagKey
, the name of the tag. Tag keys must be unique for the domain to which they are attached.
The TagValue
, the value assigned to the corresponding tag key. Tag values can be null and don't have to be unique in a tag set. For example, you can have a key value pair in a tag set of project : Trinity
and cost-center : Trinity
A key value pair for a resource tag.
" - }, - "TagKey":{ - "type":"string", - "documentation":"A string of length from 1 to 128 characters that specifies the key for a tag. Tag keys must be unique for the domain to which they're attached.
", - "max":128, - "min":1, - "pattern":".*" - }, - "TagList":{ - "type":"list", - "member":{"shape":"Tag"}, - "documentation":"A list of Tag
.
A string of length from 0 to 256 characters that specifies the value for a tag. Tag values can be null and don't have to be unique in a tag set.
", - "max":256, - "min":0, - "pattern":".*" - }, - "TimeUnit":{ - "type":"string", - "documentation":"The unit of a maintenance schedule duration. Valid value is HOUR. See Auto-Tune for Amazon OpenSearch Service for more information.
", - "enum":["HOURS"] - }, - "UIntValue":{ - "type":"integer", - "min":0 - }, - "UpdateDomainConfigRequest":{ - "type":"structure", - "required":["DomainName"], - "members":{ - "DomainName":{ - "shape":"DomainName", - "documentation":"The name of the domain you're updating.
", - "location":"uri", - "locationName":"DomainName" - }, - "ClusterConfig":{ - "shape":"ClusterConfig", - "documentation":"The type and number of instances to instantiate for the domain cluster.
" - }, - "EBSOptions":{ - "shape":"EBSOptions", - "documentation":"Specify the type and size of the EBS volume to use.
" - }, - "SnapshotOptions":{ - "shape":"SnapshotOptions", - "documentation":"Option to set the time, in UTC format, for the daily automated snapshot. Default value is 0
hours.
Options to specify the subnets and security groups for the VPC endpoint. For more information, see Launching your Amazon OpenSearch Service domains using a VPC .
" - }, - "CognitoOptions":{ - "shape":"CognitoOptions", - "documentation":"Options to specify the Cognito user and identity pools for OpenSearch Dashboards authentication. For more information, see Configuring Amazon Cognito authentication for OpenSearch Dashboards.
" - }, - "AdvancedOptions":{ - "shape":"AdvancedOptions", - "documentation":"Modifies the advanced option to allow references to indices in an HTTP request body. Must be false
when configuring access to individual sub-resources. By default, the value is true
. See Advanced options for more information.
IAM access policy as a JSON-formatted string.
" - }, - "LogPublishingOptions":{ - "shape":"LogPublishingOptions", - "documentation":"Map of LogType
and LogPublishingOption
, each containing options to publish a given type of OpenSearch log.
Specifies encryption of data at rest options.
" - }, - "DomainEndpointOptions":{ - "shape":"DomainEndpointOptions", - "documentation":"Options to specify configuration that will be applied to the domain endpoint.
" - }, - "NodeToNodeEncryptionOptions":{ - "shape":"NodeToNodeEncryptionOptions", - "documentation":"Specifies node-to-node encryption options.
" - }, - "AdvancedSecurityOptions":{ - "shape":"AdvancedSecurityOptionsInput", - "documentation":"Specifies advanced security options.
" - }, - "AutoTuneOptions":{ - "shape":"AutoTuneOptions", - "documentation":"Specifies Auto-Tune options.
" - } - }, - "documentation":"Container for the parameters to the UpdateDomain
operation. Specifies the type and number of instances in the domain cluster.
The status of the updated domain.
" - } - }, - "documentation":"The result of an UpdateDomain
request. Contains the status of the domain being updated.
The unique identifier for the package.
" - }, - "PackageSource":{"shape":"PackageSource"}, - "PackageDescription":{ - "shape":"PackageDescription", - "documentation":"A new description of the package.
" - }, - "CommitMessage":{ - "shape":"CommitMessage", - "documentation":"A commit message for the new version which is shown as part of GetPackageVersionHistoryResponse
.
Container for request parameters to the UpdatePackage
operation.
Information about the package.
" - } - }, - "documentation":" Container for the response returned by the UpdatePackage
operation.
The version of OpenSearch you intend to upgrade the domain to.
" - }, - "PerformCheckOnly":{ - "shape":"Boolean", - "documentation":"When true, indicates that an upgrade eligibility check needs to be performed. Does not actually perform the upgrade.
" - }, - "AdvancedOptions":{"shape":"AdvancedOptions"} - }, - "documentation":" Container for the request parameters to UpgradeDomain
operation.
The version of OpenSearch that you intend to upgrade the domain to.
" - }, - "PerformCheckOnly":{ - "shape":"Boolean", - "documentation":"When true, indicates that an upgrade eligibility check needs to be performed. Does not actually perform the upgrade.
" - }, - "AdvancedOptions":{"shape":"AdvancedOptions"} - }, - "documentation":" Container for response returned by UpgradeDomain
operation.
A string that briefly describes the upgrade.
" - }, - "StartTimestamp":{ - "shape":"StartTimestamp", - "documentation":"UTC timestamp at which the upgrade API call was made in \"yyyy-MM-ddTHH:mm:ssZ\" format.
" - }, - "UpgradeStatus":{ - "shape":"UpgradeStatus", - "documentation":"The current status of the upgrade. The status can take one of the following values:
A list of UpgradeStepItem
s representing information about each step performed as part of a specific upgrade or upgrade eligibility check.
History of the last 10 upgrades and upgrade eligibility checks.
" - }, - "UpgradeHistoryList":{ - "type":"list", - "member":{"shape":"UpgradeHistory"} - }, - "UpgradeName":{"type":"string"}, - "UpgradeStatus":{ - "type":"string", - "enum":[ - "IN_PROGRESS", - "SUCCEEDED", - "SUCCEEDED_WITH_ISSUES", - "FAILED" - ] - }, - "UpgradeStep":{ - "type":"string", - "enum":[ - "PRE_UPGRADE_CHECK", - "SNAPSHOT", - "UPGRADE" - ] - }, - "UpgradeStepItem":{ - "type":"structure", - "members":{ - "UpgradeStep":{ - "shape":"UpgradeStep", - "documentation":"One of three steps an upgrade or upgrade eligibility check goes through:
The current status of the upgrade. The status can take one of the following values:
A list of strings containing detailed information about the errors encountered in a particular step.
" - }, - "ProgressPercent":{ - "shape":"Double", - "documentation":"The floating point value representing the progress percentage of a particular step.
" - } - }, - "documentation":"Represents a single step of the upgrade or upgrade eligibility check workflow.
" - }, - "UpgradeStepsList":{ - "type":"list", - "member":{"shape":"UpgradeStepItem"} - }, - "UserPoolId":{ - "type":"string", - "max":55, - "min":1, - "pattern":"[\\w-]+_[0-9a-zA-Z]+" - }, - "Username":{ - "type":"string", - "max":64, - "min":1, - "pattern":".*", - "sensitive":true - }, - "VPCDerivedInfo":{ - "type":"structure", - "members":{ - "VPCId":{ - "shape":"String", - "documentation":"The VPC ID for the domain. Exists only if the domain was created with VPCOptions
.
The subnets for the VPC endpoint.
" - }, - "AvailabilityZones":{ - "shape":"StringList", - "documentation":"The Availability Zones for the domain. Exists only if the domain was created with VPCOptions
.
The security groups for the VPC endpoint.
" - } - }, - "documentation":"Options to specify the subnets and security groups for the VPC endpoint. For more information, see Launching your Amazon OpenSearch Service domains using a VPC.
" - }, - "VPCDerivedInfoStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"VPCDerivedInfo", - "documentation":"The VPC options for the specified domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of the VPC options for the specified domain.
" - } - }, - "documentation":"Status of the VPC options for the specified domain.
" - }, - "VPCOptions":{ - "type":"structure", - "members":{ - "SubnetIds":{ - "shape":"StringList", - "documentation":"The subnets for the VPC endpoint.
" - }, - "SecurityGroupIds":{ - "shape":"StringList", - "documentation":"The security groups for the VPC endpoint.
" - } - }, - "documentation":"Options to specify the subnets and security groups for the VPC endpoint. For more information, see Launching your Amazon OpenSearch Service domains using a VPC.
" - }, - "ValueStringList":{ - "type":"list", - "member":{"shape":"NonEmptyString"}, - "min":1 - }, - "VersionList":{ - "type":"list", - "member":{"shape":"VersionString"}, - "documentation":"List of supported OpenSearch versions.
" - }, - "VersionStatus":{ - "type":"structure", - "required":[ - "Options", - "Status" - ], - "members":{ - "Options":{ - "shape":"VersionString", - "documentation":"The OpenSearch version for the specified OpenSearch domain.
" - }, - "Status":{ - "shape":"OptionStatus", - "documentation":"The status of the OpenSearch version options for the specified OpenSearch domain.
" - } - }, - "documentation":"The status of the OpenSearch version options for the specified OpenSearch domain.
" - }, - "VersionString":{ - "type":"string", - "max":18, - "min":14, - "pattern":"^Elasticsearch_[0-9]{1}\\.[0-9]{1,2}$|^OpenSearch_[0-9]{1,2}\\.[0-9]{1,2}$" - }, - "VolumeType":{ - "type":"string", - "documentation":"The type of EBS volume, standard, gp2, or io1. See Configuring EBS-based Storage for more information.
", - "enum":[ - "standard", - "gp2", - "io1" - ] - }, - "ZoneAwarenessConfig":{ - "type":"structure", - "members":{ - "AvailabilityZoneCount":{ - "shape":"IntegerClass", - "documentation":"An integer value to indicate the number of availability zones for a domain when zone awareness is enabled. This should be equal to number of subnets if VPC endpoints is enabled.
" - } - }, - "documentation":"The zone awareness configuration for the domain cluster, such as the number of availability zones.
" - } - }, - "documentation":"Use the Amazon OpenSearch configuration API to create, configure, and manage Amazon OpenSearch Service domains.
For sample code that uses the configuration API, see the Amazon OpenSearch Service Developer Guide. The guide also contains sample code for sending signed HTTP requests to the OpenSearch APIs.
The endpoint for configuration service requests is region-specific: es.region.amazonaws.com. For example, es.us-east-1.amazonaws.com. For a current list of supported regions and endpoints, see Regions and Endpoints.
" -} diff --git a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts index d56558ef1be31..39d406e70c77d 100644 --- a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts +++ b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts @@ -79,9 +79,8 @@ function installLatestSdk(): void { latestSdkInstalled = true; } -const patchedServices: { serviceName: string; apiVersions: string[] }[] = [ - { serviceName: 'OpenSearch', apiVersions: ['2021-01-01'] }, -]; +// no currently patched services +const patchedServices: { serviceName: string; apiVersions: string[] }[] = []; /** * Patches the AWS SDK by loading service models in the same manner as the actual SDK */ diff --git a/packages/@aws-cdk/custom-resources/lib/provider-framework/provider.ts b/packages/@aws-cdk/custom-resources/lib/provider-framework/provider.ts index 2c94cad1dbf3c..d8f4e97293a2a 100644 --- a/packages/@aws-cdk/custom-resources/lib/provider-framework/provider.ts +++ b/packages/@aws-cdk/custom-resources/lib/provider-framework/provider.ts @@ -209,7 +209,9 @@ export class Provider extends CoreConstruct implements ICustomResourceProvider { private createFunction(entrypoint: string, name?: string) { const fn = new lambda.Function(this, `framework-${entrypoint}`, { - code: lambda.Code.fromAsset(RUNTIME_HANDLER_PATH), + code: lambda.Code.fromAsset(RUNTIME_HANDLER_PATH, { + exclude: ['*.ts'], + }), description: `AWS CDK resource provider framework - ${entrypoint} (${this.node.path})`.slice(0, 256), runtime: lambda.Runtime.NODEJS_12_X, handler: `framework.${entrypoint}`, diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 4a1359916223c..f8ef33b6481de 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -47,7 +47,7 @@ "watch": "cdk-watch", "lint": "cdk-lint", "test": "cdk-test", - "integ": "cdk-integ", + "integ": "integ-runner", "pkglint": "pkglint -f", "package": "cdk-package", "awslint": "cdk-awslint", @@ -84,7 +84,7 @@ "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-ssm": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", - "@aws-cdk/cdk-integ-tools": "0.0.0", + "@aws-cdk/integ-runner": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/aws-lambda": "^8.10.93", diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/asset.9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/index.js b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/asset.9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/index.js new file mode 100644 index 0000000000000..ddf62f6363bf4 --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/asset.9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/index.js @@ -0,0 +1,250 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = exports.forceSdkInstallation = exports.flatten = exports.PHYSICAL_RESOURCE_ID_REFERENCE = void 0; +/* eslint-disable no-console */ +const child_process_1 = require("child_process"); +const fs = require("fs"); +const path_1 = require("path"); +/** + * Serialized form of the physical resource id for use in the operation parameters + */ +exports.PHYSICAL_RESOURCE_ID_REFERENCE = 'PHYSICAL:RESOURCEID:'; +/** + * Flattens a nested object + * + * @param object the object to be flattened + * @returns a flat object with path as keys + */ +function flatten(object) { + return Object.assign({}, ...function _flatten(child, path = []) { + return [].concat(...Object.keys(child) + .map(key => { + const childKey = Buffer.isBuffer(child[key]) ? child[key].toString('utf8') : child[key]; + return typeof childKey === 'object' && childKey !== null + ? _flatten(childKey, path.concat([key])) + : ({ [path.concat([key]).join('.')]: childKey }); + })); + }(object)); +} +exports.flatten = flatten; +/** + * Decodes encoded special values (physicalResourceId) + */ +function decodeSpecialValues(object, physicalResourceId) { + return JSON.parse(JSON.stringify(object), (_k, v) => { + switch (v) { + case exports.PHYSICAL_RESOURCE_ID_REFERENCE: + return physicalResourceId; + default: + return v; + } + }); +} +/** + * Filters the keys of an object. + */ +function filterKeys(object, pred) { + return Object.entries(object) + .reduce((acc, [k, v]) => pred(k) + ? { ...acc, [k]: v } + : acc, {}); +} +let latestSdkInstalled = false; +function forceSdkInstallation() { + latestSdkInstalled = false; +} +exports.forceSdkInstallation = forceSdkInstallation; +/** + * Installs latest AWS SDK v2 + */ +function installLatestSdk() { + console.log('Installing latest AWS SDK v2'); + // Both HOME and --prefix are needed here because /tmp is the only writable location + child_process_1.execSync('HOME=/tmp npm install aws-sdk@2 --production --no-package-lock --no-save --prefix /tmp'); + latestSdkInstalled = true; +} +// no currently patched services +const patchedServices = []; +/** + * Patches the AWS SDK by loading service models in the same manner as the actual SDK + */ +function patchSdk(awsSdk) { + const apiLoader = awsSdk.apiLoader; + patchedServices.forEach(({ serviceName, apiVersions }) => { + const lowerServiceName = serviceName.toLowerCase(); + if (!awsSdk.Service.hasService(lowerServiceName)) { + apiLoader.services[lowerServiceName] = {}; + awsSdk[serviceName] = awsSdk.Service.defineService(lowerServiceName, apiVersions); + } + else { + awsSdk.Service.addVersions(awsSdk[serviceName], apiVersions); + } + apiVersions.forEach(apiVersion => { + Object.defineProperty(apiLoader.services[lowerServiceName], apiVersion, { + get: function get() { + const modelFilePrefix = `aws-sdk-patch/${lowerServiceName}-${apiVersion}`; + const model = JSON.parse(fs.readFileSync(path_1.join(__dirname, `${modelFilePrefix}.service.json`), 'utf-8')); + model.paginators = JSON.parse(fs.readFileSync(path_1.join(__dirname, `${modelFilePrefix}.paginators.json`), 'utf-8')).pagination; + return model; + }, + enumerable: true, + configurable: true, + }); + }); + }); + return awsSdk; +} +/* eslint-disable @typescript-eslint/no-require-imports, import/no-extraneous-dependencies */ +async function handler(event, context) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _l, _m, _o, _p; + try { + let AWS; + if (!latestSdkInstalled && event.ResourceProperties.InstallLatestAwsSdk === 'true') { + try { + installLatestSdk(); + AWS = require('/tmp/node_modules/aws-sdk'); + } + catch (e) { + console.log(`Failed to install latest AWS SDK v2: ${e}`); + AWS = require('aws-sdk'); // Fallback to pre-installed version + } + } + else if (latestSdkInstalled) { + AWS = require('/tmp/node_modules/aws-sdk'); + } + else { + AWS = require('aws-sdk'); + } + try { + AWS = patchSdk(AWS); + } + catch (e) { + console.log(`Failed to patch AWS SDK: ${e}. Proceeding with the installed copy.`); + } + console.log(JSON.stringify(event)); + console.log('AWS SDK VERSION: ' + AWS.VERSION); + event.ResourceProperties.Create = decodeCall(event.ResourceProperties.Create); + event.ResourceProperties.Update = decodeCall(event.ResourceProperties.Update); + event.ResourceProperties.Delete = decodeCall(event.ResourceProperties.Delete); + // Default physical resource id + let physicalResourceId; + switch (event.RequestType) { + case 'Create': + physicalResourceId = (_j = (_f = (_c = (_b = (_a = event.ResourceProperties.Create) === null || _a === void 0 ? void 0 : _a.physicalResourceId) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : (_e = (_d = event.ResourceProperties.Update) === null || _d === void 0 ? void 0 : _d.physicalResourceId) === null || _e === void 0 ? void 0 : _e.id) !== null && _f !== void 0 ? _f : (_h = (_g = event.ResourceProperties.Delete) === null || _g === void 0 ? void 0 : _g.physicalResourceId) === null || _h === void 0 ? void 0 : _h.id) !== null && _j !== void 0 ? _j : event.LogicalResourceId; + break; + case 'Update': + case 'Delete': + physicalResourceId = (_o = (_m = (_l = event.ResourceProperties[event.RequestType]) === null || _l === void 0 ? void 0 : _l.physicalResourceId) === null || _m === void 0 ? void 0 : _m.id) !== null && _o !== void 0 ? _o : event.PhysicalResourceId; + break; + } + let flatData = {}; + let data = {}; + const call = event.ResourceProperties[event.RequestType]; + if (call) { + let credentials; + if (call.assumedRoleArn) { + const timestamp = (new Date()).getTime(); + const params = { + RoleArn: call.assumedRoleArn, + RoleSessionName: `${timestamp}-${physicalResourceId}`.substring(0, 64), + }; + credentials = new AWS.ChainableTemporaryCredentials({ + params: params, + }); + } + if (!Object.prototype.hasOwnProperty.call(AWS, call.service)) { + throw Error(`Service ${call.service} does not exist in AWS SDK version ${AWS.VERSION}.`); + } + const awsService = new AWS[call.service]({ + apiVersion: call.apiVersion, + credentials: credentials, + region: call.region, + }); + try { + const response = await awsService[call.action](call.parameters && decodeSpecialValues(call.parameters, physicalResourceId)).promise(); + flatData = { + apiVersion: awsService.config.apiVersion, + region: awsService.config.region, + ...flatten(response), + }; + let outputPaths; + if (call.outputPath) { + outputPaths = [call.outputPath]; + } + else if (call.outputPaths) { + outputPaths = call.outputPaths; + } + if (outputPaths) { + data = filterKeys(flatData, startsWithOneOf(outputPaths)); + } + else { + data = flatData; + } + } + catch (e) { + if (!call.ignoreErrorCodesMatching || !new RegExp(call.ignoreErrorCodesMatching).test(e.code)) { + throw e; + } + } + if ((_p = call.physicalResourceId) === null || _p === void 0 ? void 0 : _p.responsePath) { + physicalResourceId = flatData[call.physicalResourceId.responsePath]; + } + } + await respond('SUCCESS', 'OK', physicalResourceId, data); + } + catch (e) { + console.log(e); + await respond('FAILED', e.message || 'Internal Error', context.logStreamName, {}); + } + function respond(responseStatus, reason, physicalResourceId, data) { + const responseBody = JSON.stringify({ + Status: responseStatus, + Reason: reason, + PhysicalResourceId: physicalResourceId, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + NoEcho: false, + Data: data, + }); + console.log('Responding', responseBody); + // eslint-disable-next-line @typescript-eslint/no-require-imports + const parsedUrl = require('url').parse(event.ResponseURL); + const requestOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + return new Promise((resolve, reject) => { + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const request = require('https').request(requestOptions, resolve); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); + } +} +exports.handler = handler; +function decodeCall(call) { + if (!call) { + return undefined; + } + return JSON.parse(call); +} +function startsWithOneOf(searchStrings) { + return function (string) { + for (const searchString of searchStrings) { + if (string.startsWith(searchString)) { + return true; + } + } + return false; + }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsaURBQXlDO0FBQ3pDLHlCQUF5QjtBQUN6QiwrQkFBNEI7QUFTNUI7O0dBRUc7QUFDVSxRQUFBLDhCQUE4QixHQUFHLHNCQUFzQixDQUFDO0FBRXJFOzs7OztHQUtHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLE1BQWM7SUFDcEMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQixFQUFFLEVBQ0YsR0FBRyxTQUFTLFFBQVEsQ0FBQyxLQUFVLEVBQUUsT0FBaUIsRUFBRTtRQUNsRCxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDVCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEYsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksUUFBUSxLQUFLLElBQUk7Z0JBQ3RELENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUNWLENBQUM7QUFDSixDQUFDO0FBYkQsMEJBYUM7QUFFRDs7R0FFRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBYyxFQUFFLGtCQUEwQjtJQUNyRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNsRCxRQUFRLENBQUMsRUFBRTtZQUNULEtBQUssc0NBQThCO2dCQUNqQyxPQUFPLGtCQUFrQixDQUFDO1lBQzVCO2dCQUNFLE9BQU8sQ0FBQyxDQUFDO1NBQ1o7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWMsRUFBRSxJQUE4QjtJQUNoRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1NBQzFCLE1BQU0sQ0FDTCxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN0QixDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtRQUNwQixDQUFDLENBQUMsR0FBRyxFQUNQLEVBQUUsQ0FDSCxDQUFDO0FBQ04sQ0FBQztBQUVELElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO0FBRS9CLFNBQWdCLG9CQUFvQjtJQUNsQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7QUFDN0IsQ0FBQztBQUZELG9EQUVDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGdCQUFnQjtJQUN2QixPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDNUMsb0ZBQW9GO0lBQ3BGLHdCQUFRLENBQUMsd0ZBQXdGLENBQUMsQ0FBQztJQUNuRyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFDNUIsQ0FBQztBQUVELGdDQUFnQztBQUNoQyxNQUFNLGVBQWUsR0FBcUQsRUFBRSxDQUFDO0FBQzdFOztHQUVHO0FBQ0gsU0FBUyxRQUFRLENBQUMsTUFBVztJQUMzQixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO0lBQ25DLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFO1FBQ3ZELE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQ2hELFNBQVMsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDMUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1NBQ25GO2FBQU07WUFDTCxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7U0FDOUQ7UUFDRCxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQy9CLE1BQU0sQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLFVBQVUsRUFBRTtnQkFDdEUsR0FBRyxFQUFFLFNBQVMsR0FBRztvQkFDZixNQUFNLGVBQWUsR0FBRyxpQkFBaUIsZ0JBQWdCLElBQUksVUFBVSxFQUFFLENBQUM7b0JBQzFFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsZUFBZSxlQUFlLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUN2RyxLQUFLLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsZUFBZSxrQkFBa0IsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO29CQUMxSCxPQUFPLEtBQUssQ0FBQztnQkFDZixDQUFDO2dCQUNELFVBQVUsRUFBRSxJQUFJO2dCQUNoQixZQUFZLEVBQUUsSUFBSTthQUNuQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELDZGQUE2RjtBQUN0RixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7O0lBQzFHLElBQUk7UUFDRixJQUFJLEdBQVEsQ0FBQztRQUNiLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLEtBQUssTUFBTSxFQUFFO1lBQ2xGLElBQUk7Z0JBQ0YsZ0JBQWdCLEVBQUUsQ0FBQztnQkFDbkIsR0FBRyxHQUFHLE9BQU8sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO2FBQzVDO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3Q0FBd0MsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDekQsR0FBRyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLG9DQUFvQzthQUMvRDtTQUNGO2FBQU0sSUFBSSxrQkFBa0IsRUFBRTtZQUM3QixHQUFHLEdBQUcsT0FBTyxDQUFDLDJCQUEyQixDQUFDLENBQUM7U0FDNUM7YUFBTTtZQUNMLEdBQUcsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDMUI7UUFDRCxJQUFJO1lBQ0YsR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNyQjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1NBQ25GO1FBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDbkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFL0MsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzlFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5RSxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUUsK0JBQStCO1FBQy9CLElBQUksa0JBQTBCLENBQUM7UUFDL0IsUUFBUSxLQUFLLENBQUMsV0FBVyxFQUFFO1lBQ3pCLEtBQUssUUFBUTtnQkFDWCxrQkFBa0IsaUNBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sMENBQUUsa0JBQWtCLDBDQUFFLEVBQUUsK0NBQ3ZELEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLDBDQUFFLGtCQUFrQiwwQ0FBRSxFQUFFLCtDQUN2RCxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSwwQ0FBRSxrQkFBa0IsMENBQUUsRUFBRSxtQ0FDdkQsS0FBSyxDQUFDLGlCQUFpQixDQUFDO2dCQUM3QyxNQUFNO1lBQ1IsS0FBSyxRQUFRLENBQUM7WUFDZCxLQUFLLFFBQVE7Z0JBQ1gsa0JBQWtCLHFCQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLDBDQUFFLGtCQUFrQiwwQ0FBRSxFQUFFLG1DQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztnQkFDckgsTUFBTTtTQUNUO1FBRUQsSUFBSSxRQUFRLEdBQThCLEVBQUUsQ0FBQztRQUM3QyxJQUFJLElBQUksR0FBOEIsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sSUFBSSxHQUEyQixLQUFLLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRWpGLElBQUksSUFBSSxFQUFFO1lBRVIsSUFBSSxXQUFXLENBQUM7WUFDaEIsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO2dCQUN2QixNQUFNLFNBQVMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFFekMsTUFBTSxNQUFNLEdBQUc7b0JBQ2IsT0FBTyxFQUFFLElBQUksQ0FBQyxjQUFjO29CQUM1QixlQUFlLEVBQUUsR0FBRyxTQUFTLElBQUksa0JBQWtCLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztpQkFDdkUsQ0FBQztnQkFFRixXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsNkJBQTZCLENBQUM7b0JBQ2xELE1BQU0sRUFBRSxNQUFNO2lCQUNmLENBQUMsQ0FBQzthQUNKO1lBRUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUM1RCxNQUFNLEtBQUssQ0FBQyxXQUFXLElBQUksQ0FBQyxPQUFPLHNDQUFzQyxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQzthQUMxRjtZQUNELE1BQU0sVUFBVSxHQUFHLElBQUssR0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDaEQsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO2dCQUMzQixXQUFXLEVBQUUsV0FBVztnQkFDeEIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO2FBQ3BCLENBQUMsQ0FBQztZQUVILElBQUk7Z0JBQ0YsTUFBTSxRQUFRLEdBQUcsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUM1QyxJQUFJLENBQUMsVUFBVSxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN6RixRQUFRLEdBQUc7b0JBQ1QsVUFBVSxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsVUFBVTtvQkFDeEMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTTtvQkFDaEMsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO2lCQUNyQixDQUFDO2dCQUVGLElBQUksV0FBaUMsQ0FBQztnQkFDdEMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUNuQixXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7aUJBQ2pDO3FCQUFNLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtvQkFDM0IsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7aUJBQ2hDO2dCQUVELElBQUksV0FBVyxFQUFFO29CQUNmLElBQUksR0FBRyxVQUFVLENBQUMsUUFBUSxFQUFFLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO2lCQUMzRDtxQkFBTTtvQkFDTCxJQUFJLEdBQUcsUUFBUSxDQUFDO2lCQUNqQjthQUNGO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQzdGLE1BQU0sQ0FBQyxDQUFDO2lCQUNUO2FBQ0Y7WUFFRCxVQUFJLElBQUksQ0FBQyxrQkFBa0IsMENBQUUsWUFBWSxFQUFFO2dCQUN6QyxrQkFBa0IsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQ3JFO1NBQ0Y7UUFFRCxNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLElBQUksQ0FBQyxDQUFDO0tBQzFEO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDVixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2YsTUFBTSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxPQUFPLElBQUksZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztLQUNuRjtJQUVELFNBQVMsT0FBTyxDQUFDLGNBQXNCLEVBQUUsTUFBYyxFQUFFLGtCQUEwQixFQUFFLElBQVM7UUFDNUYsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNsQyxNQUFNLEVBQUUsY0FBYztZQUN0QixNQUFNLEVBQUUsTUFBTTtZQUNkLGtCQUFrQixFQUFFLGtCQUFrQjtZQUN0QyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87WUFDdEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1lBQzFCLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxpQkFBaUI7WUFDMUMsTUFBTSxFQUFFLEtBQUs7WUFDYixJQUFJLEVBQUUsSUFBSTtTQUNYLENBQUMsQ0FBQztRQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRXhDLGlFQUFpRTtRQUNqRSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxRCxNQUFNLGNBQWMsR0FBRztZQUNyQixRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7WUFDNUIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO1lBQ3BCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFO1NBQ3ZFLENBQUM7UUFFRixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUk7Z0JBQ0YsaUVBQWlFO2dCQUNqRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQzthQUNmO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ1g7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7QUFDSCxDQUFDO0FBakpELDBCQWlKQztBQUVELFNBQVMsVUFBVSxDQUFDLElBQXdCO0lBQzFDLElBQUksQ0FBQyxJQUFJLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQztLQUFFO0lBQ2hDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxQixDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsYUFBdUI7SUFDOUMsT0FBTyxVQUFTLE1BQWM7UUFDNUIsS0FBSyxNQUFNLFlBQVksSUFBSSxhQUFhLEVBQUU7WUFDeEMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUNuQyxPQUFPLElBQUksQ0FBQzthQUNiO1NBQ0Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgeyBleGVjU3luYyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuLy8gaW1wb3J0IHRoZSBBV1NMYW1iZGEgcGFja2FnZSBleHBsaWNpdGx5LFxuLy8gd2hpY2ggaXMgZ2xvYmFsbHkgYXZhaWxhYmxlIGluIHRoZSBMYW1iZGEgcnVudGltZSxcbi8vIGFzIG90aGVyd2lzZSBsaW5raW5nIHRoaXMgcmVwb3NpdG9yeSB3aXRoIGxpbmstYWxsLnNoXG4vLyBmYWlscyBpbiB0aGUgQ0RLIGFwcCBleGVjdXRlZCB3aXRoIHRzLW5vZGVcbi8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMsaW1wb3J0L25vLXVucmVzb2x2ZWQgKi9cbmltcG9ydCAqIGFzIEFXU0xhbWJkYSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCB7IEF3c1Nka0NhbGwgfSBmcm9tICcuLi9hd3MtY3VzdG9tLXJlc291cmNlJztcblxuLyoqXG4gKiBTZXJpYWxpemVkIGZvcm0gb2YgdGhlIHBoeXNpY2FsIHJlc291cmNlIGlkIGZvciB1c2UgaW4gdGhlIG9wZXJhdGlvbiBwYXJhbWV0ZXJzXG4gKi9cbmV4cG9ydCBjb25zdCBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0UgPSAnUEhZU0lDQUw6UkVTT1VSQ0VJRDonO1xuXG4vKipcbiAqIEZsYXR0ZW5zIGEgbmVzdGVkIG9iamVjdFxuICpcbiAqIEBwYXJhbSBvYmplY3QgdGhlIG9iamVjdCB0byBiZSBmbGF0dGVuZWRcbiAqIEByZXR1cm5zIGEgZmxhdCBvYmplY3Qgd2l0aCBwYXRoIGFzIGtleXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4ob2JqZWN0OiBvYmplY3QpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oXG4gICAge30sXG4gICAgLi4uZnVuY3Rpb24gX2ZsYXR0ZW4oY2hpbGQ6IGFueSwgcGF0aDogc3RyaW5nW10gPSBbXSk6IGFueSB7XG4gICAgICByZXR1cm4gW10uY29uY2F0KC4uLk9iamVjdC5rZXlzKGNoaWxkKVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgY29uc3QgY2hpbGRLZXkgPSBCdWZmZXIuaXNCdWZmZXIoY2hpbGRba2V5XSkgPyBjaGlsZFtrZXldLnRvU3RyaW5nKCd1dGY4JykgOiBjaGlsZFtrZXldO1xuICAgICAgICAgIHJldHVybiB0eXBlb2YgY2hpbGRLZXkgPT09ICdvYmplY3QnICYmIGNoaWxkS2V5ICE9PSBudWxsXG4gICAgICAgICAgICA/IF9mbGF0dGVuKGNoaWxkS2V5LCBwYXRoLmNvbmNhdChba2V5XSkpXG4gICAgICAgICAgICA6ICh7IFtwYXRoLmNvbmNhdChba2V5XSkuam9pbignLicpXTogY2hpbGRLZXkgfSk7XG4gICAgICAgIH0pKTtcbiAgICB9KG9iamVjdCksXG4gICk7XG59XG5cbi8qKlxuICogRGVjb2RlcyBlbmNvZGVkIHNwZWNpYWwgdmFsdWVzIChwaHlzaWNhbFJlc291cmNlSWQpXG4gKi9cbmZ1bmN0aW9uIGRlY29kZVNwZWNpYWxWYWx1ZXMob2JqZWN0OiBvYmplY3QsIHBoeXNpY2FsUmVzb3VyY2VJZDogc3RyaW5nKSB7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iamVjdCksIChfaywgdikgPT4ge1xuICAgIHN3aXRjaCAodikge1xuICAgICAgY2FzZSBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0U6XG4gICAgICAgIHJldHVybiBwaHlzaWNhbFJlc291cmNlSWQ7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdjtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIEZpbHRlcnMgdGhlIGtleXMgb2YgYW4gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBmaWx0ZXJLZXlzKG9iamVjdDogb2JqZWN0LCBwcmVkOiAoa2V5OiBzdHJpbmcpID0+IGJvb2xlYW4pIHtcbiAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iamVjdClcbiAgICAucmVkdWNlKFxuICAgICAgKGFjYywgW2ssIHZdKSA9PiBwcmVkKGspXG4gICAgICAgID8geyAuLi5hY2MsIFtrXTogdiB9XG4gICAgICAgIDogYWNjLFxuICAgICAge30sXG4gICAgKTtcbn1cblxubGV0IGxhdGVzdFNka0luc3RhbGxlZCA9IGZhbHNlO1xuXG5leHBvcnQgZnVuY3Rpb24gZm9yY2VTZGtJbnN0YWxsYXRpb24oKSB7XG4gIGxhdGVzdFNka0luc3RhbGxlZCA9IGZhbHNlO1xufVxuXG4vKipcbiAqIEluc3RhbGxzIGxhdGVzdCBBV1MgU0RLIHYyXG4gKi9cbmZ1bmN0aW9uIGluc3RhbGxMYXRlc3RTZGsoKTogdm9pZCB7XG4gIGNvbnNvbGUubG9nKCdJbnN0YWxsaW5nIGxhdGVzdCBBV1MgU0RLIHYyJyk7XG4gIC8vIEJvdGggSE9NRSBhbmQgLS1wcmVmaXggYXJlIG5lZWRlZCBoZXJlIGJlY2F1c2UgL3RtcCBpcyB0aGUgb25seSB3cml0YWJsZSBsb2NhdGlvblxuICBleGVjU3luYygnSE9NRT0vdG1wIG5wbSBpbnN0YWxsIGF3cy1zZGtAMiAtLXByb2R1Y3Rpb24gLS1uby1wYWNrYWdlLWxvY2sgLS1uby1zYXZlIC0tcHJlZml4IC90bXAnKTtcbiAgbGF0ZXN0U2RrSW5zdGFsbGVkID0gdHJ1ZTtcbn1cblxuLy8gbm8gY3VycmVudGx5IHBhdGNoZWQgc2VydmljZXNcbmNvbnN0IHBhdGNoZWRTZXJ2aWNlczogeyBzZXJ2aWNlTmFtZTogc3RyaW5nOyBhcGlWZXJzaW9uczogc3RyaW5nW10gfVtdID0gW107XG4vKipcbiAqIFBhdGNoZXMgdGhlIEFXUyBTREsgYnkgbG9hZGluZyBzZXJ2aWNlIG1vZGVscyBpbiB0aGUgc2FtZSBtYW5uZXIgYXMgdGhlIGFjdHVhbCBTREtcbiAqL1xuZnVuY3Rpb24gcGF0Y2hTZGsoYXdzU2RrOiBhbnkpOiBhbnkge1xuICBjb25zdCBhcGlMb2FkZXIgPSBhd3NTZGsuYXBpTG9hZGVyO1xuICBwYXRjaGVkU2VydmljZXMuZm9yRWFjaCgoeyBzZXJ2aWNlTmFtZSwgYXBpVmVyc2lvbnMgfSkgPT4ge1xuICAgIGNvbnN0IGxvd2VyU2VydmljZU5hbWUgPSBzZXJ2aWNlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICghYXdzU2RrLlNlcnZpY2UuaGFzU2VydmljZShsb3dlclNlcnZpY2VOYW1lKSkge1xuICAgICAgYXBpTG9hZGVyLnNlcnZpY2VzW2xvd2VyU2VydmljZU5hbWVdID0ge307XG4gICAgICBhd3NTZGtbc2VydmljZU5hbWVdID0gYXdzU2RrLlNlcnZpY2UuZGVmaW5lU2VydmljZShsb3dlclNlcnZpY2VOYW1lLCBhcGlWZXJzaW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3c1Nkay5TZXJ2aWNlLmFkZFZlcnNpb25zKGF3c1Nka1tzZXJ2aWNlTmFtZV0sIGFwaVZlcnNpb25zKTtcbiAgICB9XG4gICAgYXBpVmVyc2lvbnMuZm9yRWFjaChhcGlWZXJzaW9uID0+IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcGlMb2FkZXIuc2VydmljZXNbbG93ZXJTZXJ2aWNlTmFtZV0sIGFwaVZlcnNpb24sIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgICAgY29uc3QgbW9kZWxGaWxlUHJlZml4ID0gYGF3cy1zZGstcGF0Y2gvJHtsb3dlclNlcnZpY2VOYW1lfS0ke2FwaVZlcnNpb259YDtcbiAgICAgICAgICBjb25zdCBtb2RlbCA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGpvaW4oX19kaXJuYW1lLCBgJHttb2RlbEZpbGVQcmVmaXh9LnNlcnZpY2UuanNvbmApLCAndXRmLTgnKSk7XG4gICAgICAgICAgbW9kZWwucGFnaW5hdG9ycyA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGpvaW4oX19kaXJuYW1lLCBgJHttb2RlbEZpbGVQcmVmaXh9LnBhZ2luYXRvcnMuanNvbmApLCAndXRmLTgnKSkucGFnaW5hdGlvbjtcbiAgICAgICAgICByZXR1cm4gbW9kZWw7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIGF3c1Nkaztcbn1cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cywgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpIHtcbiAgdHJ5IHtcbiAgICBsZXQgQVdTOiBhbnk7XG4gICAgaWYgKCFsYXRlc3RTZGtJbnN0YWxsZWQgJiYgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkluc3RhbGxMYXRlc3RBd3NTZGsgPT09ICd0cnVlJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW5zdGFsbExhdGVzdFNkaygpO1xuICAgICAgICBBV1MgPSByZXF1aXJlKCcvdG1wL25vZGVfbW9kdWxlcy9hd3Mtc2RrJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBGYWlsZWQgdG8gaW5zdGFsbCBsYXRlc3QgQVdTIFNESyB2MjogJHtlfWApO1xuICAgICAgICBBV1MgPSByZXF1aXJlKCdhd3Mtc2RrJyk7IC8vIEZhbGxiYWNrIHRvIHByZS1pbnN0YWxsZWQgdmVyc2lvblxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobGF0ZXN0U2RrSW5zdGFsbGVkKSB7XG4gICAgICBBV1MgPSByZXF1aXJlKCcvdG1wL25vZGVfbW9kdWxlcy9hd3Mtc2RrJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIEFXUyA9IHJlcXVpcmUoJ2F3cy1zZGsnKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIEFXUyA9IHBhdGNoU2RrKEFXUyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5sb2coYEZhaWxlZCB0byBwYXRjaCBBV1MgU0RLOiAke2V9LiBQcm9jZWVkaW5nIHdpdGggdGhlIGluc3RhbGxlZCBjb3B5LmApO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG4gICAgY29uc29sZS5sb2coJ0FXUyBTREsgVkVSU0lPTjogJyArIEFXUy5WRVJTSU9OKTtcblxuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGUpO1xuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5VcGRhdGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5VcGRhdGUpO1xuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGUpO1xuICAgIC8vIERlZmF1bHQgcGh5c2ljYWwgcmVzb3VyY2UgaWRcbiAgICBsZXQgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmc7XG4gICAgc3dpdGNoIChldmVudC5SZXF1ZXN0VHlwZSkge1xuICAgICAgY2FzZSAnQ3JlYXRlJzpcbiAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkNyZWF0ZT8ucGh5c2ljYWxSZXNvdXJjZUlkPy5pZCA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGU/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuTG9naWNhbFJlc291cmNlSWQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnVXBkYXRlJzpcbiAgICAgIGNhc2UgJ0RlbGV0ZSc6XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllc1tldmVudC5SZXF1ZXN0VHlwZV0/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz8gZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBsZXQgZmxhdERhdGE6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBsZXQgZGF0YTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIGNvbnN0IGNhbGw6IEF3c1Nka0NhbGwgfCB1bmRlZmluZWQgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXNbZXZlbnQuUmVxdWVzdFR5cGVdO1xuXG4gICAgaWYgKGNhbGwpIHtcblxuICAgICAgbGV0IGNyZWRlbnRpYWxzO1xuICAgICAgaWYgKGNhbGwuYXNzdW1lZFJvbGVBcm4pIHtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gKG5ldyBEYXRlKCkpLmdldFRpbWUoKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgUm9sZUFybjogY2FsbC5hc3N1bWVkUm9sZUFybixcbiAgICAgICAgICBSb2xlU2Vzc2lvbk5hbWU6IGAke3RpbWVzdGFtcH0tJHtwaHlzaWNhbFJlc291cmNlSWR9YC5zdWJzdHJpbmcoMCwgNjQpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNyZWRlbnRpYWxzID0gbmV3IEFXUy5DaGFpbmFibGVUZW1wb3JhcnlDcmVkZW50aWFscyh7XG4gICAgICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChBV1MsIGNhbGwuc2VydmljZSkpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoYFNlcnZpY2UgJHtjYWxsLnNlcnZpY2V9IGRvZXMgbm90IGV4aXN0IGluIEFXUyBTREsgdmVyc2lvbiAke0FXUy5WRVJTSU9OfS5gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGF3c1NlcnZpY2UgPSBuZXcgKEFXUyBhcyBhbnkpW2NhbGwuc2VydmljZV0oe1xuICAgICAgICBhcGlWZXJzaW9uOiBjYWxsLmFwaVZlcnNpb24sXG4gICAgICAgIGNyZWRlbnRpYWxzOiBjcmVkZW50aWFscyxcbiAgICAgICAgcmVnaW9uOiBjYWxsLnJlZ2lvbixcbiAgICAgIH0pO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF3c1NlcnZpY2VbY2FsbC5hY3Rpb25dKFxuICAgICAgICAgIGNhbGwucGFyYW1ldGVycyAmJiBkZWNvZGVTcGVjaWFsVmFsdWVzKGNhbGwucGFyYW1ldGVycywgcGh5c2ljYWxSZXNvdXJjZUlkKSkucHJvbWlzZSgpO1xuICAgICAgICBmbGF0RGF0YSA9IHtcbiAgICAgICAgICBhcGlWZXJzaW9uOiBhd3NTZXJ2aWNlLmNvbmZpZy5hcGlWZXJzaW9uLCAvLyBGb3IgdGVzdCBwdXJwb3NlczogY2hlY2sgaWYgYXBpVmVyc2lvbiB3YXMgY29ycmVjdGx5IHBhc3NlZC5cbiAgICAgICAgICByZWdpb246IGF3c1NlcnZpY2UuY29uZmlnLnJlZ2lvbiwgLy8gRm9yIHRlc3QgcHVycG9zZXM6IGNoZWNrIGlmIHJlZ2lvbiB3YXMgY29ycmVjdGx5IHBhc3NlZC5cbiAgICAgICAgICAuLi5mbGF0dGVuKHJlc3BvbnNlKSxcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgb3V0cHV0UGF0aHM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAoY2FsbC5vdXRwdXRQYXRoKSB7XG4gICAgICAgICAgb3V0cHV0UGF0aHMgPSBbY2FsbC5vdXRwdXRQYXRoXTtcbiAgICAgICAgfSBlbHNlIGlmIChjYWxsLm91dHB1dFBhdGhzKSB7XG4gICAgICAgICAgb3V0cHV0UGF0aHMgPSBjYWxsLm91dHB1dFBhdGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG91dHB1dFBhdGhzKSB7XG4gICAgICAgICAgZGF0YSA9IGZpbHRlcktleXMoZmxhdERhdGEsIHN0YXJ0c1dpdGhPbmVPZihvdXRwdXRQYXRocykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGEgPSBmbGF0RGF0YTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoIWNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nIHx8ICFuZXcgUmVnRXhwKGNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nKS50ZXN0KGUuY29kZSkpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjYWxsLnBoeXNpY2FsUmVzb3VyY2VJZD8ucmVzcG9uc2VQYXRoKSB7XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGZsYXREYXRhW2NhbGwucGh5c2ljYWxSZXNvdXJjZUlkLnJlc3BvbnNlUGF0aF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgcmVzcG9uZCgnU1VDQ0VTUycsICdPSycsIHBoeXNpY2FsUmVzb3VyY2VJZCwgZGF0YSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmxvZyhlKTtcbiAgICBhd2FpdCByZXNwb25kKCdGQUlMRUQnLCBlLm1lc3NhZ2UgfHwgJ0ludGVybmFsIEVycm9yJywgY29udGV4dC5sb2dTdHJlYW1OYW1lLCB7fSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNwb25kKHJlc3BvbnNlU3RhdHVzOiBzdHJpbmcsIHJlYXNvbjogc3RyaW5nLCBwaHlzaWNhbFJlc291cmNlSWQ6IHN0cmluZywgZGF0YTogYW55KSB7XG4gICAgY29uc3QgcmVzcG9uc2VCb2R5ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgU3RhdHVzOiByZXNwb25zZVN0YXR1cyxcbiAgICAgIFJlYXNvbjogcmVhc29uLFxuICAgICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBwaHlzaWNhbFJlc291cmNlSWQsXG4gICAgICBTdGFja0lkOiBldmVudC5TdGFja0lkLFxuICAgICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgICBOb0VjaG86IGZhbHNlLFxuICAgICAgRGF0YTogZGF0YSxcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKCdSZXNwb25kaW5nJywgcmVzcG9uc2VCb2R5KTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgcGFyc2VkVXJsID0gcmVxdWlyZSgndXJsJykucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgICAgbWV0aG9kOiAnUFVUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICcnLCAnY29udGVudC1sZW5ndGgnOiByZXNwb25zZUJvZHkubGVuZ3RoIH0sXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnaHR0cHMnKS5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCByZXNvbHZlKTtcbiAgICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgICByZXF1ZXN0LndyaXRlKHJlc3BvbnNlQm9keSk7XG4gICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWNvZGVDYWxsKGNhbGw6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICBpZiAoIWNhbGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICByZXR1cm4gSlNPTi5wYXJzZShjYWxsKTtcbn1cblxuZnVuY3Rpb24gc3RhcnRzV2l0aE9uZU9mKHNlYXJjaFN0cmluZ3M6IHN0cmluZ1tdKTogKHN0cmluZzogc3RyaW5nKSA9PiBib29sZWFuIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmluZzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBzZWFyY2hTdHJpbmcgb2Ygc2VhcmNoU3RyaW5ncykge1xuICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKHNlYXJjaFN0cmluZykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/aws-cdk-sdk-js.template.json b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/aws-cdk-sdk-js.template.json new file mode 100644 index 0000000000000..c5eefae4225da --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/aws-cdk-sdk-js.template.json @@ -0,0 +1,316 @@ +{ + "Resources": { + "TopicBFC7AF6E": { + "Type": "AWS::SNS::Topic" + }, + "PublishCustomResourcePolicyDF696FCA": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PublishCustomResourcePolicyDF696FCA", + "Roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + } + }, + "Publish2E9BDF73": { + "Type": "Custom::SNSPublisher", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "AWS679f53fac002430cb0da5b7982bd22872D164C4C", + "Arn" + ] + }, + "Create": { + "Fn::Join": [ + "", + [ + "{\"service\":\"SNS\",\"action\":\"publish\",\"parameters\":{\"Message\":\"hello\",\"TopicArn\":\"", + { + "Ref": "TopicBFC7AF6E" + }, + "\"},\"physicalResourceId\":{\"id\":\"", + { + "Ref": "TopicBFC7AF6E" + }, + "\"}}" + ] + ] + }, + "Update": { + "Fn::Join": [ + "", + [ + "{\"service\":\"SNS\",\"action\":\"publish\",\"parameters\":{\"Message\":\"hello\",\"TopicArn\":\"", + { + "Ref": "TopicBFC7AF6E" + }, + "\"},\"physicalResourceId\":{\"id\":\"", + { + "Ref": "TopicBFC7AF6E" + }, + "\"}}" + ] + ] + }, + "InstallLatestAwsSdk": true + }, + "DependsOn": [ + "PublishCustomResourcePolicyDF696FCA" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "AWS679f53fac002430cb0da5b7982bd22872D164C4C": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3BucketB21FB59F" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3VersionKey73D4F058" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3VersionKey73D4F058" + } + ] + } + ] + } + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs12.x", + "Timeout": 120 + }, + "DependsOn": [ + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + ] + }, + "ListTopicsCustomResourcePolicy31A8396A": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "sns:ListTopics", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ListTopicsCustomResourcePolicy31A8396A", + "Roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + }, + "DependsOn": [ + "TopicBFC7AF6E" + ] + }, + "ListTopicsCE1E0341": { + "Type": "Custom::AWS", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "AWS679f53fac002430cb0da5b7982bd22872D164C4C", + "Arn" + ] + }, + "Create": "{\"service\":\"SNS\",\"action\":\"listTopics\",\"physicalResourceId\":{\"responsePath\":\"Topics.0.TopicArn\"}}", + "Update": "{\"service\":\"SNS\",\"action\":\"listTopics\",\"physicalResourceId\":{\"responsePath\":\"Topics.0.TopicArn\"}}", + "InstallLatestAwsSdk": true + }, + "DependsOn": [ + "ListTopicsCustomResourcePolicy31A8396A", + "TopicBFC7AF6E" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DummyParameter53662B67": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Type": "String", + "Value": "1337" + } + }, + "GetParameterCustomResourcePolicyD8E5D455": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:GetParameter", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "GetParameterCustomResourcePolicyD8E5D455", + "Roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + } + }, + "GetParameter42B0A00E": { + "Type": "Custom::SSMParameter", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "AWS679f53fac002430cb0da5b7982bd22872D164C4C", + "Arn" + ] + }, + "Create": { + "Fn::Join": [ + "", + [ + "{\"service\":\"SSM\",\"action\":\"getParameter\",\"parameters\":{\"Name\":\"", + { + "Ref": "DummyParameter53662B67" + }, + "\",\"WithDecryption\":true},\"physicalResourceId\":{\"responsePath\":\"Parameter.ARN\"}}" + ] + ] + }, + "Update": { + "Fn::Join": [ + "", + [ + "{\"service\":\"SSM\",\"action\":\"getParameter\",\"parameters\":{\"Name\":\"", + { + "Ref": "DummyParameter53662B67" + }, + "\",\"WithDecryption\":true},\"physicalResourceId\":{\"responsePath\":\"Parameter.ARN\"}}" + ] + ] + }, + "InstallLatestAwsSdk": true + }, + "DependsOn": [ + "GetParameterCustomResourcePolicyD8E5D455" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3BucketB21FB59F": { + "Type": "String", + "Description": "S3 bucket for asset \"9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90\"" + }, + "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3VersionKey73D4F058": { + "Type": "String", + "Description": "S3 key for asset version \"9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90\"" + }, + "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90ArtifactHashC00C7285": { + "Type": "String", + "Description": "Artifact hash for asset \"9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90\"" + } + }, + "Outputs": { + "MessageId": { + "Value": { + "Fn::GetAtt": [ + "Publish2E9BDF73", + "MessageId" + ] + } + }, + "TopicArn": { + "Value": { + "Fn::GetAtt": [ + "ListTopicsCE1E0341", + "Topics.0.TopicArn" + ] + } + }, + "ParameterValue": { + "Value": { + "Fn::GetAtt": [ + "GetParameter42B0A00E", + "Parameter.Value" + ] + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/cdk.out b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/cdk.out new file mode 100644 index 0000000000000..90bef2e09ad39 --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"17.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/integ.json b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/integ.json new file mode 100644 index 0000000000000..34d1c61e45426 --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/integ.json @@ -0,0 +1,14 @@ +{ + "version": "18.0.0", + "testCases": { + "custom-resources/test/aws-custom-resource/integ.aws-custom-resource": { + "stacks": [ + "aws-cdk-sdk-js" + ], + "diffAssets": false, + "stackUpdateWorkflow": true + } + }, + "synthContext": {}, + "enableLookups": false +} \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/manifest.json b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/manifest.json new file mode 100644 index 0000000000000..85aa00eb8d36e --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/manifest.json @@ -0,0 +1,132 @@ +{ + "version": "17.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "aws-cdk-sdk-js": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-sdk-js.template.json", + "validateOnSynth": false + }, + "metadata": { + "/aws-cdk-sdk-js": [ + { + "type": "aws:cdk:asset", + "data": { + "path": "asset.9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90", + "id": "9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90", + "packaging": "zip", + "sourceHash": "9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90", + "s3BucketParameter": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3BucketB21FB59F", + "s3KeyParameter": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3VersionKey73D4F058", + "artifactHashParameter": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90ArtifactHashC00C7285" + } + } + ], + "/aws-cdk-sdk-js/Topic/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TopicBFC7AF6E" + } + ], + "/aws-cdk-sdk-js/Publish/CustomResourcePolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PublishCustomResourcePolicyDF696FCA" + } + ], + "/aws-cdk-sdk-js/Publish/Resource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "Publish2E9BDF73" + } + ], + "/aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ], + "/aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AWS679f53fac002430cb0da5b7982bd22872D164C4C" + } + ], + "/aws-cdk-sdk-js/AssetParameters/9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/S3Bucket": [ + { + "type": "aws:cdk:logicalId", + "data": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3BucketB21FB59F" + } + ], + "/aws-cdk-sdk-js/AssetParameters/9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/S3VersionKey": [ + { + "type": "aws:cdk:logicalId", + "data": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3VersionKey73D4F058" + } + ], + "/aws-cdk-sdk-js/AssetParameters/9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/ArtifactHash": [ + { + "type": "aws:cdk:logicalId", + "data": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90ArtifactHashC00C7285" + } + ], + "/aws-cdk-sdk-js/ListTopics/CustomResourcePolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ListTopicsCustomResourcePolicy31A8396A" + } + ], + "/aws-cdk-sdk-js/ListTopics/Resource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "ListTopicsCE1E0341" + } + ], + "/aws-cdk-sdk-js/DummyParameter/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DummyParameter53662B67" + } + ], + "/aws-cdk-sdk-js/GetParameter/CustomResourcePolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "GetParameterCustomResourcePolicyD8E5D455" + } + ], + "/aws-cdk-sdk-js/GetParameter/Resource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "GetParameter42B0A00E" + } + ], + "/aws-cdk-sdk-js/MessageId": [ + { + "type": "aws:cdk:logicalId", + "data": "MessageId" + } + ], + "/aws-cdk-sdk-js/TopicArn": [ + { + "type": "aws:cdk:logicalId", + "data": "TopicArn" + } + ], + "/aws-cdk-sdk-js/ParameterValue": [ + { + "type": "aws:cdk:logicalId", + "data": "ParameterValue" + } + ] + }, + "displayName": "aws-cdk-sdk-js" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/tree.json b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/tree.json new file mode 100644 index 0000000000000..2849b976116eb --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.integ.snapshot/tree.json @@ -0,0 +1,516 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "@aws-cdk/core.Construct", + "version": "0.0.0" + } + }, + "aws-cdk-sdk-js": { + "id": "aws-cdk-sdk-js", + "path": "aws-cdk-sdk-js", + "children": { + "Topic": { + "id": "Topic", + "path": "aws-cdk-sdk-js/Topic", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/Topic/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SNS::Topic", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-sns.CfnTopic", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-sns.Topic", + "version": "0.0.0" + } + }, + "Publish": { + "id": "Publish", + "path": "aws-cdk-sdk-js/Publish", + "children": { + "Provider": { + "id": "Provider", + "path": "aws-cdk-sdk-js/Publish/Provider", + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.SingletonFunction", + "version": "0.0.0" + } + }, + "CustomResourcePolicy": { + "id": "CustomResourcePolicy", + "path": "aws-cdk-sdk-js/Publish/CustomResourcePolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/Publish/CustomResourcePolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "PublishCustomResourcePolicyDF696FCA", + "roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/Publish/Resource", + "children": { + "Default": { + "id": "Default", + "path": "aws-cdk-sdk-js/Publish/Resource/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/custom-resources.AwsCustomResource", + "version": "0.0.0" + } + }, + "AWS679f53fac002430cb0da5b7982bd2287": { + "id": "AWS679f53fac002430cb0da5b7982bd2287", + "path": "aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287/Code/AssetBucket", + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3-assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/AWS679f53fac002430cb0da5b7982bd2287/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Ref": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3BucketB21FB59F" + }, + "s3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3VersionKey73D4F058" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90S3VersionKey73D4F058" + } + ] + } + ] + } + ] + ] + } + }, + "role": { + "Fn::GetAtt": [ + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs12.x", + "timeout": 120 + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AssetParameters": { + "id": "AssetParameters", + "path": "aws-cdk-sdk-js/AssetParameters", + "children": { + "9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90": { + "id": "9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90", + "path": "aws-cdk-sdk-js/AssetParameters/9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90", + "children": { + "S3Bucket": { + "id": "S3Bucket", + "path": "aws-cdk-sdk-js/AssetParameters/9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/S3Bucket", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "S3VersionKey": { + "id": "S3VersionKey", + "path": "aws-cdk-sdk-js/AssetParameters/9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/S3VersionKey", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "ArtifactHash": { + "id": "ArtifactHash", + "path": "aws-cdk-sdk-js/AssetParameters/9d784cf317cead201dfe56ed0404d6d23eba6d499ca7354138230c2267f2fe90/ArtifactHash", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Construct", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Construct", + "version": "0.0.0" + } + }, + "ListTopics": { + "id": "ListTopics", + "path": "aws-cdk-sdk-js/ListTopics", + "children": { + "Provider": { + "id": "Provider", + "path": "aws-cdk-sdk-js/ListTopics/Provider", + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.SingletonFunction", + "version": "0.0.0" + } + }, + "CustomResourcePolicy": { + "id": "CustomResourcePolicy", + "path": "aws-cdk-sdk-js/ListTopics/CustomResourcePolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/ListTopics/CustomResourcePolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "sns:ListTopics", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "ListTopicsCustomResourcePolicy31A8396A", + "roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/ListTopics/Resource", + "children": { + "Default": { + "id": "Default", + "path": "aws-cdk-sdk-js/ListTopics/Resource/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/custom-resources.AwsCustomResource", + "version": "0.0.0" + } + }, + "DummyParameter": { + "id": "DummyParameter", + "path": "aws-cdk-sdk-js/DummyParameter", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/DummyParameter/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SSM::Parameter", + "aws:cdk:cloudformation:props": { + "type": "String", + "value": "1337" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ssm.CfnParameter", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ssm.StringParameter", + "version": "0.0.0" + } + }, + "GetParameter": { + "id": "GetParameter", + "path": "aws-cdk-sdk-js/GetParameter", + "children": { + "Provider": { + "id": "Provider", + "path": "aws-cdk-sdk-js/GetParameter/Provider", + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.SingletonFunction", + "version": "0.0.0" + } + }, + "CustomResourcePolicy": { + "id": "CustomResourcePolicy", + "path": "aws-cdk-sdk-js/GetParameter/CustomResourcePolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/GetParameter/CustomResourcePolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "ssm:GetParameter", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "GetParameterCustomResourcePolicyD8E5D455", + "roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-sdk-js/GetParameter/Resource", + "children": { + "Default": { + "id": "Default", + "path": "aws-cdk-sdk-js/GetParameter/Resource/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/custom-resources.AwsCustomResource", + "version": "0.0.0" + } + }, + "MessageId": { + "id": "MessageId", + "path": "aws-cdk-sdk-js/MessageId", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + }, + "TopicArn": { + "id": "TopicArn", + "path": "aws-cdk-sdk-js/TopicArn", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + }, + "ParameterValue": { + "id": "ParameterValue", + "path": "aws-cdk-sdk-js/ParameterValue", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resources/test/provider-framework/integration-test-fixtures/s3-file-handler/index.ts b/packages/@aws-cdk/custom-resources/test/provider-framework/integration-test-fixtures/s3-file-handler/index.ts index 0e52b4ad66e3f..de12c193aa637 100644 --- a/packages/@aws-cdk/custom-resources/test/provider-framework/integration-test-fixtures/s3-file-handler/index.ts +++ b/packages/@aws-cdk/custom-resources/test/provider-framework/integration-test-fixtures/s3-file-handler/index.ts @@ -28,7 +28,7 @@ export async function putObject(event: AWSCDKAsyncCustomResource.OnEventRequest) // trim trailing `/` if (objectKey.startsWith('/')) { - objectKey = objectKey.substr(1); + objectKey = objectKey.slice(1); } const publicRead = event.ResourceProperties[api.PROP_PUBLIC] || false; diff --git a/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.d.ts b/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.d.ts new file mode 100644 index 0000000000000..9a560ded1cf9c --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.d.ts @@ -0,0 +1,7 @@ +export declare const PROP_BUCKET_NAME = "BucketName"; +export declare const PROP_OBJECT_KEY = "ObjectKey"; +export declare const PROP_CONTENTS = "Contents"; +export declare const PROP_PUBLIC = "PublicRead"; +export declare const ATTR_ETAG = "ETag"; +export declare const ATTR_URL = "URL"; +export declare const ATTR_OBJECT_KEY = "ObjectKey"; diff --git a/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.js b/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.js new file mode 100644 index 0000000000000..508f0228906ca --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ATTR_OBJECT_KEY = exports.ATTR_URL = exports.ATTR_ETAG = exports.PROP_PUBLIC = exports.PROP_CONTENTS = exports.PROP_OBJECT_KEY = exports.PROP_BUCKET_NAME = void 0; +exports.PROP_BUCKET_NAME = 'BucketName'; +exports.PROP_OBJECT_KEY = 'ObjectKey'; +exports.PROP_CONTENTS = 'Contents'; +exports.PROP_PUBLIC = 'PublicRead'; +exports.ATTR_ETAG = 'ETag'; +exports.ATTR_URL = 'URL'; +exports.ATTR_OBJECT_KEY = 'ObjectKey'; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFhLFFBQUEsZ0JBQWdCLEdBQUcsWUFBWSxDQUFDO0FBQ2hDLFFBQUEsZUFBZSxHQUFHLFdBQVcsQ0FBQztBQUM5QixRQUFBLGFBQWEsR0FBRyxVQUFVLENBQUM7QUFDM0IsUUFBQSxXQUFXLEdBQUcsWUFBWSxDQUFDO0FBRTNCLFFBQUEsU0FBUyxHQUFHLE1BQU0sQ0FBQztBQUNuQixRQUFBLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDakIsUUFBQSxlQUFlLEdBQUcsV0FBVyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IFBST1BfQlVDS0VUX05BTUUgPSAnQnVja2V0TmFtZSc7XG5leHBvcnQgY29uc3QgUFJPUF9PQkpFQ1RfS0VZID0gJ09iamVjdEtleSc7XG5leHBvcnQgY29uc3QgUFJPUF9DT05URU5UUyA9ICdDb250ZW50cyc7XG5leHBvcnQgY29uc3QgUFJPUF9QVUJMSUMgPSAnUHVibGljUmVhZCc7XG5cbmV4cG9ydCBjb25zdCBBVFRSX0VUQUcgPSAnRVRhZyc7XG5leHBvcnQgY29uc3QgQVRUUl9VUkwgPSAnVVJMJztcbmV4cG9ydCBjb25zdCBBVFRSX09CSkVDVF9LRVkgPSAnT2JqZWN0S2V5JztcbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.ts b/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.ts new file mode 100644 index 0000000000000..79b07bda5a43b --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/api.ts @@ -0,0 +1,8 @@ +export const PROP_BUCKET_NAME = 'BucketName'; +export const PROP_OBJECT_KEY = 'ObjectKey'; +export const PROP_CONTENTS = 'Contents'; +export const PROP_PUBLIC = 'PublicRead'; + +export const ATTR_ETAG = 'ETag'; +export const ATTR_URL = 'URL'; +export const ATTR_OBJECT_KEY = 'ObjectKey'; diff --git a/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/index.d.ts b/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/index.d.ts new file mode 100644 index 0000000000000..c535c997c1e97 --- /dev/null +++ b/packages/@aws-cdk/custom-resources/test/provider-framework/provider.integ.snapshot/asset.4395b44839a882f77d9467a415b5a45ab1eee138cf0d9ce078d6b366890040aa/index.d.ts @@ -0,0 +1,3 @@ +export declare function onEvent(event: AWSCDKAsyncCustomResource.OnEventRequest): Promise