├── .github ├── codecov.yml ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── auto-approve.yml │ ├── auto-merge.yml │ ├── release-sync.yml │ ├── release.yml │ ├── security-audit.yml │ └── status-checks.yml ├── .gitignore ├── ARCHITECTURE.MD ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── Justfile ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── docs ├── 1_overview.md ├── 2_conditions.md └── 3_lookups.md ├── rust-toolchain.toml ├── src ├── cdk │ ├── mod.rs │ └── schema.rs ├── code │ └── mod.rs ├── errors │ ├── mod.rs │ └── tests.rs ├── ir │ ├── README.md │ ├── conditions │ │ ├── mod.rs │ │ └── tests.rs │ ├── constructor │ ├── importer │ │ ├── mod.rs │ │ └── tests.rs │ ├── mappings │ │ ├── mod.rs │ │ └── tests.rs │ ├── mod.rs │ ├── outputs │ │ ├── mod.rs │ │ └── tests.rs │ ├── reference │ │ └── mod.rs │ ├── resources │ │ ├── mod.rs │ │ └── tests.rs │ └── sub │ │ ├── mod.rs │ │ └── tests.rs ├── lib.rs ├── main.rs ├── parser │ ├── README.md │ ├── condition │ │ ├── mod.rs │ │ └── tests.rs │ ├── intrinsics │ │ └── mod.rs │ ├── lookup_table │ │ └── mod.rs │ ├── mod.rs │ ├── output │ │ └── mod.rs │ ├── parameters │ │ ├── mod.rs │ │ └── tests.rs │ └── resource │ │ ├── mod.rs │ │ └── tests.rs ├── primitives │ ├── mod.rs │ └── tests.rs ├── specification │ ├── cdk-resources.json │ └── cdk-types.json ├── synthesizer │ ├── README.md │ ├── csharp │ │ ├── mod.rs │ │ └── tests.rs │ ├── golang │ │ ├── mod.rs │ │ └── tests.rs │ ├── java │ │ ├── mod.rs │ │ └── tests.rs │ ├── mod.rs │ ├── python │ │ ├── mod.rs │ │ └── tests.rs │ └── typescript │ │ ├── mod.rs │ │ └── tests.rs └── util.rs └── tests ├── cdk_app_code_writers.rs ├── end-to-end.rs ├── end-to-end ├── README.md ├── app-boilerplate-files │ ├── README.md │ ├── csharp │ │ ├── CSharp.csproj │ │ └── setup-and-synth.sh │ ├── golang │ │ ├── go.mod │ │ ├── go.sum │ │ └── setup-and-synth.sh │ ├── java │ │ ├── pom.xml │ │ └── setup-and-synth.sh │ ├── python │ │ ├── requirements.txt │ │ └── setup-and-synth.sh │ └── typescript │ │ ├── package.json │ │ └── setup-and-synth.sh ├── batch │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── bucket │ ├── csharp │ │ ├── Program.cs │ │ └── Stack.cs │ ├── golang │ │ ├── app.go │ │ └── stack.go │ ├── java │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── app.ts │ │ └── stack.ts ├── cloudwatch │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── config │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── documentdb │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── ec2 │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── ec2_encryption │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── ecs │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── efs │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── groundstation │ └── template.json ├── resource_w_json_type_properties │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── sam_nodejs_lambda │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.go │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── sam_nodejs_lambda_arr_transform │ ├── csharp │ │ └── Stack.cs │ ├── golang │ │ └── stack.go │ ├── java │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ └── Stack.java │ ├── python │ │ └── stack.py │ ├── template.json │ └── typescript │ │ └── stack.ts ├── simple │ ├── create_first.json │ ├── csharp │ │ ├── Program.cs │ │ ├── Stack.cs │ │ ├── Stack.diff │ │ └── Stack.template.json │ ├── golang │ │ └── stack.go │ ├── java │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── myorg │ │ │ ├── MyApp.java │ │ │ └── Stack.java │ ├── python │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.py │ │ └── stack.py │ ├── template.json │ └── typescript │ │ ├── Stack.diff │ │ ├── Stack.template.json │ │ ├── app.ts │ │ └── stack.ts ├── tsconfig.json └── vpc │ ├── csharp │ ├── Program.cs │ ├── Stack.cs │ ├── Stack.diff │ └── Stack.template.json │ ├── golang │ ├── Stack.diff │ ├── Stack.template.json │ ├── app.go │ └── stack.go │ ├── java │ ├── Stack.diff │ ├── Stack.template.json │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── myorg │ │ ├── MyApp.java │ │ └── Stack.java │ ├── python │ ├── Stack.diff │ ├── Stack.template.json │ ├── app.py │ └── stack.py │ ├── template.json │ └── typescript │ ├── Stack.diff │ ├── Stack.template.json │ ├── app.ts │ └── stack.ts ├── json.rs └── tests.rs /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | precision: 1 3 | round: nearest 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 2% # Allow coverage to drop slightly 9 | removed_code_behavior: adjust_base 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 5% # Allow coverage to drop slightly 14 | removed_code_behavior: adjust_base 15 | 16 | comment: 17 | layout: header, components, diff, files, footer 18 | behavior: new 19 | 20 | component_management: 21 | individual_components: 22 | - component_id: parser 23 | name: Parser 24 | paths: 25 | - src/parser/** 26 | - component_id: ir 27 | name: Intermediate Representation 28 | paths: 29 | - src/ir/** 30 | - component_id: synthesizer 31 | name: Synthesizers 32 | paths: 33 | - src/synthesizer/** 34 | - component_id: other 35 | name: Other 36 | paths: 37 | - src/errors/** 38 | - src/primitives/** 39 | - src/specification/** 40 | - src/*.rs 41 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | - package-ecosystem: github-actions 5 | directory: / 6 | labels: 7 | - auto-approve 8 | schedule: 9 | interval: daily 10 | 11 | - package-ecosystem: cargo 12 | directory: / 13 | labels: 14 | - auto-approve 15 | schedule: 16 | interval: daily 17 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Fixes # 2 | 3 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 4 | -------------------------------------------------------------------------------- /.github/workflows/auto-approve.yml: -------------------------------------------------------------------------------- 1 | name: auto-approve 2 | on: 3 | pull_request_target: 4 | types: 5 | - labeled 6 | - opened 7 | - synchronize 8 | - reopened 9 | - ready_for_review 10 | jobs: 11 | approve: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | pull-requests: write 15 | if: contains(github.event.pull_request.labels.*.name, 'auto-approve') && ((github.event.pull_request.user.login == 'cdklabs-automation') || (github.event.pull_request.user.login == 'dependabot[bot]')) 16 | steps: 17 | - uses: hmarr/auto-approve-action@v4.0.0 18 | with: 19 | github-token: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /.github/workflows/auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: auto-merge 2 | on: 3 | pull_request_target: 4 | types: 5 | - opened 6 | - reopened 7 | - ready_for_review 8 | - labeled 9 | jobs: 10 | enableAutoMerge: 11 | name: 'Set AutoMerge on PR #${{ github.event.number }}' 12 | runs-on: ubuntu-latest 13 | permissions: 14 | pull-requests: write 15 | contents: write 16 | steps: 17 | - uses: peter-evans/enable-pull-request-automerge@v3 18 | with: 19 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 20 | pull-request-number: ${{ github.event.number }} 21 | merge-method: ${{ contains(github.event.pull_request.labels.*.name, 'pr/no-squash') && 'merge' || 'squash' }} 22 | -------------------------------------------------------------------------------- /.github/workflows/security-audit.yml: -------------------------------------------------------------------------------- 1 | name: security-audit 2 | on: 3 | workflow_dispatch: {} 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | jobs: 8 | audit: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: rustsec/audit-check@v2 13 | with: 14 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # I use intellij, I hate it XD 6 | *.iml 7 | .idea 8 | 9 | # Mac Files 10 | **/*.DS_Store 11 | 12 | # These are backup files generated by rustfmt 13 | **/*.rs.bk 14 | .vscode/ 15 | node_modules/ 16 | 17 | # These are generated files: 18 | /local/* 19 | 20 | # For end-to-end tests 21 | tests/end-to-end-test-snapshots.zip 22 | **/__pycache__/ 23 | **/.venv/ 24 | **/cdk.out/ 25 | **/*working-dir/ 26 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to cdk-from-cfn 2 | 3 | We welcome contributions to the cdk-from-cfn project! This guide will help you get started with contributing. 4 | 5 | ## Development Environment Setup 6 | 7 | ### Prerequisites 8 | - [Rust](https://www.rust-lang.org/tools/install) (Latest stable version) 9 | - [Wasm-Pack](https://github.com/rustwasm/wasm-pack?tab=readme-ov-file) 10 | - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) 11 | - [GitHub Account](https://github.com/join) 12 | 13 | ### Getting the Project 14 | 15 | ```bash 16 | # Clone your fork 17 | gh repo fork cdklabs/cdk-from-cfn 18 | # Or manually clone 19 | git clone https://github.com/YOUR_USERNAME/cdk-from-cfn.git 20 | cd cdk-from-cfn 21 | ``` 22 | 23 | ## Building the Project 24 | ```bash 25 | # build the debug target 26 | cargo build 27 | 28 | # build the release target 29 | cargo build --release 30 | 31 | # build the wasm release 32 | wasm-pack build --all-features --target=nodejs 33 | ``` 34 | 35 | ## Testing the Project 36 | 37 | ```bash 38 | # run all tests 39 | cargo test 40 | 41 | # run clippy to lint 42 | cargo clippy 43 | ``` -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cdk-from-cfn" 3 | version = "0.219.0" 4 | edition = "2021" 5 | rust-version = "1.85" 6 | description = "Turn AWS CloudFormation templates into AWS CDK applications" 7 | license = "MIT OR Apache-2.0" 8 | 9 | repository = "https://github.com/cdklabs/cdk-from-cfn" 10 | homepage = "https://github.com/cdklabs/cdk-from-cfn#readme" 11 | 12 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 13 | 14 | [features] 15 | default = ["golang", "java", "typescript", "python", "csharp"] 16 | # Language support 17 | golang = [] 18 | java = [] 19 | typescript = [] 20 | csharp = [] 21 | python = [] 22 | 23 | [lib] 24 | crate-type = ["cdylib", "lib"] 25 | 26 | [dependencies] 27 | anyhow = "^1.0.98" 28 | base64 = "^0.22.1" 29 | clap = { version = "^4.5.39", features = ["cargo"] } 30 | console_error_panic_hook = { version = "0.1.1", optional = true } 31 | indexmap = { version = "^2.9.0", features = ["serde"] } 32 | nom = "^8.0.0" 33 | numberkit = "^0.1.0" 34 | phf = { version = "^0.11.3", features = ["macros"] } 35 | rustc-hash = { version = "2.1.1", optional = true } 36 | serde = { version = "^1.0.218", features = ["derive"] } 37 | serde-enum-str = "^0.4.0" 38 | serde_with = "^3.12.0" 39 | serde_yaml = "^0.9.34" 40 | thiserror = "^2.0.11" 41 | topological-sort = "^0.2.2" 42 | voca_rs = "^1.15.2" 43 | wasm-bindgen = "^0.2.100" 44 | 45 | [dev-dependencies] 46 | aws-config = "^1.6.3" 47 | aws-sdk-cloudformation = "^1.78.0" 48 | tokio = { version = "1", features = ["full"] } 49 | walkdir = "2.5.0" 50 | zip = "4.0.0" 51 | 52 | [build-dependencies] 53 | indexmap = "^2.9.0" 54 | phf = { version = "^0.11.3", features = ["macros"] } 55 | phf_codegen = "^0.11.3" 56 | rustc-hash = { version = "2.1.1", optional = true } 57 | serde = { version = "^1.0.218", features = ["derive"] } 58 | serde-enum-str = "^0.4.0" 59 | serde_json = "^1.0.140" 60 | serde_with = "^3.12.0" 61 | voca_rs = "^1.15.2" 62 | walkdir = "2.5.0" 63 | zip = "4.0.0" 64 | 65 | [profile.release] 66 | codegen-units = 1 67 | lto = true 68 | opt-level = 3 69 | -------------------------------------------------------------------------------- /Justfile: -------------------------------------------------------------------------------- 1 | alias b := build 2 | alias r := release 3 | 4 | release: build test lint 5 | 6 | build: 7 | cargo build --all-features 8 | 9 | test *TEST: 10 | cargo test {{TEST}} 11 | 12 | lint: fmt clippy 13 | 14 | fmt: 15 | cargo fmt -- --version && cargo fmt --check 16 | 17 | clippy: 18 | cargo clippy --tests -- -Adead-code -Dwarnings -Dclippy::dbg_macro 19 | 20 | test-cov: 21 | cargo llvm-cov --all-features --ignore-filename-regex '^(tests/.*\.rs|.*/tests\.rs)$' --no-fail-fast --lcov --output-path target/lcov.info 22 | 23 | install-tools: 24 | cargo install cargo-llvm-cov -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "1.85" 3 | #targets = [ "x86_64-unknown-linux-gnu", "aarch64-apple-darwin" ] 4 | 5 | profile = "default" 6 | -------------------------------------------------------------------------------- /src/cdk/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | mod schema; 4 | 5 | #[doc(inline)] 6 | pub use schema::*; 7 | 8 | include!(env!("GENERATED_CDK_SCHEMA_PATH")); 9 | -------------------------------------------------------------------------------- /src/errors/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use thiserror::Error; 4 | 5 | #[derive(Debug, Error)] 6 | pub enum Error { 7 | #[error("{message}")] 8 | ImportInstructionError { message: String }, 9 | #[error("{message}")] 10 | ResourceTranslationError { message: String }, 11 | #[error("{message}")] 12 | SubParseError { message: String }, 13 | #[error("{message}")] 14 | ResourceInstructionError { message: String }, 15 | #[error("{message}")] 16 | ResourceTypeError { message: String }, 17 | #[error(transparent)] 18 | YamlParseError { 19 | #[from] 20 | err: serde_yaml::Error, 21 | }, 22 | #[error("{language} is not a supported language")] 23 | UnsupportedLanguageError { language: String }, 24 | #[error(transparent)] 25 | IOError { 26 | #[from] 27 | err: std::io::Error, 28 | }, 29 | #[error("{message}")] 30 | TypeReferenceError { message: String }, 31 | #[error("{message}")] 32 | PrimitiveError { message: String }, 33 | } 34 | 35 | #[cfg(test)] 36 | mod tests; 37 | -------------------------------------------------------------------------------- /src/errors/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use serde::de::Error; 4 | 5 | #[test] 6 | fn test_import_instruction_error() { 7 | let error = crate::Error::ImportInstructionError { 8 | message: "Import instruction error".to_string(), 9 | }; 10 | assert_eq!(error.to_string(), "Import instruction error"); 11 | } 12 | 13 | #[test] 14 | fn test_resource_translation_error() { 15 | let error = crate::Error::ResourceTranslationError { 16 | message: "Resource instruction error".to_string(), 17 | }; 18 | assert_eq!(error.to_string(), "Resource instruction error"); 19 | } 20 | 21 | #[test] 22 | fn test_sub_parse_error() { 23 | let error = crate::Error::SubParseError { 24 | message: "Sub parse error".to_string(), 25 | }; 26 | assert_eq!(error.to_string(), "Sub parse error"); 27 | } 28 | 29 | #[test] 30 | fn test_resource_instruction_error() { 31 | let error = crate::Error::ResourceInstructionError { 32 | message: "Resource instruction error".to_string(), 33 | }; 34 | assert_eq!(error.to_string(), "Resource instruction error"); 35 | } 36 | 37 | #[test] 38 | fn test_resource_type_error() { 39 | let error = crate::Error::ResourceTypeError { 40 | message: "Resource type error".to_string(), 41 | }; 42 | assert_eq!(error.to_string(), "Resource type error"); 43 | } 44 | 45 | #[test] 46 | fn test_yaml_parse_error() { 47 | let yaml_error = serde_yaml::Error::custom("YAML parsing error"); 48 | let error: crate::Error = yaml_error.into(); 49 | assert_eq!(error.to_string(), "YAML parsing error"); 50 | } 51 | 52 | #[test] 53 | fn test_unsupported_language_error() { 54 | let error = crate::Error::UnsupportedLanguageError { 55 | language: "php".to_string(), 56 | }; 57 | assert_eq!(error.to_string(), "php is not a supported language"); 58 | } 59 | 60 | #[test] 61 | fn test_type_reference_error() { 62 | let error = crate::Error::TypeReferenceError { 63 | message: "Type reference error".to_string(), 64 | }; 65 | assert_eq!(error.to_string(), "Type reference error"); 66 | } 67 | 68 | #[test] 69 | fn test_primitive_error() { 70 | let error = crate::Error::PrimitiveError { 71 | message: "Primitive error".to_string(), 72 | }; 73 | assert_eq!(error.to_string(), "Primitive error"); 74 | } 75 | -------------------------------------------------------------------------------- /src/ir/README.md: -------------------------------------------------------------------------------- 1 | # `cdk_from_cfn::ir` 2 | 3 | This module contains the Intermediate Representation (IR) `cdk_from_cfn` uses in 4 | order to facilitate translating CloudFormation templates into AWS CDK 5 | applications. The IR data structures are obtained by transforming Parse Trees 6 | produced by the `cdk_from_cfn::parser` module. 7 | 8 | The conversion is informed by a copy of the [AWS CloudFormation Resource 9 | Specification][cfnspec] document, which provides information about properties 10 | accepted (and attributes returned) by the various supported CloudFormation 11 | Resource Types. 12 | 13 | The IR is composed of various kinds of "instructions" (which can also be 14 | thought about as declarations), which will compose the final AWS CDK 15 | application: 16 | 17 | - `ImportInstruction` convey information about modules that need importing in 18 | order to bring the necessary AWS CDK constructs in-scope; 19 | - `ResourceInstruction` models a single CloudFormation Resource construct 20 | instanciation, listing the provided properties and their associated values; 21 | - `OutputInstruction` represents properties exposed by the generated AWS CDK 22 | Stack class, optionally bound to a CloudFormation Output object; 23 | - etc... 24 | 25 | The IR is topologically sorted so that `cdk_from_cfn::synthesizer` can process 26 | instructions in the order they are provided, resulting in a program with 27 | correctly ordered declarations (while CloudFormation templates allow resources 28 | to be declared in an arbitrary order, AWS CDK applications naturally require 29 | variables to be declared before they can be referenced). 30 | 31 | [cfnspec]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html 32 | -------------------------------------------------------------------------------- /src/ir/conditions/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use indexmap::IndexMap; 4 | 5 | use crate::ir::conditions::{determine_order, ConditionIr}; 6 | use crate::ir::reference::{Origin, PseudoParameter, Reference}; 7 | use crate::parser::condition::{ConditionFunction, ConditionValue}; 8 | 9 | #[test] 10 | fn test_eq_translation() { 11 | let condition_structure = ConditionFunction::Equals( 12 | ConditionValue::String("us-west-2".into()), 13 | ConditionValue::Ref("AWS::Region".into()), 14 | ); 15 | 16 | let condition_ir = condition_structure.into_ir(); 17 | assert_eq!( 18 | ConditionIr::Equals( 19 | Box::new(ConditionIr::Str("us-west-2".into())), 20 | Box::new(ConditionIr::Ref(Reference::new( 21 | "AWS::Region", 22 | Origin::PseudoParameter(PseudoParameter::Region) 23 | ))) 24 | ), 25 | condition_ir 26 | ); 27 | } 28 | 29 | #[test] 30 | fn test_sorting() { 31 | let a = ConditionFunction::Equals( 32 | ConditionValue::Ref("Foo".into()), 33 | ConditionValue::Ref("Bar".into()), 34 | ); 35 | 36 | let b = ConditionFunction::Not(ConditionValue::Condition("A".into())); 37 | 38 | let hash = IndexMap::from([("A".into(), a), ("B".into(), b)]); 39 | let ordered = determine_order(&hash); 40 | 41 | assert_eq!(ordered, vec!["A", "B"]); 42 | } 43 | 44 | #[test] 45 | fn test_condition_translation() { 46 | let condition_structure: ConditionValue = ConditionValue::Condition("other".into()); 47 | let condition_ir = condition_structure.into_ir(); 48 | assert_eq!( 49 | (ConditionIr::Ref(Reference::new("other", Origin::Condition))), 50 | condition_ir 51 | ); 52 | } 53 | 54 | #[test] 55 | fn test_simple() { 56 | assert_eq!( 57 | ConditionIr::Str("hi".into()), 58 | ConditionValue::String("hi".into()).into_ir() 59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /src/ir/importer/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use indexmap::IndexMap; 4 | 5 | use crate::parser::resource::ResourceAttributes; 6 | 7 | use super::ImportInstruction; 8 | 9 | #[test] 10 | fn test_invalid_resource_type_name() { 11 | let resource_attributes = ResourceAttributes { 12 | resource_type: "AWS:Invalid:Resource:Type".to_string(), 13 | condition: Option::None, 14 | metadata: Option::None, 15 | depends_on: vec![], 16 | update_policy: Option::None, 17 | deletion_policy: Option::None, 18 | properties: IndexMap::new(), 19 | }; 20 | let parse_tree = IndexMap::from([("Resource".to_string(), resource_attributes)]); 21 | let import_instruction = ImportInstruction::from(&parse_tree).unwrap_err(); 22 | assert_eq!( 23 | "Invalid resource type name: AWS:Invalid:Resource:Type", 24 | import_instruction.to_string() 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /src/ir/mappings/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use indexmap::IndexMap; 4 | 5 | use crate::ir::mappings::OutputType::{Complex, Consistent}; 6 | use crate::parser::lookup_table::{MappingInnerValue, MappingTable}; 7 | use crate::Hasher; 8 | 9 | #[derive(Debug)] 10 | pub struct MappingInstruction { 11 | pub name: String, 12 | pub map: IndexMap, Hasher>, 13 | } 14 | 15 | // When printing out to a file, sometimes there are non ordinal types in mappings. 16 | // An example of this is something like: 17 | // { 18 | // "DisableScaleIn": true, 19 | // "ScaleInCooldown": 10 20 | // } 21 | // 22 | // The above example has both a number and a bool. This is considered "Complex". 23 | #[derive(Clone, Debug, PartialEq)] 24 | pub enum OutputType { 25 | Consistent(MappingInnerValue), 26 | Complex, 27 | } 28 | 29 | impl MappingInstruction { 30 | pub(super) fn from( 31 | parse_tree: IndexMap, 32 | ) -> Vec { 33 | parse_tree 34 | .into_iter() 35 | .map(|(name, MappingTable { mappings: map, .. })| MappingInstruction { name, map }) 36 | .collect() 37 | } 38 | 39 | pub fn output_type(&self) -> OutputType { 40 | let value = self.map.values().next().unwrap(); 41 | let first_inner_value = value.values().next().unwrap(); 42 | 43 | for _outer_map in self.map.values() { 44 | for inner_value in value.values() { 45 | if std::mem::discriminant(inner_value) != std::mem::discriminant(first_inner_value) 46 | { 47 | return Complex; 48 | } 49 | } 50 | } 51 | Consistent(first_inner_value.clone()) 52 | } 53 | } 54 | 55 | #[cfg(test)] 56 | mod tests; 57 | -------------------------------------------------------------------------------- /src/ir/mappings/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use super::*; 4 | macro_rules! map { 5 | ($($key:expr => $value:expr),+) => { 6 | { 7 | let mut m = ::indexmap::IndexMap::::default(); 8 | $( 9 | m.insert($key.into(), $value); 10 | )+ 11 | m 12 | } 13 | }; 14 | } 15 | 16 | #[test] 17 | fn test_mapping_consistent_string() { 18 | let mapping = MappingInstruction { 19 | name: "TableMappings".into(), 20 | map: map! { 21 | "Table" => map!{ 22 | "Key" => MappingInnerValue::String("Value".into()), 23 | "Key2" => MappingInnerValue::String("Value2".into()) 24 | } 25 | }, 26 | }; 27 | 28 | let actual_output = mapping.output_type(); 29 | let expected_output = OutputType::Consistent(MappingInnerValue::String("Value".into())); 30 | // In the end, we only care if the output is Consistent(string), not the value that is used. 31 | assert_eq!( 32 | std::mem::discriminant(&expected_output), 33 | std::mem::discriminant(&actual_output) 34 | ); 35 | } 36 | 37 | #[test] 38 | fn test_mapping_consistent_bool() { 39 | let mapping = MappingInstruction { 40 | name: "TableMappings".into(), 41 | map: map! { 42 | "Table" => map!{ 43 | "DisableScaleIn" => MappingInnerValue::Bool(true) 44 | } 45 | }, 46 | }; 47 | 48 | let actual_output = mapping.output_type(); 49 | let expected_output = OutputType::Consistent(MappingInnerValue::Bool(true)); 50 | assert_eq!(expected_output, actual_output); 51 | } 52 | 53 | #[test] 54 | fn test_mapping_complex() { 55 | let mapping = MappingInstruction { 56 | name: "TableMappings".into(), 57 | map: map! { 58 | "Table" => map!{ 59 | "DisableScaleIn" => MappingInnerValue::Bool(true), 60 | "Cooldown" => MappingInnerValue::Number(10) 61 | } 62 | }, 63 | }; 64 | 65 | let actual_output = mapping.output_type(); 66 | let expected_output = OutputType::Complex; 67 | assert_eq!(expected_output, actual_output); 68 | } 69 | -------------------------------------------------------------------------------- /src/ir/outputs/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use indexmap::IndexMap; 4 | 5 | use crate::cdk::{Primitive, Schema, TypeReference}; 6 | use crate::ir::resources::{ResourceIr, ResourceTranslator}; 7 | use crate::parser::output::Output; 8 | use crate::parser::resource::ResourceValue; 9 | use crate::util::Hasher; 10 | use crate::Error; 11 | 12 | use super::ReferenceOrigins; 13 | 14 | #[derive(Debug, PartialEq)] 15 | pub struct OutputInstruction { 16 | pub name: String, 17 | pub export: Option, 18 | pub value: ResourceIr, 19 | pub condition: Option, 20 | pub description: Option, 21 | } 22 | 23 | impl OutputInstruction { 24 | pub(super) fn from( 25 | parse_tree: IndexMap, 26 | schema: &Schema, 27 | origins: &ReferenceOrigins, 28 | ) -> Result, Error> { 29 | let mut list = Vec::with_capacity(parse_tree.len()); 30 | 31 | for (name, output) in parse_tree { 32 | let resource_translator = ResourceTranslator { 33 | schema, 34 | origins, 35 | value_type: Some(TypeReference::Primitive(Primitive::Json)), 36 | }; 37 | 38 | let value = resource_translator.translate(output.value)?; 39 | let condition = output.condition; 40 | let description = output.description; 41 | let mut export: Option = None; 42 | if let Some(ResourceValue::Object(x)) = output.export { 43 | if let Some(x) = x.get_key_value("Name") { 44 | export = Some(resource_translator.translate(x.1.clone())?); 45 | } 46 | } 47 | 48 | list.push(Self { 49 | name, 50 | export, 51 | value, 52 | condition, 53 | description, 54 | }) 55 | } 56 | 57 | Ok(list) 58 | } 59 | } 60 | 61 | #[cfg(test)] 62 | mod tests; 63 | -------------------------------------------------------------------------------- /src/ir/outputs/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use crate::CloudformationParseTree; 4 | 5 | use super::*; 6 | 7 | #[test] 8 | pub fn none() { 9 | assert_eq!( 10 | OutputInstruction::from( 11 | IndexMap::default(), 12 | Schema::builtin(), 13 | &ReferenceOrigins::new(&CloudformationParseTree { 14 | description: None, 15 | transforms: vec![], 16 | conditions: IndexMap::default(), 17 | mappings: IndexMap::default(), 18 | outputs: IndexMap::default(), 19 | parameters: IndexMap::default(), 20 | resources: IndexMap::default() 21 | }) 22 | ) 23 | .unwrap(), 24 | vec![] 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /src/ir/reference/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | #[derive(Debug, Clone, PartialEq)] 4 | pub struct Reference { 5 | pub origin: Origin, 6 | pub name: String, 7 | } 8 | 9 | impl Reference { 10 | #[inline] 11 | pub fn new(name: &str, origin: Origin) -> Reference { 12 | Reference { 13 | name: name.to_string(), 14 | origin, 15 | } 16 | } 17 | } 18 | 19 | // Origin for the ReferenceTable 20 | #[derive(Debug, Clone, PartialEq)] 21 | pub enum Origin { 22 | CfnParameter, 23 | Parameter, 24 | LogicalId { 25 | conditional: bool, 26 | }, 27 | Condition, 28 | GetAttribute { 29 | attribute: String, 30 | conditional: bool, 31 | }, 32 | PseudoParameter(PseudoParameter), 33 | } 34 | 35 | impl From for Origin { 36 | #[inline] 37 | fn from(pseudo: PseudoParameter) -> Self { 38 | Origin::PseudoParameter(pseudo) 39 | } 40 | } 41 | 42 | #[derive(Clone, Copy, Debug, PartialEq)] 43 | pub enum PseudoParameter { 44 | Partition, 45 | Region, 46 | StackId, 47 | StackName, 48 | URLSuffix, 49 | AccountId, 50 | NotificationArns, 51 | } 52 | 53 | impl PseudoParameter { 54 | pub(super) fn try_from(name: &str) -> Option { 55 | match name { 56 | "AWS::AccountId" => Some(PseudoParameter::AccountId), 57 | "AWS::NotificationARNs" => Some(PseudoParameter::NotificationArns), 58 | "AWS::Partition" => Some(PseudoParameter::Partition), 59 | "AWS::Region" => Some(PseudoParameter::Region), 60 | "AWS::StackId" => Some(PseudoParameter::StackId), 61 | "AWS::StackName" => Some(PseudoParameter::StackName), 62 | "AWS::URLSuffix" => Some(PseudoParameter::URLSuffix), 63 | _ => None, 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/parser/README.md: -------------------------------------------------------------------------------- 1 | # `cdk_from_cfn::parser` 2 | 3 | This module is responsible for parsing AWS CloudFormation YAML (and JSON) 4 | templates to a very immediate rust representation of it. The parsing logic is 5 | implemented using the [`serde` crate][serde] (a part of it is derived, while 6 | some special cases are hand-coded, typically to accommodate for specific 7 | CloudFormation syntax allowances). Naturally, the 8 | [`serde_yaml` crate][serde_yaml] produces the YAML/JSON specific parser 9 | front-end. 10 | 11 | The [Template anatomy][cfn-template-anatomy] page in the CloudFormation user 12 | guide describes the elements and schema of the various components of a 13 | CloudFormation template document. It is worth noting however that CloudFormation 14 | is relatively lenient in how it parses and validates templates: 15 | 16 | - it is often legal to pass a single, scalar value in a place where an array is 17 | expected, and CloudFormation usually interprets this as synonymous to a single 18 | valued array containing that value; 19 | - CloudFormation is able to transparently convert data between types as is 20 | necessary, as long as the conversion is straight-forward (e.g: the string 21 | `'1337'` can trivially be converted to the integer `1337`, and vice-versa); 22 | 23 | This leniency explains most of the complexity and hand-written parts of the 24 | parser module, which is otherwise a straight-forward translation of the schema 25 | described by the [Template anatomy][cfn-template-anatomy] documentation. 26 | 27 | [serde]: https://docs.rs/serde/latest/serde/ 28 | [serde_yaml]: https://docs.rs/serde_yaml/latest/serde_yaml/ 29 | [cfn-template-anatomy]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html 30 | -------------------------------------------------------------------------------- /src/parser/lookup_table/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use crate::{primitives::WrapperF64, Hasher}; 4 | use indexmap::IndexMap; 5 | use std::fmt::{Display, Formatter}; 6 | 7 | #[derive(Clone, Debug, PartialEq, serde::Deserialize)] 8 | #[serde(transparent)] 9 | pub struct MappingTable { 10 | pub mappings: IndexMap, Hasher>, 11 | } 12 | 13 | /** 14 | * MappingInnerValue tracks the allowed value types in a Mapping as defined by CloudFormation in the 15 | * link below. The values are allowed to only be a String or List: 16 | * 17 | * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html#mappings-section-structure-syntax 18 | * 19 | * In reality, all values are allowed from the json specification. If we detect any other conflicting 20 | * numbers, then the type becomes "Any" to allow for the strangeness. 21 | */ 22 | #[derive(Debug, Clone, PartialEq, serde::Deserialize)] 23 | #[serde(untagged)] 24 | pub enum MappingInnerValue { 25 | Number(i64), 26 | Float(WrapperF64), 27 | Bool(bool), 28 | String(String), 29 | List(Vec), 30 | } 31 | 32 | impl Display for MappingInnerValue { 33 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 34 | match self { 35 | MappingInnerValue::String(string_val) => write!(f, "'{string_val}'"), 36 | MappingInnerValue::List(list_val) => { 37 | let quoted_list_values: Vec = 38 | list_val.iter().map(|val| format!("'{val}'")).collect(); 39 | write!(f, "[{}]", quoted_list_values.join(",")) 40 | } 41 | MappingInnerValue::Number(val) => write!(f, "{val}"), 42 | MappingInnerValue::Float(val) => write!(f, "{val}"), 43 | MappingInnerValue::Bool(val) => write!(f, "{val}"), 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/parser/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | pub mod condition; 4 | mod intrinsics; 5 | pub mod lookup_table; 6 | pub mod output; 7 | pub mod parameters; 8 | pub mod resource; 9 | -------------------------------------------------------------------------------- /src/parser/output/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use super::resource::ResourceValue; 4 | 5 | #[derive(Clone, Debug, PartialEq, serde::Deserialize)] 6 | #[serde(rename_all = "PascalCase")] 7 | pub struct Output { 8 | pub value: ResourceValue, 9 | pub export: Option, 10 | pub condition: Option, 11 | pub description: Option, 12 | } 13 | -------------------------------------------------------------------------------- /src/parser/parameters/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use std::fmt; 4 | 5 | #[derive(Debug, PartialEq, serde::Deserialize)] 6 | #[serde(rename_all = "PascalCase")] 7 | pub struct Parameter { 8 | pub allowed_values: Option>, 9 | pub default: Option, 10 | pub description: Option, 11 | #[serde(rename = "Type")] 12 | pub parameter_type: ParameterType, 13 | pub no_echo: Option, 14 | } 15 | 16 | #[derive(Clone, Debug, PartialEq, serde_enum_str::Deserialize_enum_str)] 17 | pub enum ParameterType { 18 | String, 19 | Number, 20 | #[serde(rename = "List")] 21 | ListOfNumbers, 22 | CommaDelimitedList, 23 | Bool, 24 | #[serde(other)] 25 | Other(String), 26 | } 27 | 28 | impl fmt::Display for ParameterType { 29 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 30 | match self { 31 | ParameterType::String => write!(f, "String"), 32 | ParameterType::Number => write!(f, "Number"), 33 | ParameterType::ListOfNumbers => write!(f, "List"), 34 | ParameterType::CommaDelimitedList => write!(f, "CommaDelimitedList"), 35 | ParameterType::Other(s) => write!(f, "{}", s), 36 | ParameterType::Bool => write!(f, "Boolean"), 37 | } 38 | } 39 | } 40 | 41 | #[cfg(test)] 42 | mod tests; 43 | -------------------------------------------------------------------------------- /src/parser/parameters/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use super::*; 4 | 5 | #[test] 6 | fn test_parameter_type_display() { 7 | assert_eq!(ParameterType::String.to_string(), "String"); 8 | assert_eq!(ParameterType::Number.to_string(), "Number"); 9 | assert_eq!(ParameterType::ListOfNumbers.to_string(), "List"); 10 | assert_eq!( 11 | ParameterType::CommaDelimitedList.to_string(), 12 | "CommaDelimitedList" 13 | ); 14 | assert_eq!( 15 | ParameterType::Other("CustomType".to_string()).to_string(), 16 | "CustomType" 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/primitives/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | /** 4 | * Primitives are for things that can be outside the scope of parsing and IR and used heavily across both 5 | * Generally, attempt to keep this section to a minimu 6 | * 7 | */ 8 | use std::fmt; 9 | 10 | /// WrapperF64 exists because compraisons and outputs into typescripts are annoying with the 11 | /// default f64. Use this whenever referring to a floating point number in CFN standard. 12 | #[derive(Clone, Copy, Debug, serde::Deserialize)] 13 | #[serde(transparent)] 14 | pub struct WrapperF64(f64); 15 | 16 | impl WrapperF64 { 17 | pub fn new(num: f64) -> WrapperF64 { 18 | WrapperF64(num) 19 | } 20 | } 21 | 22 | impl PartialEq for WrapperF64 { 23 | fn eq(&self, other: &Self) -> bool { 24 | // It's equal if the diff is very small 25 | (self.0 - other.0).abs() < f64::EPSILON 26 | } 27 | } 28 | 29 | impl fmt::Display for WrapperF64 { 30 | #[inline] 31 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 32 | self.0.fmt(f) 33 | } 34 | } 35 | 36 | impl From for WrapperF64 { 37 | fn from(num: f64) -> Self { 38 | WrapperF64::new(num) 39 | } 40 | } 41 | 42 | impl From for WrapperF64 { 43 | fn from(num: u64) -> Self { 44 | WrapperF64::new(num as f64) 45 | } 46 | } 47 | 48 | impl From for WrapperF64 { 49 | fn from(num: i128) -> Self { 50 | WrapperF64::new(num as f64) 51 | } 52 | } 53 | 54 | impl From for WrapperF64 { 55 | fn from(num: u128) -> Self { 56 | WrapperF64::new(num as f64) 57 | } 58 | } 59 | 60 | #[cfg(test)] 61 | mod tests; 62 | -------------------------------------------------------------------------------- /src/primitives/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use super::*; 4 | 5 | #[test] 6 | fn test_from_u64() { 7 | let value: u64 = 42; 8 | let wrapper: WrapperF64 = value.into(); 9 | let expected: WrapperF64 = WrapperF64::new(42.0); 10 | 11 | assert_eq!(wrapper, expected); 12 | } 13 | 14 | #[test] 15 | fn test_from_i128() { 16 | let value: i128 = -10; 17 | let wrapper: WrapperF64 = value.into(); 18 | let expected: WrapperF64 = WrapperF64::new(-10.0); 19 | 20 | assert_eq!(wrapper, expected); 21 | } 22 | 23 | #[test] 24 | fn test_from_u128() { 25 | let value: u128 = 1000; 26 | let wrapper: WrapperF64 = value.into(); 27 | let expected: WrapperF64 = WrapperF64::new(1000.0); 28 | 29 | assert_eq!(wrapper, expected); 30 | } 31 | -------------------------------------------------------------------------------- /src/synthesizer/README.md: -------------------------------------------------------------------------------- 1 | # `cdk_from_cfn::synthesizer` 2 | 3 | This module contains the synthesizers for the various supported output 4 | languages. They transform the Intermediate Representation (IR) produced by the 5 | `cdk_from_cfn::ir` module into AWS CDK applications in a particular language. 6 | 7 | Each target language is exposed as a specific Cargo feature (`typescript`, 8 | `golang`, ...), so that users can build `cdk_from_cfn` binaries tailored down to 9 | their specific use-cases, reducing compilation time and binary size. Languages 10 | considered "stable" are however enabled by default, while "experimental" targets 11 | are opt-in. 12 | 13 | The `Synthesizer` API is very simple, receiving a CloudFormation Template IR 14 | object, and a `Writer` to which the generated code should be written. The 15 | `cdk_from_cfn::code` module provides assistance for generating code, in 16 | particular for maintaining correct indentation levels. 17 | -------------------------------------------------------------------------------- /src/synthesizer/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use std::io; 4 | 5 | use crate::{ir::CloudformationProgramIr, Error}; 6 | 7 | #[cfg(feature = "csharp")] 8 | mod csharp; 9 | #[cfg(feature = "csharp")] 10 | #[doc(inline)] 11 | pub use csharp::*; 12 | 13 | #[cfg(feature = "golang")] 14 | mod golang; 15 | #[cfg(feature = "golang")] 16 | #[doc(inline)] 17 | pub use golang::*; 18 | 19 | #[cfg(feature = "java")] 20 | mod java; 21 | #[cfg(feature = "java")] 22 | #[doc(inline)] 23 | pub use java::*; 24 | 25 | #[cfg(feature = "typescript")] 26 | mod typescript; 27 | #[cfg(feature = "typescript")] 28 | #[doc(inline)] 29 | pub use typescript::*; 30 | 31 | #[cfg(feature = "python")] 32 | mod python; 33 | #[cfg(feature = "python")] 34 | #[doc(inline)] 35 | pub use python::*; 36 | 37 | pub trait Synthesizer { 38 | fn synthesize( 39 | &self, 40 | ir: CloudformationProgramIr, 41 | into: &mut dyn io::Write, 42 | stack_name: &str, 43 | ) -> Result<(), Error>; 44 | } 45 | 46 | impl CloudformationProgramIr { 47 | #[inline(always)] 48 | pub fn synthesize( 49 | self, 50 | using: &dyn Synthesizer, 51 | into: &mut impl io::Write, 52 | stack_name: &str, 53 | ) -> Result<(), Error> { 54 | using.synthesize(self, into, stack_name) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/synthesizer/python/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use crate::ir::{conditions::ConditionIr, importer::ImportInstruction}; 4 | 5 | use super::synthesize_condition_recursive; 6 | 7 | #[test] 8 | fn test_invalid_organization() { 9 | let bad_org = "NotAws"; 10 | let import_instruction = ImportInstruction { 11 | organization: bad_org.to_string(), 12 | service: Option::None, 13 | }; 14 | let result = import_instruction.to_python().unwrap_err(); 15 | let expected = format!("Expected organization to be AWS or Alexa. Found {bad_org}"); 16 | assert_eq!(expected, result.to_string()); 17 | } 18 | 19 | #[test] 20 | fn test_alexa_org() { 21 | let import_instruction = ImportInstruction { 22 | organization: "Alexa".into(), 23 | service: Some("Ask".into()), 24 | }; 25 | let result = import_instruction.to_python(); 26 | assert_eq!("import alexa_ask as ask from ask", result.unwrap()); 27 | } 28 | 29 | #[test] 30 | fn test_condition_ir_not_simple() { 31 | let condition_ir = ConditionIr::Not(Box::new(ConditionIr::Condition("condition".into()))); 32 | let result = synthesize_condition_recursive(&condition_ir); 33 | assert_eq!("not (condition)", result); 34 | } 35 | -------------------------------------------------------------------------------- /src/synthesizer/typescript/tests.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | use super::*; 4 | 5 | #[test] 6 | fn pretty_name_fixes() { 7 | assert_eq!("vpc", pretty_name("VPC")); 8 | assert_eq!("vpcs", pretty_name("VPCs")); 9 | assert_eq!("objectAccess", pretty_name("GetObject")); 10 | assert_eq!("equalTo", pretty_name("Equals")); 11 | assert_eq!("providerArns", pretty_name("ProviderARNs")); 12 | assert_eq!("targetAZs", pretty_name("TargetAZs")); 13 | assert_eq!("diskSizeMBs", pretty_name("DiskSizeMBs")); 14 | } 15 | 16 | #[test] 17 | fn test_invalid_organization() { 18 | let bad_org = "NotAws"; 19 | let import_instruction = ImportInstruction { 20 | organization: bad_org.to_string(), 21 | service: Option::None, 22 | }; 23 | let result = import_instruction.to_typescript().unwrap_err(); 24 | let expected = format!("Expected organization to be AWS or Alexa. Found {bad_org}"); 25 | assert_eq!(expected, result.to_string()); 26 | } 27 | 28 | #[test] 29 | fn test_alexa_organization() { 30 | let import_instruction = ImportInstruction { 31 | organization: "Alexa".to_string(), 32 | service: Some("ASK".to_string()), 33 | }; 34 | let result = import_instruction.to_typescript(); 35 | assert_eq!( 36 | "import * as ask from 'aws-cdk-lib/alexa-ask';", 37 | result.unwrap() 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /src/util.rs: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | pub type Hasher = std::collections::hash_map::RandomState; 4 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/README.md: -------------------------------------------------------------------------------- 1 | This directory contains a directory for each language supported by cdk-from-cfn. 2 | 3 | Each language-specific directory contains the minimum necessary boilerplate 4 | files for running a CDK application in that language. During runtime execution 5 | of the end-to-end tests, all files in a language's directory here are copied to 6 | the temporary working directory for each test case. 7 | 8 | See the main end-to-end test [README](../README.md) for more information. -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/csharp/CSharp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | 7 | Major 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/csharp/setup-and-synth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | npx --yes cdk@latest synth --no-version-reporting --no-path-metadata --app 'dotnet run --project ./CSharp.csproj' 5 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/golang/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/iph/cdk_from_cfn/end-to-end 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/aws/aws-cdk-go/awscdk/v2 v2.117.0 7 | github.com/aws/constructs-go/constructs/v10 v10.2.25 8 | github.com/aws/jsii-runtime-go v1.81.0 9 | ) 10 | 11 | require ( 12 | github.com/Masterminds/semver/v3 v3.2.0 // indirect 13 | github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.201 // indirect 14 | github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2 // indirect 15 | github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv5/v2 v2.0.166 // indirect 16 | github.com/mattn/go-isatty v0.0.18 // indirect 17 | github.com/yuin/goldmark v1.4.13 // indirect 18 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect 19 | golang.org/x/mod v0.10.0 // indirect 20 | golang.org/x/sys v0.7.0 // indirect 21 | golang.org/x/tools v0.8.0 // indirect 22 | ) 23 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/golang/setup-and-synth.sh: -------------------------------------------------------------------------------- 1 | npm remove node_modules 2 | npx --yes cdk@latest synth --no-version-reporting --no-path-metadata --app 'go mod download && go run stack.go app.go' 3 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.myorg 7 | hello-java 8 | 0.1 9 | 10 | 11 | UTF-8 12 | 2.119.0 13 | [10.0.0,11.0.0) 14 | 5.7.1 15 | 16 | 17 | 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.11.0 23 | 24 | 17 25 | 26 | 27 | 28 | 29 | org.codehaus.mojo 30 | exec-maven-plugin 31 | 3.1.1 32 | 33 | com.myorg.MyApp 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | software.amazon.awscdk 43 | aws-cdk-lib 44 | ${cdk.version} 45 | 46 | 47 | 48 | software.constructs 49 | constructs 50 | ${constructs.version} 51 | 52 | 53 | 54 | org.junit.jupiter 55 | junit-jupiter 56 | ${junit.version} 57 | test 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/java/setup-and-synth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | echo "java setup" 5 | 6 | echo "cdk synth" 7 | npx --yes cdk@latest synth --no-version-reporting --no-path-metadata --app 'mvn -e -q compile exec:java' 8 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/python/requirements.txt: -------------------------------------------------------------------------------- 1 | aws-cdk-lib==2.117.0 2 | constructs>=10.0.0,<11.0.0 3 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/python/setup-and-synth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | echo "create venv" 5 | python3 -m venv .venv 6 | 7 | echo "source venv" 8 | source .venv/bin/activate 9 | 10 | echo "pip install" 11 | pip install --disable-pip-version-check -q -r requirements.txt 12 | 13 | echo "cdk synth" 14 | npx --yes cdk@latest synth --no-version-reporting --no-path-metadata --app 'python3 app.py' 15 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-end-to-end-test-app", 3 | "version": "0.1.0", 4 | "bin": { 5 | "typescript": "bin/typescript.js" 6 | }, 7 | "scripts": { 8 | "build": "tsc", 9 | "watch": "tsc -w", 10 | "cdk": "cdk" 11 | }, 12 | "devDependencies": { 13 | "@types/node": "18.14.6", 14 | "aws-cdk": "^2.117.0", 15 | "ts-node": "^10.9.1", 16 | "typescript": "~4.9.5" 17 | }, 18 | "dependencies": { 19 | "aws-cdk-lib": "^2.117.0", 20 | "buffer": "^6.0.3", 21 | "constructs": "^10.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/end-to-end/app-boilerplate-files/typescript/setup-and-synth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | echo "npm install" 5 | npm install --no-package-lock 6 | 7 | echo "cdk synth" 8 | npx --yes cdk@latest synth --no-version-reporting --no-path-metadata --app 'npx ts-node ./app.ts' 9 | -------------------------------------------------------------------------------- /tests/end-to-end/batch/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new BatchStack.BatchStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/batch/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new BatchStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/batch/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import BatchStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | BatchStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/batch/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { BatchStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new BatchStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new BucketStack.BucketStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/csharp/Stack.cs: -------------------------------------------------------------------------------- 1 | using Amazon.CDK; 2 | using Amazon.CDK.AWS.S3; 3 | using Constructs; 4 | using System.Collections.Generic; 5 | 6 | namespace BucketStack 7 | { 8 | public class BucketStackProps : StackProps 9 | { 10 | } 11 | 12 | public class BucketStack : Stack 13 | { 14 | public BucketStack(Construct scope, string id, BucketStackProps props = null) : base(scope, id, props) 15 | { 16 | 17 | // Resources 18 | var bucket = new CfnBucket(this, "Bucket", new CfnBucketProps 19 | { 20 | }); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/golang/app.go: -------------------------------------------------------------------------------- 1 | // auto-generated 2 | package main 3 | import ( 4 | "github.com/aws/aws-cdk-go/awscdk/v2" 5 | "github.com/aws/jsii-runtime-go" 6 | ) 7 | func main() { 8 | defer jsii.Close() 9 | app := awscdk.NewApp(&awscdk.AppProps{ 10 | DefaultStackSynthesizer: awscdk.NewDefaultStackSynthesizer(&awscdk.DefaultStackSynthesizerProps{ 11 | GenerateBootstrapVersionRule: jsii.Bool(false), 12 | }), 13 | }) 14 | NewBucketStack(app, "Stack", nil) 15 | app.Synth(nil) 16 | } 17 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/golang/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | cdk "github.com/aws/aws-cdk-go/awscdk/v2" 5 | s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3" 6 | "github.com/aws/constructs-go/constructs/v10" 7 | "github.com/aws/jsii-runtime-go" 8 | ) 9 | 10 | type BucketStackProps struct { 11 | cdk.StackProps 12 | } 13 | 14 | type BucketStack struct { 15 | cdk.Stack 16 | } 17 | 18 | func NewBucketStack(scope constructs.Construct, id string, props *BucketStackProps) *BucketStack { 19 | var sprops cdk.StackProps 20 | if props != nil { 21 | sprops = props.StackProps 22 | } 23 | stack := cdk.NewStack(scope, &id, &sprops) 24 | 25 | s3.NewCfnBucket( 26 | stack, 27 | jsii.String("Bucket"), 28 | &s3.CfnBucketProps{ 29 | }, 30 | ) 31 | 32 | return &BucketStack{ 33 | Stack: stack, 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new BucketStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/java/src/main/java/com/myorg/Stack.java: -------------------------------------------------------------------------------- 1 | package com.myorg; 2 | 3 | import software.constructs.Construct; 4 | 5 | import java.util.*; 6 | import software.amazon.awscdk.CfnMapping; 7 | import software.amazon.awscdk.CfnTag; 8 | import software.amazon.awscdk.Stack; 9 | import software.amazon.awscdk.StackProps; 10 | 11 | import software.amazon.awscdk.*; 12 | import software.amazon.awscdk.services.s3.*; 13 | 14 | class BucketStack extends Stack { 15 | public BucketStack(final Construct scope, final String id) { 16 | super(scope, id, null); 17 | } 18 | 19 | public BucketStack(final Construct scope, final String id, final StackProps props) { 20 | super(scope, id, props); 21 | 22 | CfnBucket bucket = CfnBucket.Builder.create(this, "Bucket") 23 | .build(); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import BucketStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | BucketStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/python/stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack 2 | import aws_cdk as cdk 3 | import aws_cdk.aws_s3 as s3 4 | from constructs import Construct 5 | 6 | class BucketStack(Stack): 7 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 8 | super().__init__(scope, construct_id, **kwargs) 9 | 10 | # Resources 11 | bucket = s3.CfnBucket(self, 'Bucket', 12 | ) 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "Bucket": { 4 | "Type": "AWS::S3::Bucket" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /tests/end-to-end/bucket/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { BucketStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new BucketStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/bucket/typescript/stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as s3 from 'aws-cdk-lib/aws-s3'; 3 | 4 | export interface BucketStackProps extends cdk.StackProps { 5 | } 6 | 7 | export class BucketStack extends cdk.Stack { 8 | public constructor(scope: cdk.App, id: string, props: BucketStackProps = {}) { 9 | super(scope, id, props); 10 | 11 | // Resources 12 | const bucket = new s3.CfnBucket(this, 'Bucket', { 13 | }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new CloudwatchStack.CloudwatchStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/csharp/Stack.cs: -------------------------------------------------------------------------------- 1 | using Amazon.CDK; 2 | using Amazon.CDK.AWS.CloudWatch; 3 | using Constructs; 4 | using System.Collections.Generic; 5 | 6 | namespace CloudwatchStack 7 | { 8 | public class CloudwatchStackProps : StackProps 9 | { 10 | /// 11 | /// Environment used for this deployment. 12 | /// 13 | public string EnvironmentName { get; set; } 14 | 15 | } 16 | 17 | public class CloudwatchStack : Stack 18 | { 19 | public CloudwatchStack(Construct scope, string id, CloudwatchStackProps props = null) : base(scope, id, props) 20 | { 21 | // Applying default props 22 | props ??= new CloudwatchStackProps(); 23 | props.EnvironmentName ??= "dev"; 24 | 25 | 26 | // Resources 27 | var myApi5xxErrorsAlarm = new CfnAlarm(this, "MyApi5xxErrorsAlarm", new CfnAlarmProps 28 | { 29 | AlarmDescription = "Example alarm", 30 | Namespace = "AWS/ApiGateway", 31 | Dimensions = new [] 32 | { 33 | new CfnAlarm.DimensionProperty 34 | { 35 | Name = "ApiName", 36 | Value = "MyApi", 37 | }, 38 | }, 39 | MetricName = "5XXError", 40 | ComparisonOperator = "GreaterThanThreshold", 41 | Statistic = "Average", 42 | Threshold = 0.005, 43 | Period = 900, 44 | EvaluationPeriods = 1, 45 | TreatMissingData = "notBreaching", 46 | AlarmActions = new [] 47 | { 48 | Fn.ImportValue($"{props.EnvironmentName}AlarmsTopicArn"), 49 | }, 50 | }); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/csharp/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/cloudwatch/template.json b/tests/end-to-end/cloudwatch-csharp-working-dir/cdk.out/Stack.template.json 2 | index 30a1dd6..fd7e22a 100644 3 | --- a/./tests/end-to-end/cloudwatch/template.json 4 | +++ b/tests/end-to-end/cloudwatch-csharp-working-dir/cdk.out/Stack.template.json 5 | @@ -1,50 +1,28 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | - "Parameters": { 9 | - "EnvironmentName": { 10 | - "Default": "dev", 11 | - "Description": "Environment used for this deployment.", 12 | - "Type": "String", 13 | - "AllowedValues": [ 14 | - "dev", 15 | - "stage", 16 | - "prod" 17 | - ] 18 | - } 19 | - }, 20 | "Resources": { 21 | "MyApi5xxErrorsAlarm": { 22 | "Type": "AWS::CloudWatch::Alarm", 23 | "Properties": { 24 | + "AlarmActions": [ 25 | + { 26 | + "Fn::ImportValue": "devAlarmsTopicArn" 27 | + } 28 | + ], 29 | "AlarmDescription": "Example alarm", 30 | - "Namespace": "AWS/ApiGateway", 31 | + "ComparisonOperator": "GreaterThanThreshold", 32 | "Dimensions": [ 33 | { 34 | "Name": "ApiName", 35 | "Value": "MyApi" 36 | } 37 | ], 38 | + "EvaluationPeriods": 1, 39 | "MetricName": "5XXError", 40 | - "ComparisonOperator": "GreaterThanThreshold", 41 | - "Statistic": "Average", 42 | - "Threshold": "0.005", 43 | + "Namespace": "AWS/ApiGateway", 44 | "Period": 900, 45 | - "EvaluationPeriods": 1, 46 | - "TreatMissingData": "notBreaching", 47 | - "AlarmActions": [ 48 | - { 49 | - "Fn::ImportValue": { 50 | - "Fn::Sub": [ 51 | - "${Environment}AlarmsTopicArn", 52 | - { 53 | - "Environment": { 54 | - "Ref": "EnvironmentName" 55 | - } 56 | - } 57 | - ] 58 | - } 59 | - } 60 | - ] 61 | + "Statistic": "Average", 62 | + "Threshold": 0.005, 63 | + "TreatMissingData": "notBreaching" 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "MyApi5xxErrorsAlarm": { 4 | "Type": "AWS::CloudWatch::Alarm", 5 | "Properties": { 6 | "AlarmActions": [ 7 | { 8 | "Fn::ImportValue": "devAlarmsTopicArn" 9 | } 10 | ], 11 | "AlarmDescription": "Example alarm", 12 | "ComparisonOperator": "GreaterThanThreshold", 13 | "Dimensions": [ 14 | { 15 | "Name": "ApiName", 16 | "Value": "MyApi" 17 | } 18 | ], 19 | "EvaluationPeriods": 1, 20 | "MetricName": "5XXError", 21 | "Namespace": "AWS/ApiGateway", 22 | "Period": 900, 23 | "Statistic": "Average", 24 | "Threshold": 0.005, 25 | "TreatMissingData": "notBreaching" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/golang/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | cdk "github.com/aws/aws-cdk-go/awscdk/v2" 7 | cloudwatch "github.com/aws/aws-cdk-go/awscdk/v2/awscloudwatch" 8 | "github.com/aws/constructs-go/constructs/v10" 9 | "github.com/aws/jsii-runtime-go" 10 | ) 11 | 12 | type CloudwatchStackProps struct { 13 | cdk.StackProps 14 | /// Environment used for this deployment. 15 | EnvironmentName *string 16 | } 17 | 18 | type CloudwatchStack struct { 19 | cdk.Stack 20 | } 21 | 22 | func NewCloudwatchStack(scope constructs.Construct, id string, props *CloudwatchStackProps) *CloudwatchStack { 23 | var sprops cdk.StackProps 24 | if props != nil { 25 | sprops = props.StackProps 26 | } 27 | stack := cdk.NewStack(scope, &id, &sprops) 28 | 29 | cloud_watch.NewCfnAlarm( 30 | stack, 31 | jsii.String("MyApi5xxErrorsAlarm"), 32 | &cloud_watch.CfnAlarmProps{ 33 | AlarmDescription: jsii.String("Example alarm"), 34 | Namespace: jsii.String("AWS/ApiGateway"), 35 | Dimensions: &[]interface{}{ 36 | &DimensionProperty{ 37 | Name: jsii.String("ApiName"), 38 | Value: jsii.String("MyApi"), 39 | }, 40 | }, 41 | MetricName: jsii.String("5XXError"), 42 | ComparisonOperator: jsii.String("GreaterThanThreshold"), 43 | Statistic: jsii.String("Average"), 44 | Threshold: jsii.Number(0.005), 45 | Period: jsii.Number(900), 46 | EvaluationPeriods: jsii.Number(1), 47 | TreatMissingData: jsii.String("notBreaching"), 48 | AlarmActions: &[]*string{ 49 | cdk.Fn_ImportValue(jsii.String(fmt.Sprintf("%vAlarmsTopicArn", props.EnvironmentName))), 50 | }, 51 | }, 52 | ) 53 | 54 | return &CloudwatchStack{ 55 | Stack: stack, 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/java/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/cloudwatch/template.json b/tests/end-to-end/cloudwatch-java-working-dir/cdk.out/Stack.template.json 2 | index 30a1dd6..fd7e22a 100644 3 | --- a/./tests/end-to-end/cloudwatch/template.json 4 | +++ b/tests/end-to-end/cloudwatch-java-working-dir/cdk.out/Stack.template.json 5 | @@ -1,50 +1,28 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | - "Parameters": { 9 | - "EnvironmentName": { 10 | - "Default": "dev", 11 | - "Description": "Environment used for this deployment.", 12 | - "Type": "String", 13 | - "AllowedValues": [ 14 | - "dev", 15 | - "stage", 16 | - "prod" 17 | - ] 18 | - } 19 | - }, 20 | "Resources": { 21 | "MyApi5xxErrorsAlarm": { 22 | "Type": "AWS::CloudWatch::Alarm", 23 | "Properties": { 24 | + "AlarmActions": [ 25 | + { 26 | + "Fn::ImportValue": "devAlarmsTopicArn" 27 | + } 28 | + ], 29 | "AlarmDescription": "Example alarm", 30 | - "Namespace": "AWS/ApiGateway", 31 | + "ComparisonOperator": "GreaterThanThreshold", 32 | "Dimensions": [ 33 | { 34 | "Name": "ApiName", 35 | "Value": "MyApi" 36 | } 37 | ], 38 | + "EvaluationPeriods": 1, 39 | "MetricName": "5XXError", 40 | - "ComparisonOperator": "GreaterThanThreshold", 41 | - "Statistic": "Average", 42 | - "Threshold": "0.005", 43 | + "Namespace": "AWS/ApiGateway", 44 | "Period": 900, 45 | - "EvaluationPeriods": 1, 46 | - "TreatMissingData": "notBreaching", 47 | - "AlarmActions": [ 48 | - { 49 | - "Fn::ImportValue": { 50 | - "Fn::Sub": [ 51 | - "${Environment}AlarmsTopicArn", 52 | - { 53 | - "Environment": { 54 | - "Ref": "EnvironmentName" 55 | - } 56 | - } 57 | - ] 58 | - } 59 | - } 60 | - ] 61 | + "Statistic": "Average", 62 | + "Threshold": 0.005, 63 | + "TreatMissingData": "notBreaching" 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/java/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "MyApi5xxErrorsAlarm": { 4 | "Type": "AWS::CloudWatch::Alarm", 5 | "Properties": { 6 | "AlarmActions": [ 7 | { 8 | "Fn::ImportValue": "devAlarmsTopicArn" 9 | } 10 | ], 11 | "AlarmDescription": "Example alarm", 12 | "ComparisonOperator": "GreaterThanThreshold", 13 | "Dimensions": [ 14 | { 15 | "Name": "ApiName", 16 | "Value": "MyApi" 17 | } 18 | ], 19 | "EvaluationPeriods": 1, 20 | "MetricName": "5XXError", 21 | "Namespace": "AWS/ApiGateway", 22 | "Period": 900, 23 | "Statistic": "Average", 24 | "Threshold": 0.005, 25 | "TreatMissingData": "notBreaching" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new CloudwatchStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/java/src/main/java/com/myorg/Stack.java: -------------------------------------------------------------------------------- 1 | package com.myorg; 2 | 3 | import software.constructs.Construct; 4 | 5 | import java.util.*; 6 | import software.amazon.awscdk.CfnMapping; 7 | import software.amazon.awscdk.CfnTag; 8 | import software.amazon.awscdk.Stack; 9 | import software.amazon.awscdk.StackProps; 10 | 11 | import software.amazon.awscdk.*; 12 | import software.amazon.awscdk.services.cloudwatch.*; 13 | 14 | class CloudwatchStack extends Stack { 15 | public CloudwatchStack(final Construct scope, final String id) { 16 | super(scope, id, null); 17 | } 18 | 19 | public CloudwatchStack(final Construct scope, final String id, final StackProps props) { 20 | this(scope, id, props, null); 21 | } 22 | 23 | public CloudwatchStack(final Construct scope, final String id, final StackProps props, 24 | String environmentName) { 25 | super(scope, id, props); 26 | 27 | environmentName = Optional.ofNullable(environmentName).isPresent() ? environmentName 28 | : "dev"; 29 | 30 | CfnAlarm myApi5xxErrorsAlarm = CfnAlarm.Builder.create(this, "MyApi5xxErrorsAlarm") 31 | .alarmDescription("Example alarm") 32 | .namespace("AWS/ApiGateway") 33 | .dimensions(Arrays.asList( 34 | CfnAlarm.DimensionProperty.builder() 35 | .name("ApiName") 36 | .value("MyApi") 37 | .build())) 38 | .metricName("5XXError") 39 | .comparisonOperator("GreaterThanThreshold") 40 | .statistic("Average") 41 | .threshold(0.005) 42 | .period(900) 43 | .evaluationPeriods(1) 44 | .treatMissingData("notBreaching") 45 | .alarmActions(Arrays.asList( 46 | Fn.importValue(environmentName + "AlarmsTopicArn"))) 47 | .build(); 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/python/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/cloudwatch/template.json b/tests/end-to-end/cloudwatch-python-working-dir/cdk.out/Stack.template.json 2 | index 30a1dd6..fd7e22a 100644 3 | --- a/./tests/end-to-end/cloudwatch/template.json 4 | +++ b/tests/end-to-end/cloudwatch-python-working-dir/cdk.out/Stack.template.json 5 | @@ -1,50 +1,28 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | - "Parameters": { 9 | - "EnvironmentName": { 10 | - "Default": "dev", 11 | - "Description": "Environment used for this deployment.", 12 | - "Type": "String", 13 | - "AllowedValues": [ 14 | - "dev", 15 | - "stage", 16 | - "prod" 17 | - ] 18 | - } 19 | - }, 20 | "Resources": { 21 | "MyApi5xxErrorsAlarm": { 22 | "Type": "AWS::CloudWatch::Alarm", 23 | "Properties": { 24 | + "AlarmActions": [ 25 | + { 26 | + "Fn::ImportValue": "devAlarmsTopicArn" 27 | + } 28 | + ], 29 | "AlarmDescription": "Example alarm", 30 | - "Namespace": "AWS/ApiGateway", 31 | + "ComparisonOperator": "GreaterThanThreshold", 32 | "Dimensions": [ 33 | { 34 | "Name": "ApiName", 35 | "Value": "MyApi" 36 | } 37 | ], 38 | + "EvaluationPeriods": 1, 39 | "MetricName": "5XXError", 40 | - "ComparisonOperator": "GreaterThanThreshold", 41 | - "Statistic": "Average", 42 | - "Threshold": "0.005", 43 | + "Namespace": "AWS/ApiGateway", 44 | "Period": 900, 45 | - "EvaluationPeriods": 1, 46 | - "TreatMissingData": "notBreaching", 47 | - "AlarmActions": [ 48 | - { 49 | - "Fn::ImportValue": { 50 | - "Fn::Sub": [ 51 | - "${Environment}AlarmsTopicArn", 52 | - { 53 | - "Environment": { 54 | - "Ref": "EnvironmentName" 55 | - } 56 | - } 57 | - ] 58 | - } 59 | - } 60 | - ] 61 | + "Statistic": "Average", 62 | + "Threshold": 0.005, 63 | + "TreatMissingData": "notBreaching" 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "MyApi5xxErrorsAlarm": { 4 | "Type": "AWS::CloudWatch::Alarm", 5 | "Properties": { 6 | "AlarmActions": [ 7 | { 8 | "Fn::ImportValue": "devAlarmsTopicArn" 9 | } 10 | ], 11 | "AlarmDescription": "Example alarm", 12 | "ComparisonOperator": "GreaterThanThreshold", 13 | "Dimensions": [ 14 | { 15 | "Name": "ApiName", 16 | "Value": "MyApi" 17 | } 18 | ], 19 | "EvaluationPeriods": 1, 20 | "MetricName": "5XXError", 21 | "Namespace": "AWS/ApiGateway", 22 | "Period": 900, 23 | "Statistic": "Average", 24 | "Threshold": 0.005, 25 | "TreatMissingData": "notBreaching" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import CloudwatchStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | CloudwatchStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/python/stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack 2 | import aws_cdk as cdk 3 | import aws_cdk.aws_cloudwatch as cloudwatch 4 | from constructs import Construct 5 | 6 | class CloudwatchStack(Stack): 7 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 8 | super().__init__(scope, construct_id, **kwargs) 9 | 10 | # Applying default props 11 | props = { 12 | 'environmentName': kwargs.get('environmentName', 'dev'), 13 | } 14 | 15 | # Resources 16 | myApi5xxErrorsAlarm = cloudwatch.CfnAlarm(self, 'MyApi5xxErrorsAlarm', 17 | alarm_description = 'Example alarm', 18 | namespace = 'AWS/ApiGateway', 19 | dimensions = [ 20 | { 21 | 'name': 'ApiName', 22 | 'value': 'MyApi', 23 | }, 24 | ], 25 | metric_name = '5XXError', 26 | comparison_operator = 'GreaterThanThreshold', 27 | statistic = 'Average', 28 | threshold = 0.005, 29 | period = 900, 30 | evaluation_periods = 1, 31 | treat_missing_data = 'notBreaching', 32 | alarm_actions = [ 33 | cdk.Fn.import_value(f"""{props['environmentName']}AlarmsTopicArn"""), 34 | ], 35 | ) 36 | 37 | 38 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Parameters": { 4 | "EnvironmentName": { 5 | "Default": "dev", 6 | "Description": "Environment used for this deployment.", 7 | "Type": "String", 8 | "AllowedValues": [ 9 | "dev", 10 | "stage", 11 | "prod" 12 | ] 13 | } 14 | }, 15 | "Resources": { 16 | "MyApi5xxErrorsAlarm": { 17 | "Type": "AWS::CloudWatch::Alarm", 18 | "Properties": { 19 | "AlarmDescription": "Example alarm", 20 | "Namespace": "AWS/ApiGateway", 21 | "Dimensions": [ 22 | { 23 | "Name": "ApiName", 24 | "Value": "MyApi" 25 | } 26 | ], 27 | "MetricName": "5XXError", 28 | "ComparisonOperator": "GreaterThanThreshold", 29 | "Statistic": "Average", 30 | "Threshold": "0.005", 31 | "Period": 900, 32 | "EvaluationPeriods": 1, 33 | "TreatMissingData": "notBreaching", 34 | "AlarmActions": [ 35 | { 36 | "Fn::ImportValue": { 37 | "Fn::Sub": [ 38 | "${Environment}AlarmsTopicArn", 39 | { 40 | "Environment": { 41 | "Ref": "EnvironmentName" 42 | } 43 | } 44 | ] 45 | } 46 | } 47 | ] 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/typescript/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/cloudwatch/template.json b/tests/end-to-end/cloudwatch-typescript-working-dir/cdk.out/Stack.template.json 2 | index 30a1dd6..fd7e22a 100644 3 | --- a/./tests/end-to-end/cloudwatch/template.json 4 | +++ b/tests/end-to-end/cloudwatch-typescript-working-dir/cdk.out/Stack.template.json 5 | @@ -1,50 +1,28 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | - "Parameters": { 9 | - "EnvironmentName": { 10 | - "Default": "dev", 11 | - "Description": "Environment used for this deployment.", 12 | - "Type": "String", 13 | - "AllowedValues": [ 14 | - "dev", 15 | - "stage", 16 | - "prod" 17 | - ] 18 | - } 19 | - }, 20 | "Resources": { 21 | "MyApi5xxErrorsAlarm": { 22 | "Type": "AWS::CloudWatch::Alarm", 23 | "Properties": { 24 | + "AlarmActions": [ 25 | + { 26 | + "Fn::ImportValue": "devAlarmsTopicArn" 27 | + } 28 | + ], 29 | "AlarmDescription": "Example alarm", 30 | - "Namespace": "AWS/ApiGateway", 31 | + "ComparisonOperator": "GreaterThanThreshold", 32 | "Dimensions": [ 33 | { 34 | "Name": "ApiName", 35 | "Value": "MyApi" 36 | } 37 | ], 38 | + "EvaluationPeriods": 1, 39 | "MetricName": "5XXError", 40 | - "ComparisonOperator": "GreaterThanThreshold", 41 | - "Statistic": "Average", 42 | - "Threshold": "0.005", 43 | + "Namespace": "AWS/ApiGateway", 44 | "Period": 900, 45 | - "EvaluationPeriods": 1, 46 | - "TreatMissingData": "notBreaching", 47 | - "AlarmActions": [ 48 | - { 49 | - "Fn::ImportValue": { 50 | - "Fn::Sub": [ 51 | - "${Environment}AlarmsTopicArn", 52 | - { 53 | - "Environment": { 54 | - "Ref": "EnvironmentName" 55 | - } 56 | - } 57 | - ] 58 | - } 59 | - } 60 | - ] 61 | + "Statistic": "Average", 62 | + "Threshold": 0.005, 63 | + "TreatMissingData": "notBreaching" 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "MyApi5xxErrorsAlarm": { 4 | "Type": "AWS::CloudWatch::Alarm", 5 | "Properties": { 6 | "AlarmActions": [ 7 | { 8 | "Fn::ImportValue": "devAlarmsTopicArn" 9 | } 10 | ], 11 | "AlarmDescription": "Example alarm", 12 | "ComparisonOperator": "GreaterThanThreshold", 13 | "Dimensions": [ 14 | { 15 | "Name": "ApiName", 16 | "Value": "MyApi" 17 | } 18 | ], 19 | "EvaluationPeriods": 1, 20 | "MetricName": "5XXError", 21 | "Namespace": "AWS/ApiGateway", 22 | "Period": 900, 23 | "Statistic": "Average", 24 | "Threshold": 0.005, 25 | "TreatMissingData": "notBreaching" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { CloudwatchStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new CloudwatchStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/cloudwatch/typescript/stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch'; 3 | 4 | export interface CloudwatchStackProps extends cdk.StackProps { 5 | /** 6 | * Environment used for this deployment. 7 | * @default 'dev' 8 | */ 9 | readonly environmentName?: string; 10 | } 11 | 12 | export class CloudwatchStack extends cdk.Stack { 13 | public constructor(scope: cdk.App, id: string, props: CloudwatchStackProps = {}) { 14 | super(scope, id, props); 15 | 16 | // Applying default props 17 | props = { 18 | ...props, 19 | environmentName: props.environmentName ?? 'dev', 20 | }; 21 | 22 | // Resources 23 | const myApi5xxErrorsAlarm = new cloudwatch.CfnAlarm(this, 'MyApi5xxErrorsAlarm', { 24 | alarmDescription: 'Example alarm', 25 | namespace: 'AWS/ApiGateway', 26 | dimensions: [ 27 | { 28 | name: 'ApiName', 29 | value: 'MyApi', 30 | }, 31 | ], 32 | metricName: '5XXError', 33 | comparisonOperator: 'GreaterThanThreshold', 34 | statistic: 'Average', 35 | threshold: 0.005, 36 | period: 900, 37 | evaluationPeriods: 1, 38 | treatMissingData: 'notBreaching', 39 | alarmActions: [ 40 | cdk.Fn.importValue(`${props.environmentName!}AlarmsTopicArn`), 41 | ], 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/end-to-end/config/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new ConfigStack.ConfigStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/config/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new ConfigStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/config/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import ConfigStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | ConfigStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/config/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { ConfigStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new ConfigStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/documentdb/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new DocumentDbStack.DocumentDbStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/documentdb/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "MasterUser": { 4 | "Type": "String", 5 | "Default": "MainUser", 6 | "Description": "The database admin account username", 7 | "NoEcho": true 8 | }, 9 | "MasterPassword": { 10 | "Type": "String", 11 | "Default": "password", 12 | "Description": "The database admin account password", 13 | "NoEcho": true 14 | } 15 | }, 16 | "Resources": { 17 | "DBCluster": { 18 | "Type": "AWS::DocDB::DBCluster", 19 | "Properties": { 20 | "DBClusterIdentifier": "MyCluster", 21 | "EngineVersion": "4.0.0", 22 | "MasterUserPassword": { 23 | "Ref": "MasterPassword" 24 | }, 25 | "MasterUsername": { 26 | "Ref": "MasterUser" 27 | } 28 | } 29 | }, 30 | "DBInstance": { 31 | "Type": "AWS::DocDB::DBInstance", 32 | "Properties": { 33 | "DBClusterIdentifier": { 34 | "Ref": "DBCluster" 35 | }, 36 | "DBInstanceClass": "db.t3.medium", 37 | "DBInstanceIdentifier": "MyInstance" 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /tests/end-to-end/documentdb/java/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "MasterUser": { 4 | "Type": "String", 5 | "Default": "MainUser", 6 | "NoEcho": true 7 | }, 8 | "MasterPassword": { 9 | "Type": "String", 10 | "Default": "password", 11 | "NoEcho": true 12 | } 13 | }, 14 | "Resources": { 15 | "DBCluster": { 16 | "Type": "AWS::DocDB::DBCluster", 17 | "Properties": { 18 | "DBClusterIdentifier": "MyCluster", 19 | "EngineVersion": "4.0.0", 20 | "MasterUserPassword": { 21 | "Ref": "MasterPassword" 22 | }, 23 | "MasterUsername": { 24 | "Ref": "MasterUser" 25 | } 26 | }, 27 | "UpdateReplacePolicy": "Delete", 28 | "DeletionPolicy": "Delete" 29 | }, 30 | "DBInstance": { 31 | "Type": "AWS::DocDB::DBInstance", 32 | "Properties": { 33 | "DBClusterIdentifier": { 34 | "Ref": "DBCluster" 35 | }, 36 | "DBInstanceClass": "db.t3.medium", 37 | "DBInstanceIdentifier": "MyInstance" 38 | }, 39 | "DependsOn": [ 40 | "DBCluster" 41 | ] 42 | } 43 | }, 44 | "Outputs": { 45 | "ClusterId": { 46 | "Value": { 47 | "Ref": "DBCluster" 48 | } 49 | }, 50 | "ClusterEndpoint": { 51 | "Value": { 52 | "Fn::GetAtt": [ 53 | "DBCluster", 54 | "Endpoint" 55 | ] 56 | } 57 | }, 58 | "ClusterPort": { 59 | "Value": { 60 | "Fn::GetAtt": [ 61 | "DBCluster", 62 | "Port" 63 | ] 64 | } 65 | }, 66 | "EngineVersion": { 67 | "Value": "4.0.0" 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /tests/end-to-end/documentdb/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new DocumentDbStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/documentdb/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "masterUser": { 4 | "Type": "String", 5 | "Default": "MainUser", 6 | "Description": "The database admin account username", 7 | "NoEcho": true 8 | }, 9 | "masterPassword": { 10 | "Type": "String", 11 | "Default": "password", 12 | "Description": "The database admin account password", 13 | "NoEcho": true 14 | } 15 | }, 16 | "Resources": { 17 | "DBCluster": { 18 | "Type": "AWS::DocDB::DBCluster", 19 | "Properties": { 20 | "DBClusterIdentifier": "MyCluster", 21 | "EngineVersion": "4.0.0", 22 | "MasterUserPassword": { 23 | "Ref": "masterPassword" 24 | }, 25 | "MasterUsername": { 26 | "Ref": "masterUser" 27 | } 28 | }, 29 | "DeletionPolicy": "Delete" 30 | }, 31 | "DBInstance": { 32 | "Type": "AWS::DocDB::DBInstance", 33 | "Properties": { 34 | "DBClusterIdentifier": { 35 | "Ref": "DBCluster" 36 | }, 37 | "DBInstanceClass": "db.t3.medium", 38 | "DBInstanceIdentifier": "MyInstance" 39 | }, 40 | "DependsOn": [ 41 | "DBCluster" 42 | ] 43 | } 44 | }, 45 | "Outputs": { 46 | "ClusterId": { 47 | "Value": { 48 | "Ref": "DBCluster" 49 | } 50 | }, 51 | "ClusterEndpoint": { 52 | "Value": { 53 | "Fn::GetAtt": [ 54 | "DBCluster", 55 | "Endpoint" 56 | ] 57 | } 58 | }, 59 | "ClusterPort": { 60 | "Value": { 61 | "Fn::GetAtt": [ 62 | "DBCluster", 63 | "Port" 64 | ] 65 | } 66 | }, 67 | "EngineVersion": { 68 | "Value": "4.0.0" 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /tests/end-to-end/documentdb/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import DocumentDbStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | DocumentDbStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/documentdb/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "MasterUser": { 4 | "Type": "String", 5 | "Default": "MainUser", 6 | "Description": "The database admin account username", 7 | "NoEcho": true 8 | }, 9 | "MasterPassword": { 10 | "Type": "String", 11 | "Default": "password", 12 | "Description": "The database admin account password", 13 | "NoEcho": true 14 | } 15 | }, 16 | "Resources": { 17 | "DBCluster": { 18 | "Type": "AWS::DocDB::DBCluster", 19 | "Properties": { 20 | "DBClusterIdentifier": "MyCluster", 21 | "EngineVersion": "4.0.0", 22 | "MasterUserPassword": { 23 | "Ref": "MasterPassword" 24 | }, 25 | "MasterUsername": { 26 | "Ref": "MasterUser" 27 | } 28 | }, 29 | "DeletionPolicy": "Delete" 30 | }, 31 | "DBInstance": { 32 | "Type": "AWS::DocDB::DBInstance", 33 | "Properties": { 34 | "DBClusterIdentifier": { 35 | "Ref": "DBCluster" 36 | }, 37 | "DBInstanceClass": "db.t3.medium", 38 | "DBInstanceIdentifier": "MyInstance" 39 | }, 40 | "DependsOn": [ 41 | "DBCluster" 42 | ] 43 | } 44 | }, 45 | "Outputs": { 46 | "ClusterId": { 47 | "Value": { 48 | "Ref": "DBCluster" 49 | } 50 | }, 51 | "ClusterEndpoint": { 52 | "Value": { 53 | "Fn::GetAtt": [ 54 | "DBCluster", 55 | "Endpoint" 56 | ] 57 | } 58 | }, 59 | "ClusterPort": { 60 | "Value": { 61 | "Fn::GetAtt": [ 62 | "DBCluster", 63 | "Port" 64 | ] 65 | } 66 | }, 67 | "EngineVersion": { 68 | "Value": "4.0.0" 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /tests/end-to-end/documentdb/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { DocumentDbStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new DocumentDbStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new Ec2Stack.Ec2Stack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/csharp/Stack.cs: -------------------------------------------------------------------------------- 1 | using Amazon.CDK; 2 | using Amazon.CDK.AWS.EC2; 3 | using Constructs; 4 | using System.Collections.Generic; 5 | 6 | namespace Ec2Stack 7 | { 8 | public class Ec2StackProps : StackProps 9 | { 10 | } 11 | 12 | public class Ec2Stack : Stack 13 | { 14 | public Ec2Stack(Construct scope, string id, Ec2StackProps props = null) : base(scope, id, props) 15 | { 16 | 17 | // Resources 18 | var testVpc = new CfnVPC(this, "TestVPC", new CfnVPCProps 19 | { 20 | CidrBlock = "10.0.0.0/16", 21 | }); 22 | var sg1 = new CfnSecurityGroup(this, "SG1", new CfnSecurityGroupProps 23 | { 24 | GroupDescription = "SG2", 25 | VpcId = testVpc.Ref, 26 | SecurityGroupEgress = new [] 27 | { 28 | new CfnSecurityGroup.EgressProperty 29 | { 30 | IpProtocol = "TCP", 31 | FromPort = 10000, 32 | ToPort = 10000, 33 | CidrIp = "10.0.0.0/16", 34 | }, 35 | }, 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/csharp/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/ec2/template.json b/tests/end-to-end/ec2-csharp-working-dir/cdk.out/Stack.template.json 2 | index a467a3e..da91487 100644 3 | --- a/./tests/end-to-end/ec2/template.json 4 | +++ b/tests/end-to-end/ec2-csharp-working-dir/cdk.out/Stack.template.json 5 | @@ -1,25 +1,26 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | "Resources": { 9 | + "TestVPC": { 10 | + "Type": "AWS::EC2::VPC", 11 | + "Properties": { 12 | + "CidrBlock": "10.0.0.0/16" 13 | + } 14 | + }, 15 | "SG1": { 16 | "Type": "AWS::EC2::SecurityGroup", 17 | "Properties": { 18 | "GroupDescription": "SG2", 19 | - "VpcId": { 20 | - "Ref": "TestVPC" 21 | - }, 22 | - "SecurityGroupEgress": { 23 | - "IpProtocol": "TCP", 24 | + "SecurityGroupEgress": [ 25 | + { 26 | + "CidrIp": "10.0.0.0/16", 27 | "FromPort": 10000, 28 | - "ToPort": 10000, 29 | - "CidrIp": "10.0.0.0/16" 30 | + "IpProtocol": "TCP", 31 | + "ToPort": 10000 32 | } 33 | + ], 34 | + "VpcId": { 35 | + "Ref": "TestVPC" 36 | } 37 | - }, 38 | - "TestVPC": { 39 | - "Type": "AWS::EC2::VPC", 40 | - "Properties": { 41 | - "CidrBlock": "10.0.0.0/16" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "TestVPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.0.0.0/16" 7 | } 8 | }, 9 | "SG1": { 10 | "Type": "AWS::EC2::SecurityGroup", 11 | "Properties": { 12 | "GroupDescription": "SG2", 13 | "SecurityGroupEgress": [ 14 | { 15 | "CidrIp": "10.0.0.0/16", 16 | "FromPort": 10000, 17 | "IpProtocol": "TCP", 18 | "ToPort": 10000 19 | } 20 | ], 21 | "VpcId": { 22 | "Ref": "TestVPC" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /tests/end-to-end/ec2/golang/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | cdk "github.com/aws/aws-cdk-go/awscdk/v2" 5 | ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2" 6 | "github.com/aws/constructs-go/constructs/v10" 7 | "github.com/aws/jsii-runtime-go" 8 | ) 9 | 10 | type Ec2StackProps struct { 11 | cdk.StackProps 12 | } 13 | 14 | type Ec2Stack struct { 15 | cdk.Stack 16 | } 17 | 18 | func NewEc2Stack(scope constructs.Construct, id string, props *Ec2StackProps) *Ec2Stack { 19 | var sprops cdk.StackProps 20 | if props != nil { 21 | sprops = props.StackProps 22 | } 23 | stack := cdk.NewStack(scope, &id, &sprops) 24 | 25 | testVpc := ec2.NewCfnVPC( 26 | stack, 27 | jsii.String("TestVPC"), 28 | &ec2.CfnVPCProps{ 29 | CidrBlock: jsii.String("10.0.0.0/16"), 30 | }, 31 | ) 32 | 33 | ec2.NewCfnSecurityGroup( 34 | stack, 35 | jsii.String("SG1"), 36 | &ec2.CfnSecurityGroupProps{ 37 | GroupDescription: jsii.String("SG2"), 38 | VpcId: testVpc.Ref(), 39 | SecurityGroupEgress: &[][]*awsec2.CfnSecurityGroup_EgressProperty{ 40 | &EgressProperty{ 41 | IpProtocol: jsii.String("TCP"), 42 | FromPort: jsii.Number(10000), 43 | ToPort: jsii.Number(10000), 44 | CidrIp: jsii.String("10.0.0.0/16"), 45 | }, 46 | }, 47 | }, 48 | ) 49 | 50 | return &Ec2Stack{ 51 | Stack: stack, 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/java/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/ec2/template.json b/tests/end-to-end/ec2-java-working-dir/cdk.out/Stack.template.json 2 | index a467a3e..da91487 100644 3 | --- a/./tests/end-to-end/ec2/template.json 4 | +++ b/tests/end-to-end/ec2-java-working-dir/cdk.out/Stack.template.json 5 | @@ -1,25 +1,26 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | "Resources": { 9 | + "TestVPC": { 10 | + "Type": "AWS::EC2::VPC", 11 | + "Properties": { 12 | + "CidrBlock": "10.0.0.0/16" 13 | + } 14 | + }, 15 | "SG1": { 16 | "Type": "AWS::EC2::SecurityGroup", 17 | "Properties": { 18 | "GroupDescription": "SG2", 19 | - "VpcId": { 20 | - "Ref": "TestVPC" 21 | - }, 22 | - "SecurityGroupEgress": { 23 | - "IpProtocol": "TCP", 24 | + "SecurityGroupEgress": [ 25 | + { 26 | + "CidrIp": "10.0.0.0/16", 27 | "FromPort": 10000, 28 | - "ToPort": 10000, 29 | - "CidrIp": "10.0.0.0/16" 30 | + "IpProtocol": "TCP", 31 | + "ToPort": 10000 32 | } 33 | + ], 34 | + "VpcId": { 35 | + "Ref": "TestVPC" 36 | } 37 | - }, 38 | - "TestVPC": { 39 | - "Type": "AWS::EC2::VPC", 40 | - "Properties": { 41 | - "CidrBlock": "10.0.0.0/16" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/java/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "TestVPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.0.0.0/16" 7 | } 8 | }, 9 | "SG1": { 10 | "Type": "AWS::EC2::SecurityGroup", 11 | "Properties": { 12 | "GroupDescription": "SG2", 13 | "SecurityGroupEgress": [ 14 | { 15 | "CidrIp": "10.0.0.0/16", 16 | "FromPort": 10000, 17 | "IpProtocol": "TCP", 18 | "ToPort": 10000 19 | } 20 | ], 21 | "VpcId": { 22 | "Ref": "TestVPC" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /tests/end-to-end/ec2/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new Ec2Stack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/java/src/main/java/com/myorg/Stack.java: -------------------------------------------------------------------------------- 1 | package com.myorg; 2 | 3 | import software.constructs.Construct; 4 | 5 | import java.util.*; 6 | import software.amazon.awscdk.CfnMapping; 7 | import software.amazon.awscdk.CfnTag; 8 | import software.amazon.awscdk.Stack; 9 | import software.amazon.awscdk.StackProps; 10 | 11 | import software.amazon.awscdk.*; 12 | import software.amazon.awscdk.services.ec2.*; 13 | 14 | class Ec2Stack extends Stack { 15 | public Ec2Stack(final Construct scope, final String id) { 16 | super(scope, id, null); 17 | } 18 | 19 | public Ec2Stack(final Construct scope, final String id, final StackProps props) { 20 | super(scope, id, props); 21 | 22 | CfnVPC testVpc = CfnVPC.Builder.create(this, "TestVPC") 23 | .cidrBlock("10.0.0.0/16") 24 | .build(); 25 | 26 | CfnSecurityGroup sg1 = CfnSecurityGroup.Builder.create(this, "SG1") 27 | .groupDescription("SG2") 28 | .vpcId(testVpc.getRef()) 29 | .securityGroupEgress(Arrays.asList( 30 | CfnSecurityGroup.EgressProperty.builder() 31 | .ipProtocol("TCP") 32 | .fromPort(10000) 33 | .toPort(10000) 34 | .cidrIp("10.0.0.0/16") 35 | .build())) 36 | .build(); 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/python/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/ec2/template.json b/tests/end-to-end/ec2-python-working-dir/cdk.out/Stack.template.json 2 | index a467a3e..da91487 100644 3 | --- a/./tests/end-to-end/ec2/template.json 4 | +++ b/tests/end-to-end/ec2-python-working-dir/cdk.out/Stack.template.json 5 | @@ -1,25 +1,26 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | "Resources": { 9 | + "TestVPC": { 10 | + "Type": "AWS::EC2::VPC", 11 | + "Properties": { 12 | + "CidrBlock": "10.0.0.0/16" 13 | + } 14 | + }, 15 | "SG1": { 16 | "Type": "AWS::EC2::SecurityGroup", 17 | "Properties": { 18 | "GroupDescription": "SG2", 19 | - "VpcId": { 20 | - "Ref": "TestVPC" 21 | - }, 22 | - "SecurityGroupEgress": { 23 | - "IpProtocol": "TCP", 24 | + "SecurityGroupEgress": [ 25 | + { 26 | + "CidrIp": "10.0.0.0/16", 27 | "FromPort": 10000, 28 | - "ToPort": 10000, 29 | - "CidrIp": "10.0.0.0/16" 30 | + "IpProtocol": "TCP", 31 | + "ToPort": 10000 32 | } 33 | + ], 34 | + "VpcId": { 35 | + "Ref": "TestVPC" 36 | } 37 | - }, 38 | - "TestVPC": { 39 | - "Type": "AWS::EC2::VPC", 40 | - "Properties": { 41 | - "CidrBlock": "10.0.0.0/16" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "TestVPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.0.0.0/16" 7 | } 8 | }, 9 | "SG1": { 10 | "Type": "AWS::EC2::SecurityGroup", 11 | "Properties": { 12 | "GroupDescription": "SG2", 13 | "SecurityGroupEgress": [ 14 | { 15 | "CidrIp": "10.0.0.0/16", 16 | "FromPort": 10000, 17 | "IpProtocol": "TCP", 18 | "ToPort": 10000 19 | } 20 | ], 21 | "VpcId": { 22 | "Ref": "TestVPC" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /tests/end-to-end/ec2/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import Ec2Stack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | Ec2Stack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/python/stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack 2 | import aws_cdk as cdk 3 | import aws_cdk.aws_ec2 as ec2 4 | from constructs import Construct 5 | 6 | class Ec2Stack(Stack): 7 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 8 | super().__init__(scope, construct_id, **kwargs) 9 | 10 | # Resources 11 | testVpc = ec2.CfnVPC(self, 'TestVPC', 12 | cidr_block = '10.0.0.0/16', 13 | ) 14 | 15 | sg1 = ec2.CfnSecurityGroup(self, 'SG1', 16 | group_description = 'SG2', 17 | vpc_id = testVpc.ref, 18 | security_group_egress = [ 19 | { 20 | 'ipProtocol': 'TCP', 21 | 'fromPort': 10000, 22 | 'toPort': 10000, 23 | 'cidrIp': '10.0.0.0/16', 24 | }, 25 | ], 26 | ) 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Resources": { 4 | "SG1": { 5 | "Type": "AWS::EC2::SecurityGroup", 6 | "Properties": { 7 | "GroupDescription": "SG2", 8 | "VpcId": { 9 | "Ref": "TestVPC" 10 | }, 11 | "SecurityGroupEgress": { 12 | "IpProtocol": "TCP", 13 | "FromPort": 10000, 14 | "ToPort": 10000, 15 | "CidrIp": "10.0.0.0/16" 16 | } 17 | } 18 | }, 19 | "TestVPC": { 20 | "Type": "AWS::EC2::VPC", 21 | "Properties": { 22 | "CidrBlock": "10.0.0.0/16" 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/typescript/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/ec2/template.json b/tests/end-to-end/ec2-typescript-working-dir/cdk.out/Stack.template.json 2 | index a467a3e..da91487 100644 3 | --- a/./tests/end-to-end/ec2/template.json 4 | +++ b/tests/end-to-end/ec2-typescript-working-dir/cdk.out/Stack.template.json 5 | @@ -1,25 +1,26 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | "Resources": { 9 | + "TestVPC": { 10 | + "Type": "AWS::EC2::VPC", 11 | + "Properties": { 12 | + "CidrBlock": "10.0.0.0/16" 13 | + } 14 | + }, 15 | "SG1": { 16 | "Type": "AWS::EC2::SecurityGroup", 17 | "Properties": { 18 | "GroupDescription": "SG2", 19 | - "VpcId": { 20 | - "Ref": "TestVPC" 21 | - }, 22 | - "SecurityGroupEgress": { 23 | - "IpProtocol": "TCP", 24 | + "SecurityGroupEgress": [ 25 | + { 26 | + "CidrIp": "10.0.0.0/16", 27 | "FromPort": 10000, 28 | - "ToPort": 10000, 29 | - "CidrIp": "10.0.0.0/16" 30 | + "IpProtocol": "TCP", 31 | + "ToPort": 10000 32 | } 33 | + ], 34 | + "VpcId": { 35 | + "Ref": "TestVPC" 36 | } 37 | - }, 38 | - "TestVPC": { 39 | - "Type": "AWS::EC2::VPC", 40 | - "Properties": { 41 | - "CidrBlock": "10.0.0.0/16" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "TestVPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.0.0.0/16" 7 | } 8 | }, 9 | "SG1": { 10 | "Type": "AWS::EC2::SecurityGroup", 11 | "Properties": { 12 | "GroupDescription": "SG2", 13 | "SecurityGroupEgress": [ 14 | { 15 | "CidrIp": "10.0.0.0/16", 16 | "FromPort": 10000, 17 | "IpProtocol": "TCP", 18 | "ToPort": 10000 19 | } 20 | ], 21 | "VpcId": { 22 | "Ref": "TestVPC" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /tests/end-to-end/ec2/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { Ec2Stack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new Ec2Stack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2/typescript/stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as ec2 from 'aws-cdk-lib/aws-ec2'; 3 | 4 | export interface Ec2StackProps extends cdk.StackProps { 5 | } 6 | 7 | export class Ec2Stack extends cdk.Stack { 8 | public constructor(scope: cdk.App, id: string, props: Ec2StackProps = {}) { 9 | super(scope, id, props); 10 | 11 | // Resources 12 | const testVpc = new ec2.CfnVPC(this, 'TestVPC', { 13 | cidrBlock: '10.0.0.0/16', 14 | }); 15 | 16 | const sg1 = new ec2.CfnSecurityGroup(this, 'SG1', { 17 | groupDescription: 'SG2', 18 | vpcId: testVpc.ref, 19 | securityGroupEgress: [ 20 | { 21 | ipProtocol: 'TCP', 22 | fromPort: 10000, 23 | toPort: 10000, 24 | cidrIp: '10.0.0.0/16', 25 | }, 26 | ], 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2_encryption/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new Ec2EncryptionStack.Ec2EncryptionStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2_encryption/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "PrivateSecurityGroup": { 4 | "Type": "AWS::EC2::SecurityGroup", 5 | "Properties": { 6 | "GroupDescription": "Private security group", 7 | "VpcId": "vpc-xxxxxxxx" 8 | } 9 | }, 10 | "PublicSecurityGroup": { 11 | "Type": "AWS::EC2::SecurityGroup", 12 | "Properties": { 13 | "GroupDescription": "Public security group", 14 | "VpcId": "vpc-xxxxxxxx" 15 | } 16 | }, 17 | "MyApp": { 18 | "Type": "AWS::EC2::Instance", 19 | "Properties": { 20 | "ImageId": "ami-12345678", 21 | "SecurityGroups": [ 22 | { 23 | "Ref": "PrivateSecurityGroup" 24 | } 25 | ], 26 | "Tags": [ 27 | { 28 | "Key": "Name", 29 | "Value": "EC2" 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /tests/end-to-end/ec2_encryption/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new StackSetStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2_encryption/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "PrivateSecurityGroup": { 4 | "Type": "AWS::EC2::SecurityGroup", 5 | "Properties": { 6 | "GroupDescription": "Private security group", 7 | "VpcId": "vpc-xxxxxxxx" 8 | } 9 | }, 10 | "PublicSecurityGroup": { 11 | "Type": "AWS::EC2::SecurityGroup", 12 | "Properties": { 13 | "GroupDescription": "Public security group", 14 | "VpcId": "vpc-xxxxxxxx" 15 | } 16 | }, 17 | "MyApp": { 18 | "Type": "AWS::EC2::Instance", 19 | "Properties": { 20 | "ImageId": "ami-12345678", 21 | "SecurityGroups": [ 22 | { 23 | "Ref": "PrivateSecurityGroup" 24 | } 25 | ], 26 | "Tags": [ 27 | { 28 | "Key": "Name", 29 | "Value": "EC2" 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /tests/end-to-end/ec2_encryption/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import Ec2EncryptionStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | Ec2EncryptionStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2_encryption/python/stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack 2 | import aws_cdk as cdk 3 | import aws_cdk.aws_ec2 as ec2 4 | from constructs import Construct 5 | 6 | class Ec2EncryptionStack(Stack): 7 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 8 | super().__init__(scope, construct_id, **kwargs) 9 | 10 | # Applying default props 11 | props = { 12 | 'environment': kwargs.get('environment', 'dev'), 13 | 'databaseType': kwargs.get('databaseType', 'postgresql'), 14 | 'useEncryption': kwargs.get('useEncryption', False), 15 | 'encryptedAmi': kwargs.get('encryptedAmi', 'ami-1234567890abcdef0'), 16 | 'unencryptedAmi': kwargs.get('unencryptedAmi', 'ami-0987654321fedcba0'), 17 | 'subnetType': kwargs.get('subnetType', 'Private1'), 18 | 'enableMonitoringParameter': kwargs.get('enableMonitoringParameter', False), 19 | } 20 | 21 | # Mappings 22 | regionToAmi = { 23 | 'us-east-1': { 24 | 'AMI': 'ami-12345678', 25 | }, 26 | 'us-west-2': { 27 | 'AMI': 'ami-87654321', 28 | }, 29 | } 30 | 31 | # Conditions 32 | has_database = props['databaseType'] == 'mysql' 33 | is_production = props['environment'] == 'prod' 34 | use_private_security_group = (props['subnetType'] == 'Private1' or props['subnetType'] == 'Private2') 35 | key_pair_prod = not is_production 36 | use_encryption = (is_production and has_database) 37 | 38 | # Resources 39 | privateSecurityGroup = ec2.CfnSecurityGroup(self, 'PrivateSecurityGroup', 40 | group_description = 'Private security group', 41 | vpc_id = 'vpc-xxxxxxxx', 42 | ) 43 | 44 | publicSecurityGroup = ec2.CfnSecurityGroup(self, 'PublicSecurityGroup', 45 | group_description = 'Public security group', 46 | vpc_id = 'vpc-xxxxxxxx', 47 | ) 48 | 49 | myApp = ec2.CfnInstance(self, 'MyApp', 50 | image_id = regionToAmi['us-east-1']['AMI'], 51 | tags = [ 52 | { 53 | 'key': 'Name', 54 | 'value': cdk.Fn.select(1, 'My-EC2-Instance'.split('-')), 55 | }, 56 | ], 57 | security_groups = [ 58 | privateSecurityGroup.ref if use_private_security_group else publicSecurityGroup.ref, 59 | ], 60 | ) 61 | 62 | 63 | -------------------------------------------------------------------------------- /tests/end-to-end/ec2_encryption/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "PrivateSecurityGroup": { 4 | "Type": "AWS::EC2::SecurityGroup", 5 | "Properties": { 6 | "GroupDescription": "Private security group", 7 | "VpcId": "vpc-xxxxxxxx" 8 | } 9 | }, 10 | "PublicSecurityGroup": { 11 | "Type": "AWS::EC2::SecurityGroup", 12 | "Properties": { 13 | "GroupDescription": "Public security group", 14 | "VpcId": "vpc-xxxxxxxx" 15 | } 16 | }, 17 | "MyApp": { 18 | "Type": "AWS::EC2::Instance", 19 | "Properties": { 20 | "ImageId": "ami-12345678", 21 | "SecurityGroups": [ 22 | { 23 | "Ref": "PrivateSecurityGroup" 24 | } 25 | ], 26 | "Tags": [ 27 | { 28 | "Key": "Name", 29 | "Value": "EC2" 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /tests/end-to-end/ec2_encryption/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { Ec2EncryptionStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new Ec2EncryptionStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/ecs/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new EcsStack.EcsStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/ecs/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "BackendECSTaskRole": { 4 | "Type": "AWS::IAM::Role", 5 | "Properties": { 6 | "AssumeRolePolicyDocument": { 7 | "Statement": [ 8 | { 9 | "Action": "sts:AssumeRole", 10 | "Effect": "Allow", 11 | "Principal": { 12 | "Service": "ecs-tasks.amazonaws.com" 13 | } 14 | } 15 | ] 16 | }, 17 | "Path": "/" 18 | } 19 | }, 20 | "ECSTaskExecutionRole": { 21 | "Type": "AWS::IAM::Role", 22 | "Properties": { 23 | "AssumeRolePolicyDocument": { 24 | "Statement": [ 25 | { 26 | "Action": "sts:AssumeRole", 27 | "Effect": "Allow", 28 | "Principal": { 29 | "Service": "ecs-tasks.amazonaws.com" 30 | } 31 | } 32 | ] 33 | }, 34 | "ManagedPolicyArns": [ 35 | "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", 36 | "arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess", 37 | "arn:aws:iam::aws:policy/SecretsManagerReadWrite" 38 | ], 39 | "Path": "/" 40 | } 41 | }, 42 | "BackendServiceECSTaskDefinition": { 43 | "Type": "AWS::ECS::TaskDefinition", 44 | "Properties": { 45 | "ContainerDefinitions": [ 46 | { 47 | "Image": "nginx", 48 | "LogConfiguration": { 49 | "LogDriver": "awslogs", 50 | "Options": { 51 | "awslogs-group": "/aws/ecs/test/main", 52 | "awslogs-region": "ap-northeast-1", 53 | "awslogs-stream-prefix": "ecs" 54 | } 55 | }, 56 | "Name": "main" 57 | } 58 | ], 59 | "Cpu": "256", 60 | "ExecutionRoleArn": { 61 | "Fn::GetAtt": [ 62 | "ECSTaskExecutionRole", 63 | "Arn" 64 | ] 65 | }, 66 | "Family": "test", 67 | "Memory": "1024", 68 | "NetworkMode": "awsvpc", 69 | "RequiresCompatibilities": [ 70 | "FARGATE" 71 | ], 72 | "TaskRoleArn": { 73 | "Fn::GetAtt": [ 74 | "BackendECSTaskRole", 75 | "Arn" 76 | ] 77 | } 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /tests/end-to-end/ecs/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "BackendECSTaskRole": { 4 | "Type": "AWS::IAM::Role", 5 | "Properties": { 6 | "AssumeRolePolicyDocument": { 7 | "Statement": [ 8 | { 9 | "Action": "sts:AssumeRole", 10 | "Effect": "Allow", 11 | "Principal": { 12 | "Service": "ecs-tasks.amazonaws.com" 13 | } 14 | } 15 | ] 16 | }, 17 | "Path": "/" 18 | } 19 | }, 20 | "ECSTaskExecutionRole": { 21 | "Type": "AWS::IAM::Role", 22 | "Properties": { 23 | "AssumeRolePolicyDocument": { 24 | "Statement": [ 25 | { 26 | "Action": "sts:AssumeRole", 27 | "Effect": "Allow", 28 | "Principal": { 29 | "Service": "ecs-tasks.amazonaws.com" 30 | } 31 | } 32 | ] 33 | }, 34 | "ManagedPolicyArns": [ 35 | "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", 36 | "arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess", 37 | "arn:aws:iam::aws:policy/SecretsManagerReadWrite" 38 | ], 39 | "Path": "/" 40 | } 41 | }, 42 | "BackendServiceECSTaskDefinition": { 43 | "Type": "AWS::ECS::TaskDefinition", 44 | "Properties": { 45 | "ContainerDefinitions": [ 46 | { 47 | "Image": "nginx", 48 | "LogConfiguration": { 49 | "LogDriver": "awslogs", 50 | "Options": { 51 | "awslogs-group": "/aws/ecs/test/main", 52 | "awslogs-region": "ap-northeast-1", 53 | "awslogs-stream-prefix": "ecs" 54 | } 55 | }, 56 | "Name": "main" 57 | } 58 | ], 59 | "Cpu": "256", 60 | "ExecutionRoleArn": { 61 | "Fn::GetAtt": [ 62 | "ECSTaskExecutionRole", 63 | "Arn" 64 | ] 65 | }, 66 | "Family": "test", 67 | "Memory": "1024", 68 | "NetworkMode": "awsvpc", 69 | "RequiresCompatibilities": [ 70 | "FARGATE" 71 | ], 72 | "TaskRoleArn": { 73 | "Fn::GetAtt": [ 74 | "BackendECSTaskRole", 75 | "Arn" 76 | ] 77 | } 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /tests/end-to-end/ecs/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import EcsStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | EcsStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/ecs/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "BackendECSTaskRole": { 4 | "Type": "AWS::IAM::Role", 5 | "Properties": { 6 | "AssumeRolePolicyDocument": { 7 | "Statement": [ 8 | { 9 | "Action": "sts:AssumeRole", 10 | "Effect": "Allow", 11 | "Principal": { 12 | "Service": "ecs-tasks.amazonaws.com" 13 | } 14 | } 15 | ] 16 | }, 17 | "Path": "/" 18 | } 19 | }, 20 | "ECSTaskExecutionRole": { 21 | "Type": "AWS::IAM::Role", 22 | "Properties": { 23 | "AssumeRolePolicyDocument": { 24 | "Statement": [ 25 | { 26 | "Action": "sts:AssumeRole", 27 | "Effect": "Allow", 28 | "Principal": { 29 | "Service": "ecs-tasks.amazonaws.com" 30 | } 31 | } 32 | ] 33 | }, 34 | "ManagedPolicyArns": [ 35 | "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", 36 | "arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess", 37 | "arn:aws:iam::aws:policy/SecretsManagerReadWrite" 38 | ], 39 | "Path": "/" 40 | } 41 | }, 42 | "BackendServiceECSTaskDefinition": { 43 | "Type": "AWS::ECS::TaskDefinition", 44 | "Properties": { 45 | "ContainerDefinitions": [ 46 | { 47 | "Image": "nginx", 48 | "LogConfiguration": { 49 | "LogDriver": "awslogs", 50 | "Options": { 51 | "awslogs-group": "/aws/ecs/test/main", 52 | "awslogs-region": "ap-northeast-1", 53 | "awslogs-stream-prefix": "ecs" 54 | } 55 | }, 56 | "Name": "main" 57 | } 58 | ], 59 | "Cpu": "256", 60 | "ExecutionRoleArn": { 61 | "Fn::GetAtt": [ 62 | "ECSTaskExecutionRole", 63 | "Arn" 64 | ] 65 | }, 66 | "Family": "test", 67 | "Memory": "1024", 68 | "NetworkMode": "awsvpc", 69 | "RequiresCompatibilities": [ 70 | "FARGATE" 71 | ], 72 | "TaskRoleArn": { 73 | "Fn::GetAtt": [ 74 | "BackendECSTaskRole", 75 | "Arn" 76 | ] 77 | } 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /tests/end-to-end/ecs/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { EcsStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new EcsStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/ecs/typescript/stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as ecs from 'aws-cdk-lib/aws-ecs'; 3 | import * as iam from 'aws-cdk-lib/aws-iam'; 4 | 5 | export interface EcsStackProps extends cdk.StackProps { 6 | } 7 | 8 | export class EcsStack extends cdk.Stack { 9 | public constructor(scope: cdk.App, id: string, props: EcsStackProps = {}) { 10 | super(scope, id, props); 11 | 12 | // Resources 13 | const backendEcsTaskRole = new iam.CfnRole(this, 'BackendECSTaskRole', { 14 | path: '/', 15 | assumeRolePolicyDocument: { 16 | Statement: [ 17 | { 18 | Action: 'sts:AssumeRole', 19 | Effect: 'Allow', 20 | Principal: { 21 | Service: 'ecs-tasks.amazonaws.com', 22 | }, 23 | }, 24 | ], 25 | }, 26 | }); 27 | 28 | const ecsTaskExecutionRole = new iam.CfnRole(this, 'ECSTaskExecutionRole', { 29 | path: '/', 30 | assumeRolePolicyDocument: { 31 | Statement: [ 32 | { 33 | Action: 'sts:AssumeRole', 34 | Effect: 'Allow', 35 | Principal: { 36 | Service: 'ecs-tasks.amazonaws.com', 37 | }, 38 | }, 39 | ], 40 | }, 41 | managedPolicyArns: [ 42 | 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy', 43 | 'arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess', 44 | 'arn:aws:iam::aws:policy/SecretsManagerReadWrite', 45 | ], 46 | }); 47 | 48 | const backendServiceEcsTaskDefinition = new ecs.CfnTaskDefinition(this, 'BackendServiceECSTaskDefinition', { 49 | family: 'test', 50 | requiresCompatibilities: [ 51 | 'FARGATE', 52 | ], 53 | memory: '1024', 54 | cpu: '256', 55 | networkMode: 'awsvpc', 56 | executionRoleArn: ecsTaskExecutionRole.attrArn, 57 | taskRoleArn: backendEcsTaskRole.attrArn, 58 | containerDefinitions: [ 59 | { 60 | name: 'main', 61 | image: 'nginx', 62 | logConfiguration: { 63 | options: { 64 | 'awslogs-group': '/aws/ecs/test/main', 65 | 'awslogs-region': 'ap-northeast-1', 66 | 'awslogs-stream-prefix': 'ecs', 67 | }, 68 | logDriver: 'awslogs', 69 | }, 70 | }, 71 | ], 72 | }); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/end-to-end/efs/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new EfsStack.EfsStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/efs/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new EfsStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/efs/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import EfsStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | EfsStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/efs/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { EfsStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new EfsStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new JsonPropsStack.JsonPropsStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/csharp/Stack.cs: -------------------------------------------------------------------------------- 1 | using Amazon.CDK; 2 | using Amazon.CDK.AWS.IAM; 3 | using Amazon.CDK.AWS.SQS; 4 | using Constructs; 5 | using System.Collections.Generic; 6 | 7 | namespace JsonPropsStack 8 | { 9 | public class JsonPropsStackProps : StackProps 10 | { 11 | } 12 | 13 | public class JsonPropsStack : Stack 14 | { 15 | public JsonPropsStack(Construct scope, string id, JsonPropsStackProps props = null) : base(scope, id, props) 16 | { 17 | 18 | // Resources 19 | var myQueue1 = new CfnQueue(this, "MyQueue1", new CfnQueueProps 20 | { 21 | }); 22 | var myQueue2 = new CfnQueue(this, "MyQueue2", new CfnQueueProps 23 | { 24 | }); 25 | var myRdMessageQueueGroup = new CfnGroup(this, "MyRDMessageQueueGroup", new CfnGroupProps 26 | { 27 | Policies = new [] 28 | { 29 | new CfnGroup.PolicyProperty 30 | { 31 | PolicyName = "MyQueueGroupPolicy", 32 | PolicyDocument = new Dictionary 33 | { 34 | { "Statement", new [] 35 | { 36 | new Dictionary 37 | { 38 | { "Effect", "Allow"}, 39 | { "Action", new [] 40 | { 41 | "sqs:DeleteMessage", 42 | "sqs:ReceiveMessage", 43 | }}, 44 | { "Resource", new [] 45 | { 46 | myQueue1.AttrArn, 47 | myQueue2.AttrArn, 48 | }}, 49 | }, 50 | }}, 51 | }, 52 | }, 53 | }, 54 | }); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/csharp/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/resource_w_json_type_properties/template.json b/tests/end-to-end/resource_w_json_type_properties-csharp-working-dir/cdk.out/Stack.template.json 2 | index 3fc1712..415a5dc 100644 3 | --- a/./tests/end-to-end/resource_w_json_type_properties/template.json 4 | +++ b/tests/end-to-end/resource_w_json_type_properties-csharp-working-dir/cdk.out/Stack.template.json 5 | @@ -1,5 +1,4 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | "Resources": { 9 | "MyQueue1": { 10 | "Type": "AWS::SQS::Queue" 11 | @@ -12,7 +11,6 @@ 12 | "Properties": { 13 | "Policies": [ 14 | { 15 | - "PolicyName": "MyQueueGroupPolicy", 16 | "PolicyDocument": { 17 | "Statement": [ 18 | { 19 | @@ -37,7 +35,8 @@ 20 | ] 21 | } 22 | ] 23 | - } 24 | + }, 25 | + "PolicyName": "MyQueueGroupPolicy" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "MyQueue1": { 4 | "Type": "AWS::SQS::Queue" 5 | }, 6 | "MyQueue2": { 7 | "Type": "AWS::SQS::Queue" 8 | }, 9 | "MyRDMessageQueueGroup": { 10 | "Type": "AWS::IAM::Group", 11 | "Properties": { 12 | "Policies": [ 13 | { 14 | "PolicyDocument": { 15 | "Statement": [ 16 | { 17 | "Effect": "Allow", 18 | "Action": [ 19 | "sqs:DeleteMessage", 20 | "sqs:ReceiveMessage" 21 | ], 22 | "Resource": [ 23 | { 24 | "Fn::GetAtt": [ 25 | "MyQueue1", 26 | "Arn" 27 | ] 28 | }, 29 | { 30 | "Fn::GetAtt": [ 31 | "MyQueue2", 32 | "Arn" 33 | ] 34 | } 35 | ] 36 | } 37 | ] 38 | }, 39 | "PolicyName": "MyQueueGroupPolicy" 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/golang/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | cdk "github.com/aws/aws-cdk-go/awscdk/v2" 5 | iam "github.com/aws/aws-cdk-go/awscdk/v2/awsiam" 6 | sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" 7 | "github.com/aws/constructs-go/constructs/v10" 8 | "github.com/aws/jsii-runtime-go" 9 | ) 10 | 11 | type JsonPropsStackProps struct { 12 | cdk.StackProps 13 | } 14 | 15 | type JsonPropsStack struct { 16 | cdk.Stack 17 | } 18 | 19 | func NewJsonPropsStack(scope constructs.Construct, id string, props *JsonPropsStackProps) *JsonPropsStack { 20 | var sprops cdk.StackProps 21 | if props != nil { 22 | sprops = props.StackProps 23 | } 24 | stack := cdk.NewStack(scope, &id, &sprops) 25 | 26 | myQueue1 := sqs.NewCfnQueue( 27 | stack, 28 | jsii.String("MyQueue1"), 29 | &sqs.CfnQueueProps{ 30 | }, 31 | ) 32 | 33 | myQueue2 := sqs.NewCfnQueue( 34 | stack, 35 | jsii.String("MyQueue2"), 36 | &sqs.CfnQueueProps{ 37 | }, 38 | ) 39 | 40 | iam.NewCfnGroup( 41 | stack, 42 | jsii.String("MyRDMessageQueueGroup"), 43 | &iam.CfnGroupProps{ 44 | Policies: &[]interface{}{ 45 | &PolicyProperty{ 46 | PolicyName: jsii.String("MyQueueGroupPolicy"), 47 | PolicyDocument: map[string]interface{} { 48 | "Statement": &[]interface{}{ 49 | map[string]interface{} { 50 | "Effect": jsii.String("Allow"), 51 | "Action": &[]interface{}{ 52 | jsii.String("sqs:DeleteMessage"), 53 | jsii.String("sqs:ReceiveMessage"), 54 | }, 55 | "Resource": &[]interface{}{ 56 | myQueue1.AttrArn(), 57 | myQueue2.AttrArn(), 58 | }, 59 | }, 60 | }, 61 | }, 62 | }, 63 | }, 64 | }, 65 | ) 66 | 67 | return &JsonPropsStack{ 68 | Stack: stack, 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/java/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/resource_w_json_type_properties/template.json b/tests/end-to-end/resource_w_json_type_properties-java-working-dir/cdk.out/Stack.template.json 2 | index 3fc1712..ef11b51 100644 3 | --- a/./tests/end-to-end/resource_w_json_type_properties/template.json 4 | +++ b/tests/end-to-end/resource_w_json_type_properties-java-working-dir/cdk.out/Stack.template.json 5 | @@ -1,5 +1,4 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | "Resources": { 9 | "MyQueue1": { 10 | "Type": "AWS::SQS::Queue" 11 | @@ -12,11 +11,9 @@ 12 | "Properties": { 13 | "Policies": [ 14 | { 15 | - "PolicyName": "MyQueueGroupPolicy", 16 | "PolicyDocument": { 17 | "Statement": [ 18 | { 19 | - "Effect": "Allow", 20 | "Action": [ 21 | "sqs:DeleteMessage", 22 | "sqs:ReceiveMessage" 23 | @@ -34,10 +31,12 @@ 24 | "Arn" 25 | ] 26 | } 27 | - ] 28 | + ], 29 | + "Effect": "Allow" 30 | } 31 | ] 32 | - } 33 | + }, 34 | + "PolicyName": "MyQueueGroupPolicy" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/java/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "MyQueue1": { 4 | "Type": "AWS::SQS::Queue" 5 | }, 6 | "MyQueue2": { 7 | "Type": "AWS::SQS::Queue" 8 | }, 9 | "MyRDMessageQueueGroup": { 10 | "Type": "AWS::IAM::Group", 11 | "Properties": { 12 | "Policies": [ 13 | { 14 | "PolicyDocument": { 15 | "Statement": [ 16 | { 17 | "Action": [ 18 | "sqs:DeleteMessage", 19 | "sqs:ReceiveMessage" 20 | ], 21 | "Resource": [ 22 | { 23 | "Fn::GetAtt": [ 24 | "MyQueue1", 25 | "Arn" 26 | ] 27 | }, 28 | { 29 | "Fn::GetAtt": [ 30 | "MyQueue2", 31 | "Arn" 32 | ] 33 | } 34 | ], 35 | "Effect": "Allow" 36 | } 37 | ] 38 | }, 39 | "PolicyName": "MyQueueGroupPolicy" 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new JsonPropsStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/java/src/main/java/com/myorg/Stack.java: -------------------------------------------------------------------------------- 1 | package com.myorg; 2 | 3 | import software.constructs.Construct; 4 | 5 | import java.util.*; 6 | import software.amazon.awscdk.CfnMapping; 7 | import software.amazon.awscdk.CfnTag; 8 | import software.amazon.awscdk.Stack; 9 | import software.amazon.awscdk.StackProps; 10 | 11 | import software.amazon.awscdk.*; 12 | import software.amazon.awscdk.services.iam.*; 13 | import software.amazon.awscdk.services.sqs.*; 14 | 15 | class JsonPropsStack extends Stack { 16 | public JsonPropsStack(final Construct scope, final String id) { 17 | super(scope, id, null); 18 | } 19 | 20 | public JsonPropsStack(final Construct scope, final String id, final StackProps props) { 21 | super(scope, id, props); 22 | 23 | CfnQueue myQueue1 = CfnQueue.Builder.create(this, "MyQueue1") 24 | .build(); 25 | 26 | CfnQueue myQueue2 = CfnQueue.Builder.create(this, "MyQueue2") 27 | .build(); 28 | 29 | CfnGroup myRdMessageQueueGroup = CfnGroup.Builder.create(this, "MyRDMessageQueueGroup") 30 | .policies(Arrays.asList( 31 | CfnGroup.PolicyProperty.builder() 32 | .policyName("MyQueueGroupPolicy") 33 | .policyDocument(Map.of("Statement", Arrays.asList( 34 | Map.of("Effect", "Allow", 35 | "Action", Arrays.asList( 36 | "sqs:DeleteMessage", 37 | "sqs:ReceiveMessage"), 38 | "Resource", Arrays.asList( 39 | myQueue1.getAttrArn(), 40 | myQueue2.getAttrArn()))))) 41 | .build())) 42 | .build(); 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/python/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/resource_w_json_type_properties/template.json b/tests/end-to-end/resource_w_json_type_properties-python-working-dir/cdk.out/Stack.template.json 2 | index 3fc1712..415a5dc 100644 3 | --- a/./tests/end-to-end/resource_w_json_type_properties/template.json 4 | +++ b/tests/end-to-end/resource_w_json_type_properties-python-working-dir/cdk.out/Stack.template.json 5 | @@ -1,5 +1,4 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | "Resources": { 9 | "MyQueue1": { 10 | "Type": "AWS::SQS::Queue" 11 | @@ -12,7 +11,6 @@ 12 | "Properties": { 13 | "Policies": [ 14 | { 15 | - "PolicyName": "MyQueueGroupPolicy", 16 | "PolicyDocument": { 17 | "Statement": [ 18 | { 19 | @@ -37,7 +35,8 @@ 20 | ] 21 | } 22 | ] 23 | - } 24 | + }, 25 | + "PolicyName": "MyQueueGroupPolicy" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "MyQueue1": { 4 | "Type": "AWS::SQS::Queue" 5 | }, 6 | "MyQueue2": { 7 | "Type": "AWS::SQS::Queue" 8 | }, 9 | "MyRDMessageQueueGroup": { 10 | "Type": "AWS::IAM::Group", 11 | "Properties": { 12 | "Policies": [ 13 | { 14 | "PolicyDocument": { 15 | "Statement": [ 16 | { 17 | "Effect": "Allow", 18 | "Action": [ 19 | "sqs:DeleteMessage", 20 | "sqs:ReceiveMessage" 21 | ], 22 | "Resource": [ 23 | { 24 | "Fn::GetAtt": [ 25 | "MyQueue1", 26 | "Arn" 27 | ] 28 | }, 29 | { 30 | "Fn::GetAtt": [ 31 | "MyQueue2", 32 | "Arn" 33 | ] 34 | } 35 | ] 36 | } 37 | ] 38 | }, 39 | "PolicyName": "MyQueueGroupPolicy" 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import JsonPropsStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | JsonPropsStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/python/stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack 2 | import aws_cdk as cdk 3 | import aws_cdk.aws_iam as iam 4 | import aws_cdk.aws_sqs as sqs 5 | from constructs import Construct 6 | 7 | class JsonPropsStack(Stack): 8 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 9 | super().__init__(scope, construct_id, **kwargs) 10 | 11 | # Resources 12 | myQueue1 = sqs.CfnQueue(self, 'MyQueue1', 13 | ) 14 | 15 | myQueue2 = sqs.CfnQueue(self, 'MyQueue2', 16 | ) 17 | 18 | myRdMessageQueueGroup = iam.CfnGroup(self, 'MyRDMessageQueueGroup', 19 | policies = [ 20 | { 21 | 'policyName': 'MyQueueGroupPolicy', 22 | 'policyDocument': { 23 | 'Statement': [ 24 | { 25 | 'Effect': 'Allow', 26 | 'Action': [ 27 | 'sqs:DeleteMessage', 28 | 'sqs:ReceiveMessage', 29 | ], 30 | 'Resource': [ 31 | myQueue1.attr_arn, 32 | myQueue2.attr_arn, 33 | ], 34 | }, 35 | ], 36 | }, 37 | }, 38 | ], 39 | ) 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Resources": { 4 | "MyQueue1": { 5 | "Type": "AWS::SQS::Queue" 6 | }, 7 | "MyQueue2": { 8 | "Type": "AWS::SQS::Queue" 9 | }, 10 | "MyRDMessageQueueGroup": { 11 | "Type": "AWS::IAM::Group", 12 | "Properties": { 13 | "Policies": [ 14 | { 15 | "PolicyName": "MyQueueGroupPolicy", 16 | "PolicyDocument": { 17 | "Statement": [ 18 | { 19 | "Effect": "Allow", 20 | "Action": [ 21 | "sqs:DeleteMessage", 22 | "sqs:ReceiveMessage" 23 | ], 24 | "Resource": [ 25 | { 26 | "Fn::GetAtt": [ 27 | "MyQueue1", 28 | "Arn" 29 | ] 30 | }, 31 | { 32 | "Fn::GetAtt": [ 33 | "MyQueue2", 34 | "Arn" 35 | ] 36 | } 37 | ] 38 | } 39 | ] 40 | } 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/typescript/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/resource_w_json_type_properties/template.json b/tests/end-to-end/resource_w_json_type_properties-typescript-working-dir/cdk.out/Stack.template.json 2 | index 3fc1712..415a5dc 100644 3 | --- a/./tests/end-to-end/resource_w_json_type_properties/template.json 4 | +++ b/tests/end-to-end/resource_w_json_type_properties-typescript-working-dir/cdk.out/Stack.template.json 5 | @@ -1,5 +1,4 @@ 6 | { 7 | - "AWSTemplateFormatVersion": "2010-09-09", 8 | "Resources": { 9 | "MyQueue1": { 10 | "Type": "AWS::SQS::Queue" 11 | @@ -12,7 +11,6 @@ 12 | "Properties": { 13 | "Policies": [ 14 | { 15 | - "PolicyName": "MyQueueGroupPolicy", 16 | "PolicyDocument": { 17 | "Statement": [ 18 | { 19 | @@ -37,7 +35,8 @@ 20 | ] 21 | } 22 | ] 23 | - } 24 | + }, 25 | + "PolicyName": "MyQueueGroupPolicy" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "MyQueue1": { 4 | "Type": "AWS::SQS::Queue" 5 | }, 6 | "MyQueue2": { 7 | "Type": "AWS::SQS::Queue" 8 | }, 9 | "MyRDMessageQueueGroup": { 10 | "Type": "AWS::IAM::Group", 11 | "Properties": { 12 | "Policies": [ 13 | { 14 | "PolicyDocument": { 15 | "Statement": [ 16 | { 17 | "Effect": "Allow", 18 | "Action": [ 19 | "sqs:DeleteMessage", 20 | "sqs:ReceiveMessage" 21 | ], 22 | "Resource": [ 23 | { 24 | "Fn::GetAtt": [ 25 | "MyQueue1", 26 | "Arn" 27 | ] 28 | }, 29 | { 30 | "Fn::GetAtt": [ 31 | "MyQueue2", 32 | "Arn" 33 | ] 34 | } 35 | ] 36 | } 37 | ] 38 | }, 39 | "PolicyName": "MyQueueGroupPolicy" 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { JsonPropsStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new JsonPropsStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/resource_w_json_type_properties/typescript/stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as iam from 'aws-cdk-lib/aws-iam'; 3 | import * as sqs from 'aws-cdk-lib/aws-sqs'; 4 | 5 | export interface JsonPropsStackProps extends cdk.StackProps { 6 | } 7 | 8 | export class JsonPropsStack extends cdk.Stack { 9 | public constructor(scope: cdk.App, id: string, props: JsonPropsStackProps = {}) { 10 | super(scope, id, props); 11 | 12 | // Resources 13 | const myQueue1 = new sqs.CfnQueue(this, 'MyQueue1', { 14 | }); 15 | 16 | const myQueue2 = new sqs.CfnQueue(this, 'MyQueue2', { 17 | }); 18 | 19 | const myRdMessageQueueGroup = new iam.CfnGroup(this, 'MyRDMessageQueueGroup', { 20 | policies: [ 21 | { 22 | policyName: 'MyQueueGroupPolicy', 23 | policyDocument: { 24 | Statement: [ 25 | { 26 | Effect: 'Allow', 27 | Action: [ 28 | 'sqs:DeleteMessage', 29 | 'sqs:ReceiveMessage', 30 | ], 31 | Resource: [ 32 | myQueue1.attrArn, 33 | myQueue2.attrArn, 34 | ], 35 | }, 36 | ], 37 | }, 38 | }, 39 | ], 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new SAMNodeJSLambda.SAMNodeJSLambda(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/csharp/Stack.cs: -------------------------------------------------------------------------------- 1 | using Amazon.CDK; 2 | using Amazon.CDK.AWS.SAM; 3 | using Constructs; 4 | using System.Collections.Generic; 5 | 6 | namespace SAMNodeJSLambda 7 | { 8 | public class SAMNodeJSLambdaProps : StackProps 9 | { 10 | } 11 | 12 | public class SAMNodeJSLambda : Stack 13 | { 14 | public SAMNodeJSLambda(Construct scope, string id, SAMNodeJSLambdaProps props = null) : base(scope, id, props) 15 | { 16 | // Transforms 17 | AddTransform("AWS::Serverless-2016-10-31"); 18 | 19 | // Resources 20 | var myFunction = new CfnFunction(this, "MyFunction", new CfnFunctionProps 21 | { 22 | Runtime = "nodejs18.x", 23 | Handler = "index.handler", 24 | InlineCode = @"exports.handler = async (event) => { 25 | console.log(event); 26 | } 27 | ", 28 | }); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/csharp/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/sam_nodejs_lambda/template.json b/tests/end-to-end/sam_nodejs_lambda-csharp-working-dir/cdk.out/Stack.template.json 2 | index a2eafe6..e26b60a 100644 3 | --- a/./tests/end-to-end/sam_nodejs_lambda/template.json 4 | +++ b/tests/end-to-end/sam_nodejs_lambda-csharp-working-dir/cdk.out/Stack.template.json 5 | @@ -1,12 +1,14 @@ 6 | { 7 | - "Transform": "AWS::Serverless-2016-10-31", 8 | + "Transform": [ 9 | + "AWS::Serverless-2016-10-31" 10 | + ], 11 | "Resources": { 12 | "MyFunction": { 13 | "Type": "AWS::Serverless::Function", 14 | "Properties": { 15 | - "Runtime": "nodejs18.x", 16 | "Handler": "index.handler", 17 | - "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n" 18 | + "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n }\n ", 19 | + "Runtime": "nodejs18.x" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Transform": [ 3 | "AWS::Serverless-2016-10-31" 4 | ], 5 | "Resources": { 6 | "MyFunction": { 7 | "Type": "AWS::Serverless::Function", 8 | "Properties": { 9 | "Handler": "index.handler", 10 | "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n }\n ", 11 | "Runtime": "nodejs18.x" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/golang/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/sam_nodejs_lambda/template.json b/tests/end-to-end/sam_nodejs_lambda-golang-working-dir/cdk.out/Stack.template.json 2 | index a2eafe6..5d58b90 100644 3 | --- a/./tests/end-to-end/sam_nodejs_lambda/template.json 4 | +++ b/tests/end-to-end/sam_nodejs_lambda-golang-working-dir/cdk.out/Stack.template.json 5 | @@ -1,12 +1,14 @@ 6 | { 7 | - "Transform": "AWS::Serverless-2016-10-31", 8 | + "Transform": [ 9 | + "AWS::Serverless-2016-10-31" 10 | + ], 11 | "Resources": { 12 | "MyFunction": { 13 | "Type": "AWS::Serverless::Function", 14 | "Properties": { 15 | - "Runtime": "nodejs18.x", 16 | "Handler": "index.handler", 17 | - "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n" 18 | + "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n", 19 | + "Runtime": "nodejs18.x" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/golang/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Transform": [ 3 | "AWS::Serverless-2016-10-31" 4 | ], 5 | "Resources": { 6 | "MyFunction": { 7 | "Type": "AWS::Serverless::Function", 8 | "Properties": { 9 | "Handler": "index.handler", 10 | "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n", 11 | "Runtime": "nodejs18.x" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/golang/app.go: -------------------------------------------------------------------------------- 1 | // auto-generated 2 | package main 3 | import ( 4 | "github.com/aws/aws-cdk-go/awscdk/v2" 5 | "github.com/aws/jsii-runtime-go" 6 | ) 7 | func main() { 8 | defer jsii.Close() 9 | app := awscdk.NewApp(&awscdk.AppProps{ 10 | DefaultStackSynthesizer: awscdk.NewDefaultStackSynthesizer(&awscdk.DefaultStackSynthesizerProps{ 11 | GenerateBootstrapVersionRule: jsii.Bool(false), 12 | }), 13 | }) 14 | NewSAMNodeJSLambda(app, "Stack", nil) 15 | app.Synth(nil) 16 | } 17 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/golang/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | cdk "github.com/aws/aws-cdk-go/awscdk/v2" 5 | sam "github.com/aws/aws-cdk-go/awscdk/v2/awssam" 6 | "github.com/aws/constructs-go/constructs/v10" 7 | "github.com/aws/jsii-runtime-go" 8 | ) 9 | 10 | type SAMNodeJSLambdaProps struct { 11 | cdk.StackProps 12 | } 13 | 14 | type SAMNodeJSLambda struct { 15 | cdk.Stack 16 | } 17 | 18 | func NewSAMNodeJSLambda(scope constructs.Construct, id string, props *SAMNodeJSLambdaProps) *SAMNodeJSLambda { 19 | var sprops cdk.StackProps 20 | if props != nil { 21 | sprops = props.StackProps 22 | } 23 | stack := cdk.NewStack(scope, &id, &sprops) 24 | 25 | stack.AddTransform(jsii.String("AWS::Serverless-2016-10-31")) 26 | 27 | sam.NewCfnFunction( 28 | stack, 29 | jsii.String("MyFunction"), 30 | &sam.CfnFunctionProps{ 31 | Runtime: jsii.String("nodejs18.x"), 32 | Handler: jsii.String("index.handler"), 33 | InlineCode: jsii.String("exports.handler = async (event) => {\n console.log(event);\n}\n"), 34 | }, 35 | ) 36 | 37 | return &SAMNodeJSLambda{ 38 | Stack: stack, 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/java/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/sam_nodejs_lambda/template.json b/tests/end-to-end/sam_nodejs_lambda-java-working-dir/cdk.out/Stack.template.json 2 | index a2eafe6..5d58b90 100644 3 | --- a/./tests/end-to-end/sam_nodejs_lambda/template.json 4 | +++ b/tests/end-to-end/sam_nodejs_lambda-java-working-dir/cdk.out/Stack.template.json 5 | @@ -1,12 +1,14 @@ 6 | { 7 | - "Transform": "AWS::Serverless-2016-10-31", 8 | + "Transform": [ 9 | + "AWS::Serverless-2016-10-31" 10 | + ], 11 | "Resources": { 12 | "MyFunction": { 13 | "Type": "AWS::Serverless::Function", 14 | "Properties": { 15 | - "Runtime": "nodejs18.x", 16 | "Handler": "index.handler", 17 | - "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n" 18 | + "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n", 19 | + "Runtime": "nodejs18.x" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/java/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Transform": [ 3 | "AWS::Serverless-2016-10-31" 4 | ], 5 | "Resources": { 6 | "MyFunction": { 7 | "Type": "AWS::Serverless::Function", 8 | "Properties": { 9 | "Handler": "index.handler", 10 | "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n", 11 | "Runtime": "nodejs18.x" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new SAMNodeJSLambda(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/java/src/main/java/com/myorg/Stack.java: -------------------------------------------------------------------------------- 1 | package com.myorg; 2 | 3 | import software.constructs.Construct; 4 | 5 | import java.util.*; 6 | import software.amazon.awscdk.CfnMapping; 7 | import software.amazon.awscdk.CfnTag; 8 | import software.amazon.awscdk.Stack; 9 | import software.amazon.awscdk.StackProps; 10 | 11 | import software.amazon.awscdk.*; 12 | import software.amazon.awscdk.services.sam.*; 13 | 14 | class SAMNodeJSLambda extends Stack { 15 | public SAMNodeJSLambda(final Construct scope, final String id) { 16 | super(scope, id, null); 17 | } 18 | 19 | public SAMNodeJSLambda(final Construct scope, final String id, final StackProps props) { 20 | super(scope, id, props); 21 | 22 | this.addTransform("AWS::Serverless-2016-10-31"); 23 | 24 | CfnFunction myFunction = CfnFunction.Builder.create(this, "MyFunction") 25 | .runtime("nodejs18.x") 26 | .handler("index.handler") 27 | .inlineCode(""" 28 | exports.handler = async (event) => { 29 | console.log(event); 30 | } 31 | """) 32 | .build(); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/python/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/sam_nodejs_lambda/template.json b/tests/end-to-end/sam_nodejs_lambda-python-working-dir/cdk.out/Stack.template.json 2 | index a2eafe6..5d58b90 100644 3 | --- a/./tests/end-to-end/sam_nodejs_lambda/template.json 4 | +++ b/tests/end-to-end/sam_nodejs_lambda-python-working-dir/cdk.out/Stack.template.json 5 | @@ -1,12 +1,14 @@ 6 | { 7 | - "Transform": "AWS::Serverless-2016-10-31", 8 | + "Transform": [ 9 | + "AWS::Serverless-2016-10-31" 10 | + ], 11 | "Resources": { 12 | "MyFunction": { 13 | "Type": "AWS::Serverless::Function", 14 | "Properties": { 15 | - "Runtime": "nodejs18.x", 16 | "Handler": "index.handler", 17 | - "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n" 18 | + "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n", 19 | + "Runtime": "nodejs18.x" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Transform": [ 3 | "AWS::Serverless-2016-10-31" 4 | ], 5 | "Resources": { 6 | "MyFunction": { 7 | "Type": "AWS::Serverless::Function", 8 | "Properties": { 9 | "Handler": "index.handler", 10 | "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n", 11 | "Runtime": "nodejs18.x" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import SAMNodeJSLambda 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | SAMNodeJSLambda(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/python/stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack 2 | import aws_cdk as cdk 3 | import aws_cdk.aws_sam as sam 4 | from constructs import Construct 5 | 6 | class SAMNodeJSLambda(Stack): 7 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 8 | super().__init__(scope, construct_id, **kwargs) 9 | 10 | # Transforms 11 | Stack.add_transform(self, 'AWS::Serverless-2016-10-31') 12 | 13 | # Resources 14 | myFunction = sam.CfnFunction(self, 'MyFunction', 15 | runtime = 'nodejs18.x', 16 | handler = 'index.handler', 17 | inline_code = 'exports.handler = async (event) => {\n console.log(event);\n}\n', 18 | ) 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Transform": "AWS::Serverless-2016-10-31", 3 | "Resources": { 4 | "MyFunction": { 5 | "Type": "AWS::Serverless::Function", 6 | "Properties": { 7 | "Runtime": "nodejs18.x", 8 | "Handler": "index.handler", 9 | "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/typescript/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/sam_nodejs_lambda/template.json b/tests/end-to-end/sam_nodejs_lambda-typescript-working-dir/cdk.out/Stack.template.json 2 | index a2eafe6..5d58b90 100644 3 | --- a/./tests/end-to-end/sam_nodejs_lambda/template.json 4 | +++ b/tests/end-to-end/sam_nodejs_lambda-typescript-working-dir/cdk.out/Stack.template.json 5 | @@ -1,12 +1,14 @@ 6 | { 7 | - "Transform": "AWS::Serverless-2016-10-31", 8 | + "Transform": [ 9 | + "AWS::Serverless-2016-10-31" 10 | + ], 11 | "Resources": { 12 | "MyFunction": { 13 | "Type": "AWS::Serverless::Function", 14 | "Properties": { 15 | - "Runtime": "nodejs18.x", 16 | "Handler": "index.handler", 17 | - "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n" 18 | + "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n", 19 | + "Runtime": "nodejs18.x" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Transform": [ 3 | "AWS::Serverless-2016-10-31" 4 | ], 5 | "Resources": { 6 | "MyFunction": { 7 | "Type": "AWS::Serverless::Function", 8 | "Properties": { 9 | "Handler": "index.handler", 10 | "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n", 11 | "Runtime": "nodejs18.x" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { SAMNodeJSLambda } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new SAMNodeJSLambda(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda/typescript/stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as sam from 'aws-cdk-lib/aws-sam'; 3 | 4 | export interface SAMNodeJSLambdaProps extends cdk.StackProps { 5 | } 6 | 7 | export class SAMNodeJSLambda extends cdk.Stack { 8 | public constructor(scope: cdk.App, id: string, props: SAMNodeJSLambdaProps = {}) { 9 | super(scope, id, props); 10 | 11 | // Transforms 12 | this.addTransform('AWS::Serverless-2016-10-31'); 13 | 14 | // Resources 15 | const myFunction = new sam.CfnFunction(this, 'MyFunction', { 16 | runtime: 'nodejs18.x', 17 | handler: 'index.handler', 18 | inlineCode: 'exports.handler = async (event) => {\n console.log(event);\n}\n', 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda_arr_transform/csharp/Stack.cs: -------------------------------------------------------------------------------- 1 | using Amazon.CDK; 2 | using Amazon.CDK.AWS.SAM; 3 | using Constructs; 4 | using System.Collections.Generic; 5 | 6 | namespace SAMNodeJSLambda 7 | { 8 | public class SAMNodeJSLambdaProps : StackProps 9 | { 10 | } 11 | 12 | public class SAMNodeJSLambda : Stack 13 | { 14 | public SAMNodeJSLambda(Construct scope, string id, SAMNodeJSLambdaProps props = null) : base(scope, id, props) 15 | { 16 | // Transforms 17 | AddTransform("AWS::Serverless-2016-10-31"); 18 | 19 | // Resources 20 | var myFunction = new CfnFunction(this, "MyFunction", new CfnFunctionProps 21 | { 22 | Runtime = "nodejs18.x", 23 | Handler = "index.handler", 24 | InlineCode = @"exports.handler = async (event) => { 25 | console.log(event); 26 | } 27 | ", 28 | }); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda_arr_transform/golang/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | cdk "github.com/aws/aws-cdk-go/awscdk/v2" 5 | sam "github.com/aws/aws-cdk-go/awscdk/v2/awssam" 6 | "github.com/aws/constructs-go/constructs/v10" 7 | "github.com/aws/jsii-runtime-go" 8 | ) 9 | 10 | type SAMNodeJSLambdaProps struct { 11 | cdk.StackProps 12 | } 13 | 14 | type SAMNodeJSLambda struct { 15 | cdk.Stack 16 | } 17 | 18 | func NewSAMNodeJSLambda(scope constructs.Construct, id string, props *SAMNodeJSLambdaProps) *SAMNodeJSLambda { 19 | var sprops cdk.StackProps 20 | if props != nil { 21 | sprops = props.StackProps 22 | } 23 | stack := cdk.NewStack(scope, &id, &sprops) 24 | 25 | stack.AddTransform(jsii.String("AWS::Serverless-2016-10-31")) 26 | 27 | sam.NewCfnFunction( 28 | stack, 29 | jsii.String("MyFunction"), 30 | &sam.CfnFunctionProps{ 31 | Runtime: jsii.String("nodejs18.x"), 32 | Handler: jsii.String("index.handler"), 33 | InlineCode: jsii.String("exports.handler = async (event) => {\n console.log(event);\n}\n"), 34 | }, 35 | ) 36 | 37 | return &SAMNodeJSLambda{ 38 | Stack: stack, 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda_arr_transform/java/src/main/java/com/myorg/Stack.java: -------------------------------------------------------------------------------- 1 | package com.myorg; 2 | 3 | import software.constructs.Construct; 4 | 5 | import java.util.*; 6 | import software.amazon.awscdk.CfnMapping; 7 | import software.amazon.awscdk.CfnTag; 8 | import software.amazon.awscdk.Stack; 9 | import software.amazon.awscdk.StackProps; 10 | 11 | import software.amazon.awscdk.*; 12 | import software.amazon.awscdk.services.sam.*; 13 | 14 | class SAMNodeJSLambda extends Stack { 15 | public SAMNodeJSLambda(final Construct scope, final String id) { 16 | super(scope, id, null); 17 | } 18 | 19 | public SAMNodeJSLambda(final Construct scope, final String id, final StackProps props) { 20 | super(scope, id, props); 21 | 22 | this.addTransform("AWS::Serverless-2016-10-31"); 23 | 24 | CfnFunction myFunction = CfnFunction.Builder.create(this, "MyFunction") 25 | .runtime("nodejs18.x") 26 | .handler("index.handler") 27 | .inlineCode(""" 28 | exports.handler = async (event) => { 29 | console.log(event); 30 | } 31 | """) 32 | .build(); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda_arr_transform/python/stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack 2 | import aws_cdk as cdk 3 | import aws_cdk.aws_sam as sam 4 | from constructs import Construct 5 | 6 | class SAMNodeJSLambda(Stack): 7 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 8 | super().__init__(scope, construct_id, **kwargs) 9 | 10 | # Transforms 11 | Stack.add_transform(self, 'AWS::Serverless-2016-10-31') 12 | 13 | # Resources 14 | myFunction = sam.CfnFunction(self, 'MyFunction', 15 | runtime = 'nodejs18.x', 16 | handler = 'index.handler', 17 | inline_code = 'exports.handler = async (event) => {\n console.log(event);\n}\n', 18 | ) 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda_arr_transform/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Transform": [ 3 | "AWS::Serverless-2016-10-31" 4 | ], 5 | "Resources": { 6 | "MyFunction": { 7 | "Type": "AWS::Serverless::Function", 8 | "Properties": { 9 | "Runtime": "nodejs18.x", 10 | "Handler": "index.handler", 11 | "InlineCode": "exports.handler = async (event) => {\n console.log(event);\n}\n" 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/end-to-end/sam_nodejs_lambda_arr_transform/typescript/stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as sam from 'aws-cdk-lib/aws-sam'; 3 | 4 | export interface SAMNodeJSLambdaProps extends cdk.StackProps { 5 | } 6 | 7 | export class SAMNodeJSLambda extends cdk.Stack { 8 | public constructor(scope: cdk.App, id: string, props: SAMNodeJSLambdaProps = {}) { 9 | super(scope, id, props); 10 | 11 | // Transforms 12 | this.addTransform('AWS::Serverless-2016-10-31'); 13 | 14 | // Resources 15 | const myFunction = new sam.CfnFunction(this, 'MyFunction', { 16 | runtime: 'nodejs18.x', 17 | handler: 'index.handler', 18 | inlineCode: 'exports.handler = async (event) => {\n console.log(event);\n}\n', 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/end-to-end/simple/create_first.json: -------------------------------------------------------------------------------- 1 | { 2 | "Description": "A stack that creates any resources that template.json depends on.", 3 | "Resources": { 4 | "Bucket": { 5 | "Type": "AWS::S3::Bucket", 6 | "DeletionPolicy": "Delete" 7 | }, 8 | "LoggingBucketName": { 9 | "Type": "AWS::SSM::Parameter", 10 | "Properties": { 11 | "Name": "/logging/bucket/name", 12 | "Type": "String", 13 | "Value": { 14 | "Ref": "Bucket" 15 | } 16 | } 17 | } 18 | }, 19 | "Outputs": { 20 | "SampleExport": { 21 | "Description": "The ARN of a kms key", 22 | "Export": { 23 | "Name": "Shared-KmsKeyArn" 24 | }, 25 | "Value": "FakeARN" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /tests/end-to-end/simple/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new SimpleStack.SimpleStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/simple/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "LogDestinationBucketName": { 4 | "Type": "AWS::SSM::Parameter::Value", 5 | "Default": "/logging/bucket/name" 6 | } 7 | }, 8 | "Resources": { 9 | "Queue": { 10 | "Type": "AWS::SQS::Queue", 11 | "Properties": { 12 | "DelaySeconds": 42, 13 | "KmsMasterKeyId": { 14 | "Fn::ImportValue": "Shared-KmsKeyArn" 15 | }, 16 | "QueueName": { 17 | "Fn::Join": [ 18 | "", 19 | [ 20 | "Stack-Bar-", 21 | { 22 | "Fn::Select": [ 23 | 1, 24 | { 25 | "Fn::GetAZs": { 26 | "Ref": "AWS::Region" 27 | } 28 | } 29 | ] 30 | } 31 | ] 32 | ] 33 | }, 34 | "SqsManagedSseEnabled": false, 35 | "VisibilityTimeout": 120 36 | } 37 | }, 38 | "Bucket": { 39 | "Type": "AWS::S3::Bucket", 40 | "Properties": { 41 | "AccessControl": "Private", 42 | "BucketName": { 43 | "Fn::Join": [ 44 | "", 45 | [ 46 | "bucket-", 47 | { 48 | "Ref": "AWS::Region" 49 | }, 50 | "-bucket" 51 | ] 52 | ] 53 | }, 54 | "LoggingConfiguration": { 55 | "DestinationBucketName": { 56 | "Ref": "LogDestinationBucketName" 57 | } 58 | }, 59 | "Tags": [ 60 | { 61 | "Key": "FancyTag", 62 | "Value": { 63 | "Fn::Base64": "8CiMvAo=" 64 | } 65 | } 66 | ], 67 | "WebsiteConfiguration": { 68 | "RedirectAllRequestsTo": { 69 | "HostName": "example.com", 70 | "Protocol": "https" 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /tests/end-to-end/simple/java/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "LogDestinationBucketName": { 4 | "Type": "AWS::SSM::Parameter::Value", 5 | "Default": "/logging/bucket/name" 6 | } 7 | }, 8 | "Mappings": { 9 | "booleans": { 10 | "True": { 11 | "true": true 12 | }, 13 | "False": { 14 | "false": false 15 | } 16 | }, 17 | "lists": { 18 | "Candidates": { 19 | "Empty": [ 20 | "" 21 | ], 22 | "Singleton": [ 23 | "One" 24 | ], 25 | "Pair": [ 26 | "One", 27 | "Two" 28 | ] 29 | } 30 | }, 31 | "numbers": { 32 | "Prime": { 33 | "Eleven": 11, 34 | "Thirteen": 13, 35 | "Seventeen": 17 36 | } 37 | }, 38 | "strings": { 39 | "Foos": { 40 | "Foo1": "Foo1", 41 | "Foo2": "Foo2" 42 | }, 43 | "Bars": { 44 | "Bar": "Bar" 45 | } 46 | }, 47 | "table": { 48 | "Values": { 49 | "Boolean": true, 50 | "Float": 3.14, 51 | "List": [ 52 | "1", 53 | "2", 54 | "3" 55 | ], 56 | "Number": 42, 57 | "String": "Baz" 58 | } 59 | } 60 | }, 61 | "Resources": { 62 | "Queue": { 63 | "Type": "AWS::SQS::Queue", 64 | "Properties": { 65 | "DelaySeconds": 42, 66 | "KmsMasterKeyId": { 67 | "Fn::ImportValue": "Shared-KmsKeyArn" 68 | }, 69 | "QueueName": { 70 | "Fn::Join": [ 71 | "", 72 | [ 73 | "Stack-", 74 | { 75 | "Fn::FindInMap": [ 76 | "strings", 77 | "Bars", 78 | "Bar" 79 | ] 80 | }, 81 | "-", 82 | { 83 | "Fn::Select": [ 84 | 1, 85 | { 86 | "Fn::GetAZs": { 87 | "Ref": "AWS::Region" 88 | } 89 | } 90 | ] 91 | } 92 | ] 93 | ] 94 | }, 95 | "SqsManagedSseEnabled": false, 96 | "VisibilityTimeout": 120 97 | }, 98 | "UpdateReplacePolicy": "Retain", 99 | "DeletionPolicy": "RetainExceptOnCreate" 100 | } 101 | }, 102 | "Outputs": { 103 | "QueueArn": { 104 | "Description": "The ARN of the SQS Queue", 105 | "Value": { 106 | "Ref": "Queue" 107 | } 108 | }, 109 | "IsLarge": { 110 | "Description": "Whether this is a large region or not", 111 | "Value": "false" 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /tests/end-to-end/simple/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new SimpleStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/simple/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "logDestinationBucketName": { 4 | "Type": "AWS::SSM::Parameter::Value", 5 | "Default": "/logging/bucket/name" 6 | } 7 | }, 8 | "Resources": { 9 | "Queue": { 10 | "Type": "AWS::SQS::Queue", 11 | "Properties": { 12 | "DelaySeconds": 42, 13 | "KmsMasterKeyId": { 14 | "Fn::ImportValue": "Shared-KmsKeyArn" 15 | }, 16 | "QueueName": { 17 | "Fn::Join": [ 18 | "", 19 | [ 20 | "Stack-Bar-", 21 | { 22 | "Fn::Select": [ 23 | 1, 24 | { 25 | "Fn::GetAZs": { 26 | "Ref": "AWS::Region" 27 | } 28 | } 29 | ] 30 | } 31 | ] 32 | ] 33 | }, 34 | "SqsManagedSseEnabled": false, 35 | "VisibilityTimeout": 120 36 | }, 37 | "DeletionPolicy": "RetainExceptOnCreate" 38 | } 39 | }, 40 | "Outputs": { 41 | "QueueArn": { 42 | "Description": "The ARN of the SQS Queue", 43 | "Value": { 44 | "Ref": "Queue" 45 | } 46 | }, 47 | "IsLarge": { 48 | "Description": "Whether this is a large region or not", 49 | "Value": "False" 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /tests/end-to-end/simple/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import SimpleStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | SimpleStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/simple/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "LogDestinationBucketName": { 4 | "Type": "AWS::SSM::Parameter::Value", 5 | "Default": "/logging/bucket/name" 6 | } 7 | }, 8 | "Resources": { 9 | "Queue": { 10 | "Type": "AWS::SQS::Queue", 11 | "Properties": { 12 | "DelaySeconds": 42, 13 | "KmsMasterKeyId": { 14 | "Fn::ImportValue": "Shared-KmsKeyArn" 15 | }, 16 | "QueueName": { 17 | "Fn::Join": [ 18 | "", 19 | [ 20 | "Stack-Bar-", 21 | { 22 | "Fn::Select": [ 23 | 1, 24 | { 25 | "Fn::GetAZs": { 26 | "Ref": "AWS::Region" 27 | } 28 | } 29 | ] 30 | } 31 | ] 32 | ] 33 | }, 34 | "SqsManagedSseEnabled": false, 35 | "VisibilityTimeout": 120 36 | }, 37 | "DeletionPolicy": "RetainExceptOnCreate" 38 | } 39 | }, 40 | "Outputs": { 41 | "QueueArn": { 42 | "Description": "The ARN of the SQS Queue", 43 | "Value": { 44 | "Ref": "Queue" 45 | } 46 | }, 47 | "IsLarge": { 48 | "Description": "Whether this is a large region or not", 49 | "Value": "false" 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /tests/end-to-end/simple/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { SimpleStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new SimpleStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/tsconfig.json: -------------------------------------------------------------------------------- 1 | // This TypeScript config is here for developer comfort... 2 | { 3 | "compilerOptions": { 4 | "target": "ESNext", 5 | "module": "CommonJS", 6 | "lib": [ 7 | "es2015", 8 | "dom" 9 | ], 10 | "strict": true, 11 | "skipLibCheck": true, 12 | "baseUrl": ".", 13 | "noEmit": true, 14 | }, 15 | "include": [ 16 | "*/*.ts" 17 | ], 18 | "exclude": [ 19 | "node_modules", 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/csharp/Program.cs: -------------------------------------------------------------------------------- 1 | //Auto-generated 2 | using Amazon.CDK; 3 | sealed class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | var app = new App(new AppProps 8 | { 9 | DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps 10 | { 11 | GenerateBootstrapVersionRule = false, 12 | }), 13 | }); 14 | new VpcStack.VpcStack(app, "Stack"); 15 | app.Synth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/csharp/Stack.cs: -------------------------------------------------------------------------------- 1 | using Amazon.CDK; 2 | using Amazon.CDK.AWS.EC2; 3 | using Constructs; 4 | using System.Collections.Generic; 5 | 6 | namespace VpcStack 7 | { 8 | public class VpcStackProps : StackProps 9 | { 10 | } 11 | 12 | public class VpcStack : Stack 13 | { 14 | public VpcStack(Construct scope, string id, VpcStackProps props = null) : base(scope, id, props) 15 | { 16 | 17 | // Resources 18 | var vpc = new CfnVPC(this, "VPC", new CfnVPCProps 19 | { 20 | CidrBlock = "10.42.0.0/16", 21 | EnableDnsSupport = true, 22 | EnableDnsHostnames = true, 23 | Tags = new [] 24 | { 25 | new CfnTag 26 | { 27 | Key = "cost-center", 28 | Value = "1337", 29 | }, 30 | }, 31 | }); 32 | var subnet1 = new CfnSubnet(this, "Subnet1", new CfnSubnetProps 33 | { 34 | AvailabilityZone = Fn.Select(0, Fn.GetAzs("")), 35 | CidrBlock = Fn.Select(0, Fn.Cidr(vpc.AttrCidrBlock, 6, "8")), 36 | VpcId = vpc.Ref, 37 | }); 38 | var subnet2 = new CfnSubnet(this, "Subnet2", new CfnSubnetProps 39 | { 40 | AvailabilityZone = Fn.Select(1, Fn.GetAzs("")), 41 | CidrBlock = Fn.Select(1, Fn.Cidr(vpc.AttrCidrBlock, 6, "8")), 42 | VpcId = vpc.Ref, 43 | }); 44 | var subnet3 = new CfnSubnet(this, "Subnet3", new CfnSubnetProps 45 | { 46 | AvailabilityZone = Fn.Select(2, Fn.GetAzs("")), 47 | CidrBlock = Fn.Select(2, Fn.Cidr(vpc.AttrCidrBlock, 6, "8")), 48 | VpcId = vpc.Ref, 49 | }); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/csharp/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/vpc/template.json b/tests/end-to-end/vpc-csharp-working-dir/cdk.out/Stack.template.json 2 | index cddd267..b101d46 100644 3 | --- a/./tests/end-to-end/vpc/template.json 4 | +++ b/tests/end-to-end/vpc-csharp-working-dir/cdk.out/Stack.template.json 5 | @@ -4,8 +4,8 @@ 6 | "Type": "AWS::EC2::VPC", 7 | "Properties": { 8 | "CidrBlock": "10.42.0.0/16", 9 | - "EnableDnsSupport": true, 10 | "EnableDnsHostnames": true, 11 | + "EnableDnsSupport": true, 12 | "Tags": [ 13 | { 14 | "Key": "cost-center", 15 | @@ -31,10 +31,13 @@ 16 | { 17 | "Fn::Cidr": [ 18 | { 19 | - "Fn::GetAtt": "VPC.CidrBlock" 20 | + "Fn::GetAtt": [ 21 | + "VPC", 22 | + "CidrBlock" 23 | + ] 24 | }, 25 | 6, 26 | - 8 27 | + "8" 28 | ] 29 | } 30 | ] 31 | @@ -61,10 +64,13 @@ 32 | { 33 | "Fn::Cidr": [ 34 | { 35 | - "Fn::GetAtt": "VPC.CidrBlock" 36 | + "Fn::GetAtt": [ 37 | + "VPC", 38 | + "CidrBlock" 39 | + ] 40 | }, 41 | 6, 42 | - 8 43 | + "8" 44 | ] 45 | } 46 | ] 47 | @@ -91,10 +97,13 @@ 48 | { 49 | "Fn::Cidr": [ 50 | { 51 | - "Fn::GetAtt": "VPC.CidrBlock" 52 | + "Fn::GetAtt": [ 53 | + "VPC", 54 | + "CidrBlock" 55 | + ] 56 | }, 57 | 6, 58 | - 8 59 | + "8" 60 | ] 61 | } 62 | ] 63 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/csharp/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "VPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.42.0.0/16", 7 | "EnableDnsHostnames": true, 8 | "EnableDnsSupport": true, 9 | "Tags": [ 10 | { 11 | "Key": "cost-center", 12 | "Value": "1337" 13 | } 14 | ] 15 | } 16 | }, 17 | "Subnet1": { 18 | "Type": "AWS::EC2::Subnet", 19 | "Properties": { 20 | "AvailabilityZone": { 21 | "Fn::Select": [ 22 | 0, 23 | { 24 | "Fn::GetAZs": "" 25 | } 26 | ] 27 | }, 28 | "CidrBlock": { 29 | "Fn::Select": [ 30 | 0, 31 | { 32 | "Fn::Cidr": [ 33 | { 34 | "Fn::GetAtt": [ 35 | "VPC", 36 | "CidrBlock" 37 | ] 38 | }, 39 | 6, 40 | "8" 41 | ] 42 | } 43 | ] 44 | }, 45 | "VpcId": { 46 | "Ref": "VPC" 47 | } 48 | } 49 | }, 50 | "Subnet2": { 51 | "Type": "AWS::EC2::Subnet", 52 | "Properties": { 53 | "AvailabilityZone": { 54 | "Fn::Select": [ 55 | 1, 56 | { 57 | "Fn::GetAZs": "" 58 | } 59 | ] 60 | }, 61 | "CidrBlock": { 62 | "Fn::Select": [ 63 | 1, 64 | { 65 | "Fn::Cidr": [ 66 | { 67 | "Fn::GetAtt": [ 68 | "VPC", 69 | "CidrBlock" 70 | ] 71 | }, 72 | 6, 73 | "8" 74 | ] 75 | } 76 | ] 77 | }, 78 | "VpcId": { 79 | "Ref": "VPC" 80 | } 81 | } 82 | }, 83 | "Subnet3": { 84 | "Type": "AWS::EC2::Subnet", 85 | "Properties": { 86 | "AvailabilityZone": { 87 | "Fn::Select": [ 88 | 2, 89 | { 90 | "Fn::GetAZs": "" 91 | } 92 | ] 93 | }, 94 | "CidrBlock": { 95 | "Fn::Select": [ 96 | 2, 97 | { 98 | "Fn::Cidr": [ 99 | { 100 | "Fn::GetAtt": [ 101 | "VPC", 102 | "CidrBlock" 103 | ] 104 | }, 105 | 6, 106 | "8" 107 | ] 108 | } 109 | ] 110 | }, 111 | "VpcId": { 112 | "Ref": "VPC" 113 | } 114 | } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /tests/end-to-end/vpc/golang/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/vpc/template.json b/tests/end-to-end/vpc-golang-working-dir/cdk.out/Stack.template.json 2 | index cddd267..b101d46 100644 3 | --- a/./tests/end-to-end/vpc/template.json 4 | +++ b/tests/end-to-end/vpc-golang-working-dir/cdk.out/Stack.template.json 5 | @@ -4,8 +4,8 @@ 6 | "Type": "AWS::EC2::VPC", 7 | "Properties": { 8 | "CidrBlock": "10.42.0.0/16", 9 | - "EnableDnsSupport": true, 10 | "EnableDnsHostnames": true, 11 | + "EnableDnsSupport": true, 12 | "Tags": [ 13 | { 14 | "Key": "cost-center", 15 | @@ -31,10 +31,13 @@ 16 | { 17 | "Fn::Cidr": [ 18 | { 19 | - "Fn::GetAtt": "VPC.CidrBlock" 20 | + "Fn::GetAtt": [ 21 | + "VPC", 22 | + "CidrBlock" 23 | + ] 24 | }, 25 | 6, 26 | - 8 27 | + "8" 28 | ] 29 | } 30 | ] 31 | @@ -61,10 +64,13 @@ 32 | { 33 | "Fn::Cidr": [ 34 | { 35 | - "Fn::GetAtt": "VPC.CidrBlock" 36 | + "Fn::GetAtt": [ 37 | + "VPC", 38 | + "CidrBlock" 39 | + ] 40 | }, 41 | 6, 42 | - 8 43 | + "8" 44 | ] 45 | } 46 | ] 47 | @@ -91,10 +97,13 @@ 48 | { 49 | "Fn::Cidr": [ 50 | { 51 | - "Fn::GetAtt": "VPC.CidrBlock" 52 | + "Fn::GetAtt": [ 53 | + "VPC", 54 | + "CidrBlock" 55 | + ] 56 | }, 57 | 6, 58 | - 8 59 | + "8" 60 | ] 61 | } 62 | ] 63 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/golang/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "VPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.42.0.0/16", 7 | "EnableDnsHostnames": true, 8 | "EnableDnsSupport": true, 9 | "Tags": [ 10 | { 11 | "Key": "cost-center", 12 | "Value": "1337" 13 | } 14 | ] 15 | } 16 | }, 17 | "Subnet1": { 18 | "Type": "AWS::EC2::Subnet", 19 | "Properties": { 20 | "AvailabilityZone": { 21 | "Fn::Select": [ 22 | 0, 23 | { 24 | "Fn::GetAZs": "" 25 | } 26 | ] 27 | }, 28 | "CidrBlock": { 29 | "Fn::Select": [ 30 | 0, 31 | { 32 | "Fn::Cidr": [ 33 | { 34 | "Fn::GetAtt": [ 35 | "VPC", 36 | "CidrBlock" 37 | ] 38 | }, 39 | 6, 40 | "8" 41 | ] 42 | } 43 | ] 44 | }, 45 | "VpcId": { 46 | "Ref": "VPC" 47 | } 48 | } 49 | }, 50 | "Subnet2": { 51 | "Type": "AWS::EC2::Subnet", 52 | "Properties": { 53 | "AvailabilityZone": { 54 | "Fn::Select": [ 55 | 1, 56 | { 57 | "Fn::GetAZs": "" 58 | } 59 | ] 60 | }, 61 | "CidrBlock": { 62 | "Fn::Select": [ 63 | 1, 64 | { 65 | "Fn::Cidr": [ 66 | { 67 | "Fn::GetAtt": [ 68 | "VPC", 69 | "CidrBlock" 70 | ] 71 | }, 72 | 6, 73 | "8" 74 | ] 75 | } 76 | ] 77 | }, 78 | "VpcId": { 79 | "Ref": "VPC" 80 | } 81 | } 82 | }, 83 | "Subnet3": { 84 | "Type": "AWS::EC2::Subnet", 85 | "Properties": { 86 | "AvailabilityZone": { 87 | "Fn::Select": [ 88 | 2, 89 | { 90 | "Fn::GetAZs": "" 91 | } 92 | ] 93 | }, 94 | "CidrBlock": { 95 | "Fn::Select": [ 96 | 2, 97 | { 98 | "Fn::Cidr": [ 99 | { 100 | "Fn::GetAtt": [ 101 | "VPC", 102 | "CidrBlock" 103 | ] 104 | }, 105 | 6, 106 | "8" 107 | ] 108 | } 109 | ] 110 | }, 111 | "VpcId": { 112 | "Ref": "VPC" 113 | } 114 | } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /tests/end-to-end/vpc/golang/app.go: -------------------------------------------------------------------------------- 1 | // auto-generated 2 | package main 3 | import ( 4 | "github.com/aws/aws-cdk-go/awscdk/v2" 5 | "github.com/aws/jsii-runtime-go" 6 | ) 7 | func main() { 8 | defer jsii.Close() 9 | app := awscdk.NewApp(&awscdk.AppProps{ 10 | DefaultStackSynthesizer: awscdk.NewDefaultStackSynthesizer(&awscdk.DefaultStackSynthesizerProps{ 11 | GenerateBootstrapVersionRule: jsii.Bool(false), 12 | }), 13 | }) 14 | NewVpcStack(app, "Stack", nil) 15 | app.Synth(nil) 16 | } 17 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/golang/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | cdk "github.com/aws/aws-cdk-go/awscdk/v2" 5 | ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2" 6 | "github.com/aws/constructs-go/constructs/v10" 7 | "github.com/aws/jsii-runtime-go" 8 | ) 9 | 10 | type VpcStackProps struct { 11 | cdk.StackProps 12 | } 13 | 14 | type VpcStack struct { 15 | cdk.Stack 16 | } 17 | 18 | func NewVpcStack(scope constructs.Construct, id string, props *VpcStackProps) *VpcStack { 19 | var sprops cdk.StackProps 20 | if props != nil { 21 | sprops = props.StackProps 22 | } 23 | stack := cdk.NewStack(scope, &id, &sprops) 24 | 25 | vpc := ec2.NewCfnVPC( 26 | stack, 27 | jsii.String("VPC"), 28 | &ec2.CfnVPCProps{ 29 | CidrBlock: jsii.String("10.42.0.0/16"), 30 | EnableDnsSupport: jsii.Bool(true), 31 | EnableDnsHostnames: jsii.Bool(true), 32 | Tags: &[]*cdk.CfnTag{ 33 | &cdk.CfnTag{ 34 | Key: jsii.String("cost-center"), 35 | Value: jsii.String("1337"), 36 | }, 37 | }, 38 | }, 39 | ) 40 | 41 | ec2.NewCfnSubnet( 42 | stack, 43 | jsii.String("Subnet1"), 44 | &ec2.CfnSubnetProps{ 45 | AvailabilityZone: cdk.Fn_Select(jsii.Number(0), cdk.Fn_GetAzs(jsii.String(""))), 46 | CidrBlock: cdk.Fn_Select(jsii.Number(0), cdk.Fn_Cidr(vpc.AttrCidrBlock(), jsii.Number(6), jsii.String("8"))), 47 | VpcId: vpc.Ref(), 48 | }, 49 | ) 50 | 51 | ec2.NewCfnSubnet( 52 | stack, 53 | jsii.String("Subnet2"), 54 | &ec2.CfnSubnetProps{ 55 | AvailabilityZone: cdk.Fn_Select(jsii.Number(1), cdk.Fn_GetAzs(jsii.String(""))), 56 | CidrBlock: cdk.Fn_Select(jsii.Number(1), cdk.Fn_Cidr(vpc.AttrCidrBlock(), jsii.Number(6), jsii.String("8"))), 57 | VpcId: vpc.Ref(), 58 | }, 59 | ) 60 | 61 | ec2.NewCfnSubnet( 62 | stack, 63 | jsii.String("Subnet3"), 64 | &ec2.CfnSubnetProps{ 65 | AvailabilityZone: cdk.Fn_Select(jsii.Number(2), cdk.Fn_GetAzs(jsii.String(""))), 66 | CidrBlock: cdk.Fn_Select(jsii.Number(2), cdk.Fn_Cidr(vpc.AttrCidrBlock(), jsii.Number(6), jsii.String("8"))), 67 | VpcId: vpc.Ref(), 68 | }, 69 | ) 70 | 71 | return &VpcStack{ 72 | Stack: stack, 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/java/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/vpc/template.json b/tests/end-to-end/vpc-java-working-dir/cdk.out/Stack.template.json 2 | index cddd267..b101d46 100644 3 | --- a/./tests/end-to-end/vpc/template.json 4 | +++ b/tests/end-to-end/vpc-java-working-dir/cdk.out/Stack.template.json 5 | @@ -4,8 +4,8 @@ 6 | "Type": "AWS::EC2::VPC", 7 | "Properties": { 8 | "CidrBlock": "10.42.0.0/16", 9 | - "EnableDnsSupport": true, 10 | "EnableDnsHostnames": true, 11 | + "EnableDnsSupport": true, 12 | "Tags": [ 13 | { 14 | "Key": "cost-center", 15 | @@ -31,10 +31,13 @@ 16 | { 17 | "Fn::Cidr": [ 18 | { 19 | - "Fn::GetAtt": "VPC.CidrBlock" 20 | + "Fn::GetAtt": [ 21 | + "VPC", 22 | + "CidrBlock" 23 | + ] 24 | }, 25 | 6, 26 | - 8 27 | + "8" 28 | ] 29 | } 30 | ] 31 | @@ -61,10 +64,13 @@ 32 | { 33 | "Fn::Cidr": [ 34 | { 35 | - "Fn::GetAtt": "VPC.CidrBlock" 36 | + "Fn::GetAtt": [ 37 | + "VPC", 38 | + "CidrBlock" 39 | + ] 40 | }, 41 | 6, 42 | - 8 43 | + "8" 44 | ] 45 | } 46 | ] 47 | @@ -91,10 +97,13 @@ 48 | { 49 | "Fn::Cidr": [ 50 | { 51 | - "Fn::GetAtt": "VPC.CidrBlock" 52 | + "Fn::GetAtt": [ 53 | + "VPC", 54 | + "CidrBlock" 55 | + ] 56 | }, 57 | 6, 58 | - 8 59 | + "8" 60 | ] 61 | } 62 | ] 63 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/java/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "VPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.42.0.0/16", 7 | "EnableDnsHostnames": true, 8 | "EnableDnsSupport": true, 9 | "Tags": [ 10 | { 11 | "Key": "cost-center", 12 | "Value": "1337" 13 | } 14 | ] 15 | } 16 | }, 17 | "Subnet1": { 18 | "Type": "AWS::EC2::Subnet", 19 | "Properties": { 20 | "AvailabilityZone": { 21 | "Fn::Select": [ 22 | 0, 23 | { 24 | "Fn::GetAZs": "" 25 | } 26 | ] 27 | }, 28 | "CidrBlock": { 29 | "Fn::Select": [ 30 | 0, 31 | { 32 | "Fn::Cidr": [ 33 | { 34 | "Fn::GetAtt": [ 35 | "VPC", 36 | "CidrBlock" 37 | ] 38 | }, 39 | 6, 40 | "8" 41 | ] 42 | } 43 | ] 44 | }, 45 | "VpcId": { 46 | "Ref": "VPC" 47 | } 48 | } 49 | }, 50 | "Subnet2": { 51 | "Type": "AWS::EC2::Subnet", 52 | "Properties": { 53 | "AvailabilityZone": { 54 | "Fn::Select": [ 55 | 1, 56 | { 57 | "Fn::GetAZs": "" 58 | } 59 | ] 60 | }, 61 | "CidrBlock": { 62 | "Fn::Select": [ 63 | 1, 64 | { 65 | "Fn::Cidr": [ 66 | { 67 | "Fn::GetAtt": [ 68 | "VPC", 69 | "CidrBlock" 70 | ] 71 | }, 72 | 6, 73 | "8" 74 | ] 75 | } 76 | ] 77 | }, 78 | "VpcId": { 79 | "Ref": "VPC" 80 | } 81 | } 82 | }, 83 | "Subnet3": { 84 | "Type": "AWS::EC2::Subnet", 85 | "Properties": { 86 | "AvailabilityZone": { 87 | "Fn::Select": [ 88 | 2, 89 | { 90 | "Fn::GetAZs": "" 91 | } 92 | ] 93 | }, 94 | "CidrBlock": { 95 | "Fn::Select": [ 96 | 2, 97 | { 98 | "Fn::Cidr": [ 99 | { 100 | "Fn::GetAtt": [ 101 | "VPC", 102 | "CidrBlock" 103 | ] 104 | }, 105 | 6, 106 | "8" 107 | ] 108 | } 109 | ] 110 | }, 111 | "VpcId": { 112 | "Ref": "VPC" 113 | } 114 | } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /tests/end-to-end/vpc/java/src/main/java/com/myorg/MyApp.java: -------------------------------------------------------------------------------- 1 | //auto-generated 2 | package com.myorg; 3 | import software.amazon.awscdk.App; 4 | import software.amazon.awscdk.AppProps; 5 | import software.amazon.awscdk.DefaultStackSynthesizer; 6 | import software.amazon.awscdk.StackProps; 7 | public class MyApp { 8 | public static void main(final String[] args) { 9 | App app = new App(AppProps.builder() 10 | .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create() 11 | .generateBootstrapVersionRule(false) 12 | .build()) 13 | .build()); 14 | new VpcStack(app, "Stack", StackProps.builder() 15 | .build()); 16 | app.synth(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/java/src/main/java/com/myorg/Stack.java: -------------------------------------------------------------------------------- 1 | package com.myorg; 2 | 3 | import software.constructs.Construct; 4 | 5 | import java.util.*; 6 | import software.amazon.awscdk.CfnMapping; 7 | import software.amazon.awscdk.CfnTag; 8 | import software.amazon.awscdk.Stack; 9 | import software.amazon.awscdk.StackProps; 10 | 11 | import software.amazon.awscdk.*; 12 | import software.amazon.awscdk.services.ec2.*; 13 | 14 | class VpcStack extends Stack { 15 | public VpcStack(final Construct scope, final String id) { 16 | super(scope, id, null); 17 | } 18 | 19 | public VpcStack(final Construct scope, final String id, final StackProps props) { 20 | super(scope, id, props); 21 | 22 | CfnVPC vpc = CfnVPC.Builder.create(this, "VPC") 23 | .cidrBlock("10.42.0.0/16") 24 | .enableDnsSupport(true) 25 | .enableDnsHostnames(true) 26 | .tags(Arrays.asList( 27 | CfnTag.builder() 28 | .key("cost-center") 29 | .value("1337") 30 | .build())) 31 | .build(); 32 | 33 | CfnSubnet subnet1 = CfnSubnet.Builder.create(this, "Subnet1") 34 | .availabilityZone(Fn.select(0, Fn.getAzs(""))) 35 | .cidrBlock(Fn.select(0, Fn.cidr(vpc.getAttrCidrBlock(), 6, "8"))) 36 | .vpcId(vpc.getRef()) 37 | .build(); 38 | 39 | CfnSubnet subnet2 = CfnSubnet.Builder.create(this, "Subnet2") 40 | .availabilityZone(Fn.select(1, Fn.getAzs(""))) 41 | .cidrBlock(Fn.select(1, Fn.cidr(vpc.getAttrCidrBlock(), 6, "8"))) 42 | .vpcId(vpc.getRef()) 43 | .build(); 44 | 45 | CfnSubnet subnet3 = CfnSubnet.Builder.create(this, "Subnet3") 46 | .availabilityZone(Fn.select(2, Fn.getAzs(""))) 47 | .cidrBlock(Fn.select(2, Fn.cidr(vpc.getAttrCidrBlock(), 6, "8"))) 48 | .vpcId(vpc.getRef()) 49 | .build(); 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/python/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/vpc/template.json b/tests/end-to-end/vpc-python-working-dir/cdk.out/Stack.template.json 2 | index cddd267..b101d46 100644 3 | --- a/./tests/end-to-end/vpc/template.json 4 | +++ b/tests/end-to-end/vpc-python-working-dir/cdk.out/Stack.template.json 5 | @@ -4,8 +4,8 @@ 6 | "Type": "AWS::EC2::VPC", 7 | "Properties": { 8 | "CidrBlock": "10.42.0.0/16", 9 | - "EnableDnsSupport": true, 10 | "EnableDnsHostnames": true, 11 | + "EnableDnsSupport": true, 12 | "Tags": [ 13 | { 14 | "Key": "cost-center", 15 | @@ -31,10 +31,13 @@ 16 | { 17 | "Fn::Cidr": [ 18 | { 19 | - "Fn::GetAtt": "VPC.CidrBlock" 20 | + "Fn::GetAtt": [ 21 | + "VPC", 22 | + "CidrBlock" 23 | + ] 24 | }, 25 | 6, 26 | - 8 27 | + "8" 28 | ] 29 | } 30 | ] 31 | @@ -61,10 +64,13 @@ 32 | { 33 | "Fn::Cidr": [ 34 | { 35 | - "Fn::GetAtt": "VPC.CidrBlock" 36 | + "Fn::GetAtt": [ 37 | + "VPC", 38 | + "CidrBlock" 39 | + ] 40 | }, 41 | 6, 42 | - 8 43 | + "8" 44 | ] 45 | } 46 | ] 47 | @@ -91,10 +97,13 @@ 48 | { 49 | "Fn::Cidr": [ 50 | { 51 | - "Fn::GetAtt": "VPC.CidrBlock" 52 | + "Fn::GetAtt": [ 53 | + "VPC", 54 | + "CidrBlock" 55 | + ] 56 | }, 57 | 6, 58 | - 8 59 | + "8" 60 | ] 61 | } 62 | ] 63 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/python/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "VPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.42.0.0/16", 7 | "EnableDnsHostnames": true, 8 | "EnableDnsSupport": true, 9 | "Tags": [ 10 | { 11 | "Key": "cost-center", 12 | "Value": "1337" 13 | } 14 | ] 15 | } 16 | }, 17 | "Subnet1": { 18 | "Type": "AWS::EC2::Subnet", 19 | "Properties": { 20 | "AvailabilityZone": { 21 | "Fn::Select": [ 22 | 0, 23 | { 24 | "Fn::GetAZs": "" 25 | } 26 | ] 27 | }, 28 | "CidrBlock": { 29 | "Fn::Select": [ 30 | 0, 31 | { 32 | "Fn::Cidr": [ 33 | { 34 | "Fn::GetAtt": [ 35 | "VPC", 36 | "CidrBlock" 37 | ] 38 | }, 39 | 6, 40 | "8" 41 | ] 42 | } 43 | ] 44 | }, 45 | "VpcId": { 46 | "Ref": "VPC" 47 | } 48 | } 49 | }, 50 | "Subnet2": { 51 | "Type": "AWS::EC2::Subnet", 52 | "Properties": { 53 | "AvailabilityZone": { 54 | "Fn::Select": [ 55 | 1, 56 | { 57 | "Fn::GetAZs": "" 58 | } 59 | ] 60 | }, 61 | "CidrBlock": { 62 | "Fn::Select": [ 63 | 1, 64 | { 65 | "Fn::Cidr": [ 66 | { 67 | "Fn::GetAtt": [ 68 | "VPC", 69 | "CidrBlock" 70 | ] 71 | }, 72 | 6, 73 | "8" 74 | ] 75 | } 76 | ] 77 | }, 78 | "VpcId": { 79 | "Ref": "VPC" 80 | } 81 | } 82 | }, 83 | "Subnet3": { 84 | "Type": "AWS::EC2::Subnet", 85 | "Properties": { 86 | "AvailabilityZone": { 87 | "Fn::Select": [ 88 | 2, 89 | { 90 | "Fn::GetAZs": "" 91 | } 92 | ] 93 | }, 94 | "CidrBlock": { 95 | "Fn::Select": [ 96 | 2, 97 | { 98 | "Fn::Cidr": [ 99 | { 100 | "Fn::GetAtt": [ 101 | "VPC", 102 | "CidrBlock" 103 | ] 104 | }, 105 | 6, 106 | "8" 107 | ] 108 | } 109 | ] 110 | }, 111 | "VpcId": { 112 | "Ref": "VPC" 113 | } 114 | } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /tests/end-to-end/vpc/python/app.py: -------------------------------------------------------------------------------- 1 | # autogenerated 2 | import aws_cdk as cdk 3 | from stack import VpcStack 4 | app = cdk.App( 5 | default_stack_synthesizer=cdk.DefaultStackSynthesizer( 6 | generate_bootstrap_version_rule=False 7 | ) 8 | ) 9 | 10 | VpcStack(app, 'Stack') 11 | app.synth() 12 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/python/stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack 2 | import aws_cdk as cdk 3 | import aws_cdk.aws_ec2 as ec2 4 | from constructs import Construct 5 | 6 | class VpcStack(Stack): 7 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 8 | super().__init__(scope, construct_id, **kwargs) 9 | 10 | # Resources 11 | vpc = ec2.CfnVPC(self, 'VPC', 12 | cidr_block = '10.42.0.0/16', 13 | enable_dns_support = True, 14 | enable_dns_hostnames = True, 15 | tags = [ 16 | { 17 | 'key': 'cost-center', 18 | 'value': '1337', 19 | }, 20 | ], 21 | ) 22 | 23 | subnet1 = ec2.CfnSubnet(self, 'Subnet1', 24 | availability_zone = cdk.Fn.select(0, cdk.Fn.get_azs('')), 25 | cidr_block = cdk.Fn.select(0, cdk.Fn.cidr(vpc.attr_cidr_block, 6, str(8))), 26 | vpc_id = vpc.ref, 27 | ) 28 | 29 | subnet2 = ec2.CfnSubnet(self, 'Subnet2', 30 | availability_zone = cdk.Fn.select(1, cdk.Fn.get_azs('')), 31 | cidr_block = cdk.Fn.select(1, cdk.Fn.cidr(vpc.attr_cidr_block, 6, str(8))), 32 | vpc_id = vpc.ref, 33 | ) 34 | 35 | subnet3 = ec2.CfnSubnet(self, 'Subnet3', 36 | availability_zone = cdk.Fn.select(2, cdk.Fn.get_azs('')), 37 | cidr_block = cdk.Fn.select(2, cdk.Fn.cidr(vpc.attr_cidr_block, 6, str(8))), 38 | vpc_id = vpc.ref, 39 | ) 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/typescript/Stack.diff: -------------------------------------------------------------------------------- 1 | diff --git a/./tests/end-to-end/vpc/template.json b/tests/end-to-end/vpc-typescript-working-dir/cdk.out/Stack.template.json 2 | index cddd267..b101d46 100644 3 | --- a/./tests/end-to-end/vpc/template.json 4 | +++ b/tests/end-to-end/vpc-typescript-working-dir/cdk.out/Stack.template.json 5 | @@ -4,8 +4,8 @@ 6 | "Type": "AWS::EC2::VPC", 7 | "Properties": { 8 | "CidrBlock": "10.42.0.0/16", 9 | - "EnableDnsSupport": true, 10 | "EnableDnsHostnames": true, 11 | + "EnableDnsSupport": true, 12 | "Tags": [ 13 | { 14 | "Key": "cost-center", 15 | @@ -31,10 +31,13 @@ 16 | { 17 | "Fn::Cidr": [ 18 | { 19 | - "Fn::GetAtt": "VPC.CidrBlock" 20 | + "Fn::GetAtt": [ 21 | + "VPC", 22 | + "CidrBlock" 23 | + ] 24 | }, 25 | 6, 26 | - 8 27 | + "8" 28 | ] 29 | } 30 | ] 31 | @@ -61,10 +64,13 @@ 32 | { 33 | "Fn::Cidr": [ 34 | { 35 | - "Fn::GetAtt": "VPC.CidrBlock" 36 | + "Fn::GetAtt": [ 37 | + "VPC", 38 | + "CidrBlock" 39 | + ] 40 | }, 41 | 6, 42 | - 8 43 | + "8" 44 | ] 45 | } 46 | ] 47 | @@ -91,10 +97,13 @@ 48 | { 49 | "Fn::Cidr": [ 50 | { 51 | - "Fn::GetAtt": "VPC.CidrBlock" 52 | + "Fn::GetAtt": [ 53 | + "VPC", 54 | + "CidrBlock" 55 | + ] 56 | }, 57 | 6, 58 | - 8 59 | + "8" 60 | ] 61 | } 62 | ] 63 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/typescript/Stack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "VPC": { 4 | "Type": "AWS::EC2::VPC", 5 | "Properties": { 6 | "CidrBlock": "10.42.0.0/16", 7 | "EnableDnsHostnames": true, 8 | "EnableDnsSupport": true, 9 | "Tags": [ 10 | { 11 | "Key": "cost-center", 12 | "Value": "1337" 13 | } 14 | ] 15 | } 16 | }, 17 | "Subnet1": { 18 | "Type": "AWS::EC2::Subnet", 19 | "Properties": { 20 | "AvailabilityZone": { 21 | "Fn::Select": [ 22 | 0, 23 | { 24 | "Fn::GetAZs": "" 25 | } 26 | ] 27 | }, 28 | "CidrBlock": { 29 | "Fn::Select": [ 30 | 0, 31 | { 32 | "Fn::Cidr": [ 33 | { 34 | "Fn::GetAtt": [ 35 | "VPC", 36 | "CidrBlock" 37 | ] 38 | }, 39 | 6, 40 | "8" 41 | ] 42 | } 43 | ] 44 | }, 45 | "VpcId": { 46 | "Ref": "VPC" 47 | } 48 | } 49 | }, 50 | "Subnet2": { 51 | "Type": "AWS::EC2::Subnet", 52 | "Properties": { 53 | "AvailabilityZone": { 54 | "Fn::Select": [ 55 | 1, 56 | { 57 | "Fn::GetAZs": "" 58 | } 59 | ] 60 | }, 61 | "CidrBlock": { 62 | "Fn::Select": [ 63 | 1, 64 | { 65 | "Fn::Cidr": [ 66 | { 67 | "Fn::GetAtt": [ 68 | "VPC", 69 | "CidrBlock" 70 | ] 71 | }, 72 | 6, 73 | "8" 74 | ] 75 | } 76 | ] 77 | }, 78 | "VpcId": { 79 | "Ref": "VPC" 80 | } 81 | } 82 | }, 83 | "Subnet3": { 84 | "Type": "AWS::EC2::Subnet", 85 | "Properties": { 86 | "AvailabilityZone": { 87 | "Fn::Select": [ 88 | 2, 89 | { 90 | "Fn::GetAZs": "" 91 | } 92 | ] 93 | }, 94 | "CidrBlock": { 95 | "Fn::Select": [ 96 | 2, 97 | { 98 | "Fn::Cidr": [ 99 | { 100 | "Fn::GetAtt": [ 101 | "VPC", 102 | "CidrBlock" 103 | ] 104 | }, 105 | 6, 106 | "8" 107 | ] 108 | } 109 | ] 110 | }, 111 | "VpcId": { 112 | "Ref": "VPC" 113 | } 114 | } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /tests/end-to-end/vpc/typescript/app.ts: -------------------------------------------------------------------------------- 1 | // auto-generated! a human should update this! 2 | import * as cdk from "aws-cdk-lib"; 3 | import { VpcStack } from "./stack"; 4 | const app = new cdk.App({ 5 | defaultStackSynthesizer: new cdk.DefaultStackSynthesizer({ 6 | generateBootstrapVersionRule: false, 7 | }), 8 | }); 9 | new VpcStack(app, "Stack"); 10 | app.synth(); 11 | -------------------------------------------------------------------------------- /tests/end-to-end/vpc/typescript/stack.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as ec2 from 'aws-cdk-lib/aws-ec2'; 3 | 4 | export interface VpcStackProps extends cdk.StackProps { 5 | } 6 | 7 | export class VpcStack extends cdk.Stack { 8 | public constructor(scope: cdk.App, id: string, props: VpcStackProps = {}) { 9 | super(scope, id, props); 10 | 11 | // Resources 12 | const vpc = new ec2.CfnVPC(this, 'VPC', { 13 | cidrBlock: '10.42.0.0/16', 14 | enableDnsSupport: true, 15 | enableDnsHostnames: true, 16 | tags: [ 17 | { 18 | key: 'cost-center', 19 | value: '1337', 20 | }, 21 | ], 22 | }); 23 | 24 | const subnet1 = new ec2.CfnSubnet(this, 'Subnet1', { 25 | availabilityZone: cdk.Fn.select(0, cdk.Fn.getAzs('')), 26 | cidrBlock: cdk.Fn.select(0, cdk.Fn.cidr(vpc.attrCidrBlock, 6, String(8))), 27 | vpcId: vpc.ref, 28 | }); 29 | 30 | const subnet2 = new ec2.CfnSubnet(this, 'Subnet2', { 31 | availabilityZone: cdk.Fn.select(1, cdk.Fn.getAzs('')), 32 | cidrBlock: cdk.Fn.select(1, cdk.Fn.cidr(vpc.attrCidrBlock, 6, String(8))), 33 | vpcId: vpc.ref, 34 | }); 35 | 36 | const subnet3 = new ec2.CfnSubnet(this, 'Subnet3', { 37 | availabilityZone: cdk.Fn.select(2, cdk.Fn.getAzs('')), 38 | cidrBlock: cdk.Fn.select(2, cdk.Fn.cidr(vpc.attrCidrBlock, 6, String(8))), 39 | vpcId: vpc.ref, 40 | }); 41 | } 42 | } 43 | --------------------------------------------------------------------------------