├── .eslintrc.json ├── .gitattributes ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── pull_request_template.md └── workflows │ ├── auto-approve.yml │ ├── aws.yml │ ├── build.yml │ ├── pull-request-lint.yml │ └── upgrade.yml ├── .gitignore ├── .gitpod.yml ├── .mergify.yml ├── .npmignore ├── .projen ├── deps.json ├── files.json └── tasks.json ├── .projenrc.js ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cdk.json ├── images ├── 01.png ├── 02.png ├── 03.png ├── 04.png ├── 05.png ├── cross-accounts-01.png ├── sam-deploy.png └── sam-layer-deploy.png ├── package.json ├── src ├── custom-layer │ ├── Dockerfile │ ├── build.sh │ └── custom-layer.ts └── main.ts ├── test └── main.test.ts ├── tsconfig.dev.json ├── tsconfig.json └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "jest": true, 4 | "node": true 5 | }, 6 | "root": true, 7 | "plugins": [ 8 | "@typescript-eslint", 9 | "import" 10 | ], 11 | "parser": "@typescript-eslint/parser", 12 | "parserOptions": { 13 | "ecmaVersion": 2018, 14 | "sourceType": "module", 15 | "project": "./tsconfig.dev.json" 16 | }, 17 | "extends": [ 18 | "plugin:import/typescript" 19 | ], 20 | "settings": { 21 | "import/parsers": { 22 | "@typescript-eslint/parser": [ 23 | ".ts", 24 | ".tsx" 25 | ] 26 | }, 27 | "import/resolver": { 28 | "node": {}, 29 | "typescript": { 30 | "project": "./tsconfig.dev.json", 31 | "alwaysTryTypes": true 32 | } 33 | } 34 | }, 35 | "ignorePatterns": [ 36 | "*.js", 37 | "!.projenrc.js", 38 | "*.d.ts", 39 | "node_modules/", 40 | "*.generated.ts", 41 | "coverage" 42 | ], 43 | "rules": { 44 | "indent": [ 45 | "off" 46 | ], 47 | "@typescript-eslint/indent": [ 48 | "error", 49 | 2 50 | ], 51 | "quotes": [ 52 | "error", 53 | "single", 54 | { 55 | "avoidEscape": true 56 | } 57 | ], 58 | "comma-dangle": [ 59 | "error", 60 | "always-multiline" 61 | ], 62 | "comma-spacing": [ 63 | "error", 64 | { 65 | "before": false, 66 | "after": true 67 | } 68 | ], 69 | "no-multi-spaces": [ 70 | "error", 71 | { 72 | "ignoreEOLComments": false 73 | } 74 | ], 75 | "array-bracket-spacing": [ 76 | "error", 77 | "never" 78 | ], 79 | "array-bracket-newline": [ 80 | "error", 81 | "consistent" 82 | ], 83 | "object-curly-spacing": [ 84 | "error", 85 | "always" 86 | ], 87 | "object-curly-newline": [ 88 | "error", 89 | { 90 | "multiline": true, 91 | "consistent": true 92 | } 93 | ], 94 | "object-property-newline": [ 95 | "error", 96 | { 97 | "allowAllPropertiesOnSameLine": true 98 | } 99 | ], 100 | "keyword-spacing": [ 101 | "error" 102 | ], 103 | "brace-style": [ 104 | "error", 105 | "1tbs", 106 | { 107 | "allowSingleLine": true 108 | } 109 | ], 110 | "space-before-blocks": [ 111 | "error" 112 | ], 113 | "curly": [ 114 | "error", 115 | "multi-line", 116 | "consistent" 117 | ], 118 | "@typescript-eslint/member-delimiter-style": [ 119 | "error" 120 | ], 121 | "semi": [ 122 | "error", 123 | "always" 124 | ], 125 | "max-len": [ 126 | "error", 127 | { 128 | "code": 150, 129 | "ignoreUrls": true, 130 | "ignoreStrings": true, 131 | "ignoreTemplateLiterals": true, 132 | "ignoreComments": true, 133 | "ignoreRegExpLiterals": true 134 | } 135 | ], 136 | "quote-props": [ 137 | "error", 138 | "consistent-as-needed" 139 | ], 140 | "@typescript-eslint/no-require-imports": [ 141 | "error" 142 | ], 143 | "import/no-extraneous-dependencies": [ 144 | "error", 145 | { 146 | "devDependencies": [ 147 | "**/test/**", 148 | "**/build-tools/**" 149 | ], 150 | "optionalDependencies": false, 151 | "peerDependencies": true 152 | } 153 | ], 154 | "import/no-unresolved": [ 155 | "error" 156 | ], 157 | "import/order": [ 158 | "warn", 159 | { 160 | "groups": [ 161 | "builtin", 162 | "external" 163 | ], 164 | "alphabetize": { 165 | "order": "asc", 166 | "caseInsensitive": true 167 | } 168 | } 169 | ], 170 | "no-duplicate-imports": [ 171 | "error" 172 | ], 173 | "no-shadow": [ 174 | "off" 175 | ], 176 | "@typescript-eslint/no-shadow": [ 177 | "error" 178 | ], 179 | "key-spacing": [ 180 | "error" 181 | ], 182 | "no-multiple-empty-lines": [ 183 | "error" 184 | ], 185 | "@typescript-eslint/no-floating-promises": [ 186 | "error" 187 | ], 188 | "no-return-await": [ 189 | "off" 190 | ], 191 | "@typescript-eslint/return-await": [ 192 | "error" 193 | ], 194 | "no-trailing-spaces": [ 195 | "error" 196 | ], 197 | "dot-notation": [ 198 | "error" 199 | ], 200 | "no-bitwise": [ 201 | "error" 202 | ], 203 | "@typescript-eslint/member-ordering": [ 204 | "error", 205 | { 206 | "default": [ 207 | "public-static-field", 208 | "public-static-method", 209 | "protected-static-field", 210 | "protected-static-method", 211 | "private-static-field", 212 | "private-static-method", 213 | "field", 214 | "constructor", 215 | "method" 216 | ] 217 | } 218 | ] 219 | }, 220 | "overrides": [ 221 | { 222 | "files": [ 223 | ".projenrc.js" 224 | ], 225 | "rules": { 226 | "@typescript-eslint/no-require-imports": "off", 227 | "import/no-extraneous-dependencies": "off" 228 | } 229 | } 230 | ] 231 | } 232 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | *.snap linguist-generated 4 | /.eslintrc.json linguist-generated 5 | /.gitattributes linguist-generated 6 | /.github/pull_request_template.md linguist-generated 7 | /.github/workflows/auto-approve.yml linguist-generated 8 | /.github/workflows/build.yml linguist-generated 9 | /.github/workflows/pull-request-lint.yml linguist-generated 10 | /.github/workflows/upgrade.yml linguist-generated 11 | /.gitignore linguist-generated 12 | /.gitpod.yml linguist-generated 13 | /.mergify.yml linguist-generated 14 | /.npmignore linguist-generated 15 | /.projen/** linguist-generated 16 | /.projen/deps.json linguist-generated 17 | /.projen/files.json linguist-generated 18 | /.projen/tasks.json linguist-generated 19 | /cdk.json linguist-generated 20 | /LICENSE linguist-generated 21 | /package.json linguist-generated 22 | /tsconfig.dev.json linguist-generated 23 | /tsconfig.json linguist-generated 24 | /yarn.lock linguist-generated -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 7 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Fixes # -------------------------------------------------------------------------------- /.github/workflows/auto-approve.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | name: auto-approve 4 | on: 5 | pull_request_target: 6 | types: 7 | - labeled 8 | - opened 9 | - synchronize 10 | - reopened 11 | - ready_for_review 12 | jobs: 13 | approve: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | pull-requests: write 17 | if: contains(github.event.pull_request.labels.*.name, 'auto-approve') && (github.event.pull_request.user.login == 'pahud') 18 | steps: 19 | - uses: hmarr/auto-approve-action@v2.1.0 20 | with: 21 | github-token: ${{ secrets.GITHUB_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/workflows/aws.yml: -------------------------------------------------------------------------------- 1 | on: 2 | release: 3 | types: 4 | - published 5 | 6 | name: Trigger release deployment build in AWS regions 7 | 8 | jobs: 9 | trigger-job: 10 | name: Release Trigger 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Trigger build of SAR deployment on AWS CN regions 15 | id: trigger-aws-cn-build-of-codebuild 16 | env: 17 | RELEASE_TAG: ${{ github.ref }} 18 | BUILD_URL: ${{ secrets.AWS_CN_BUILD_URL }} 19 | run: | 20 | # Trigger starting build of CodeBuild to deploy the release to SAR 21 | curl -X PUT $BUILD_URL?version=$RELEASE_TAG 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | name: build 4 | on: 5 | pull_request: {} 6 | workflow_dispatch: {} 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: write 12 | outputs: 13 | self_mutation_happened: ${{ steps.self_mutation.outputs.self_mutation_happened }} 14 | env: 15 | CI: "true" 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v2 19 | with: 20 | ref: ${{ github.event.pull_request.head.ref }} 21 | repository: ${{ github.event.pull_request.head.repo.full_name }} 22 | - name: Install dependencies 23 | run: yarn install --check-files 24 | - name: build 25 | run: npx projen build 26 | - id: self_mutation 27 | name: Find mutations 28 | run: |- 29 | git add . 30 | git diff --staged --patch --exit-code > .repo.patch || echo "::set-output name=self_mutation_happened::true" 31 | - if: steps.self_mutation.outputs.self_mutation_happened 32 | name: Upload patch 33 | uses: actions/upload-artifact@v2 34 | with: 35 | name: .repo.patch 36 | path: .repo.patch 37 | - name: Fail build on mutation 38 | if: steps.self_mutation.outputs.self_mutation_happened 39 | run: |- 40 | echo "::error::Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch." 41 | cat .repo.patch 42 | exit 1 43 | self-mutation: 44 | needs: build 45 | runs-on: ubuntu-latest 46 | permissions: 47 | contents: write 48 | if: always() && needs.build.outputs.self_mutation_happened && !(github.event.pull_request.head.repo.full_name != github.repository) 49 | steps: 50 | - name: Checkout 51 | uses: actions/checkout@v2 52 | with: 53 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 54 | ref: ${{ github.event.pull_request.head.ref }} 55 | repository: ${{ github.event.pull_request.head.repo.full_name }} 56 | - name: Download patch 57 | uses: actions/download-artifact@v2 58 | with: 59 | name: .repo.patch 60 | path: ${{ runner.temp }} 61 | - name: Apply patch 62 | run: '[ -s ${{ runner.temp }}/.repo.patch ] && git apply ${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."' 63 | - name: Set git identity 64 | run: |- 65 | git config user.name "github-actions" 66 | git config user.email "github-actions@github.com" 67 | - name: Push changes 68 | run: |2- 69 | git add . 70 | git commit -s -m "chore: self mutation" 71 | git push origin HEAD:${{ github.event.pull_request.head.ref }} 72 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-lint.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | name: pull-request-lint 4 | on: 5 | pull_request_target: 6 | types: 7 | - labeled 8 | - opened 9 | - synchronize 10 | - reopened 11 | - ready_for_review 12 | - edited 13 | jobs: 14 | validate: 15 | name: Validate PR title 16 | runs-on: ubuntu-latest 17 | permissions: 18 | pull-requests: write 19 | steps: 20 | - uses: amannn/action-semantic-pull-request@v3.4.6 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | with: 24 | types: |- 25 | feat 26 | fix 27 | chore 28 | requireScope: false 29 | -------------------------------------------------------------------------------- /.github/workflows/upgrade.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | name: upgrade 4 | on: 5 | workflow_dispatch: {} 6 | schedule: 7 | - cron: 0 0 * * * 8 | jobs: 9 | upgrade: 10 | name: Upgrade 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | outputs: 15 | patch_created: ${{ steps.create_patch.outputs.patch_created }} 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v2 19 | - name: Install dependencies 20 | run: yarn install --check-files --frozen-lockfile 21 | - name: Upgrade dependencies 22 | run: npx projen upgrade 23 | - id: create_patch 24 | name: Find mutations 25 | run: |- 26 | git add . 27 | git diff --staged --patch --exit-code > .repo.patch || echo "::set-output name=patch_created::true" 28 | - if: steps.create_patch.outputs.patch_created 29 | name: Upload patch 30 | uses: actions/upload-artifact@v2 31 | with: 32 | name: .repo.patch 33 | path: .repo.patch 34 | pr: 35 | name: Create Pull Request 36 | needs: upgrade 37 | runs-on: ubuntu-latest 38 | permissions: 39 | contents: write 40 | pull-requests: write 41 | if: ${{ needs.upgrade.outputs.patch_created }} 42 | steps: 43 | - name: Checkout 44 | uses: actions/checkout@v2 45 | with: 46 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 47 | - name: Download patch 48 | uses: actions/download-artifact@v2 49 | with: 50 | name: .repo.patch 51 | path: ${{ runner.temp }} 52 | - name: Apply patch 53 | run: '[ -s ${{ runner.temp }}/.repo.patch ] && git apply ${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."' 54 | - name: Set git identity 55 | run: |- 56 | git config user.name "github-actions" 57 | git config user.email "github-actions@github.com" 58 | - name: Create Pull Request 59 | id: create-pr 60 | uses: peter-evans/create-pull-request@v3 61 | with: 62 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 63 | commit-message: |- 64 | chore(deps): upgrade dependencies 65 | 66 | Upgrades project dependencies. See details in [workflow run]. 67 | 68 | [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} 69 | 70 | ------ 71 | 72 | *Automatically created by projen via the "upgrade" workflow* 73 | branch: github-actions/upgrade 74 | title: "chore(deps): upgrade dependencies" 75 | labels: auto-approve,auto-merge 76 | body: |- 77 | Upgrades project dependencies. See details in [workflow run]. 78 | 79 | [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} 80 | 81 | ------ 82 | 83 | *Automatically created by projen via the "upgrade" workflow* 84 | author: github-actions 85 | committer: github-actions 86 | signoff: true 87 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | !/.gitattributes 3 | !/.projen/tasks.json 4 | !/.projen/deps.json 5 | !/.projen/files.json 6 | !/.github/workflows/pull-request-lint.yml 7 | !/.github/workflows/auto-approve.yml 8 | !/package.json 9 | !/LICENSE 10 | !/.npmignore 11 | logs 12 | *.log 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | lerna-debug.log* 17 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | lib-cov 23 | *.lcov 24 | .nyc_output 25 | build/Release 26 | node_modules/ 27 | jspm_packages/ 28 | *.tsbuildinfo 29 | .eslintcache 30 | *.tgz 31 | .yarn-integrity 32 | .cache 33 | !/.projenrc.js 34 | /test-reports/ 35 | junit.xml 36 | /coverage/ 37 | !/.github/workflows/build.yml 38 | !/.mergify.yml 39 | !/.github/workflows/upgrade.yml 40 | !/.github/pull_request_template.md 41 | !/test/ 42 | !/tsconfig.json 43 | !/tsconfig.dev.json 44 | !/src/ 45 | /lib 46 | /dist/ 47 | !/.eslintrc.json 48 | /assets/ 49 | !/cdk.json 50 | /cdk.out/ 51 | .cdk.staging/ 52 | .parcel-cache/ 53 | !/.gitpod.yml 54 | cdk.out 55 | cdk.context.json 56 | LICENSE 57 | images 58 | yarn-error.log 59 | packaged.yaml 60 | layer.zip 61 | coverage 62 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | image: public.ecr.aws/pahudnet/gitpod-workspace:latest 4 | tasks: 5 | - command: npx projen upgrade 6 | init: yarn gitpod:prebuild 7 | github: 8 | prebuilds: 9 | addCheck: true 10 | addBadge: true 11 | addLabel: true 12 | branches: true 13 | pullRequests: true 14 | pullRequestsFromForks: true 15 | vscode: 16 | extensions: 17 | - dbaeumer.vscode-eslint 18 | - ms-azuretools.vscode-docker 19 | - AmazonWebServices.aws-toolkit-vscode 20 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | queue_rules: 4 | - name: default 5 | conditions: 6 | - "#approved-reviews-by>=1" 7 | - -label~=(do-not-merge) 8 | - status-success=build 9 | pull_request_rules: 10 | - name: Automatic merge on approval and successful build 11 | actions: 12 | delete_head_branch: {} 13 | queue: 14 | method: squash 15 | name: default 16 | commit_message_template: |- 17 | {{ title }} (#{{ number }}) 18 | 19 | {{ body }} 20 | conditions: 21 | - "#approved-reviews-by>=1" 22 | - -label~=(do-not-merge) 23 | - status-success=build 24 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | /.projen/ 3 | /test-reports/ 4 | junit.xml 5 | /coverage/ 6 | /.mergify.yml 7 | /test/ 8 | /tsconfig.dev.json 9 | /src/ 10 | !/lib/ 11 | !/lib/**/*.js 12 | !/lib/**/*.d.ts 13 | dist 14 | /tsconfig.json 15 | /.github/ 16 | /.vscode/ 17 | /.idea/ 18 | /.projenrc.js 19 | tsconfig.tsbuildinfo 20 | /.eslintrc.json 21 | !/assets/ 22 | cdk.out/ 23 | .cdk.staging/ 24 | cdk.out 25 | cdk.context.json 26 | LICENSE 27 | images 28 | yarn-error.log 29 | packaged.yaml 30 | layer.zip 31 | coverage 32 | -------------------------------------------------------------------------------- /.projen/deps.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "name": "@types/jest", 5 | "type": "build" 6 | }, 7 | { 8 | "name": "@types/node", 9 | "version": "^12", 10 | "type": "build" 11 | }, 12 | { 13 | "name": "@typescript-eslint/eslint-plugin", 14 | "version": "^5", 15 | "type": "build" 16 | }, 17 | { 18 | "name": "@typescript-eslint/parser", 19 | "version": "^5", 20 | "type": "build" 21 | }, 22 | { 23 | "name": "aws-cdk", 24 | "version": "^1.95.2", 25 | "type": "build" 26 | }, 27 | { 28 | "name": "esbuild", 29 | "type": "build" 30 | }, 31 | { 32 | "name": "eslint-import-resolver-node", 33 | "type": "build" 34 | }, 35 | { 36 | "name": "eslint-import-resolver-typescript", 37 | "type": "build" 38 | }, 39 | { 40 | "name": "eslint-plugin-import", 41 | "type": "build" 42 | }, 43 | { 44 | "name": "eslint", 45 | "version": "^8", 46 | "type": "build" 47 | }, 48 | { 49 | "name": "jest", 50 | "type": "build" 51 | }, 52 | { 53 | "name": "jest-junit", 54 | "version": "^13", 55 | "type": "build" 56 | }, 57 | { 58 | "name": "json-schema", 59 | "type": "build" 60 | }, 61 | { 62 | "name": "npm-check-updates", 63 | "version": "^12", 64 | "type": "build" 65 | }, 66 | { 67 | "name": "projen", 68 | "type": "build" 69 | }, 70 | { 71 | "name": "ts-jest", 72 | "type": "build" 73 | }, 74 | { 75 | "name": "ts-node", 76 | "version": "^9", 77 | "type": "build" 78 | }, 79 | { 80 | "name": "typescript", 81 | "type": "build" 82 | }, 83 | { 84 | "name": "@aws-cdk/aws-lambda", 85 | "version": "^1.95.2", 86 | "type": "runtime" 87 | }, 88 | { 89 | "name": "@aws-cdk/core", 90 | "version": "^1.95.2", 91 | "type": "runtime" 92 | }, 93 | { 94 | "name": "@aws-cdk/lambda-layer-kubectl", 95 | "version": "^1.95.2", 96 | "type": "runtime" 97 | }, 98 | { 99 | "name": "constructs", 100 | "version": "^3.2.27", 101 | "type": "runtime" 102 | }, 103 | { 104 | "name": "@aws-cdk/assert", 105 | "version": "^1.95.2", 106 | "type": "test" 107 | } 108 | ], 109 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 110 | } 111 | -------------------------------------------------------------------------------- /.projen/files.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | ".eslintrc.json", 4 | ".gitattributes", 5 | ".github/pull_request_template.md", 6 | ".github/workflows/auto-approve.yml", 7 | ".github/workflows/build.yml", 8 | ".github/workflows/pull-request-lint.yml", 9 | ".github/workflows/upgrade.yml", 10 | ".gitignore", 11 | ".gitpod.yml", 12 | ".mergify.yml", 13 | ".npmignore", 14 | ".projen/deps.json", 15 | ".projen/files.json", 16 | ".projen/tasks.json", 17 | "cdk.json", 18 | "LICENSE", 19 | "tsconfig.dev.json", 20 | "tsconfig.json" 21 | ], 22 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 23 | } 24 | -------------------------------------------------------------------------------- /.projen/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasks": { 3 | "build": { 4 | "name": "build", 5 | "description": "Full release build", 6 | "steps": [ 7 | { 8 | "spawn": "default" 9 | }, 10 | { 11 | "spawn": "pre-compile" 12 | }, 13 | { 14 | "spawn": "compile" 15 | }, 16 | { 17 | "spawn": "post-compile" 18 | }, 19 | { 20 | "spawn": "test" 21 | }, 22 | { 23 | "spawn": "package" 24 | } 25 | ] 26 | }, 27 | "bundle": { 28 | "name": "bundle", 29 | "description": "Prepare assets" 30 | }, 31 | "clobber": { 32 | "name": "clobber", 33 | "description": "hard resets to HEAD of origin and cleans the local repo", 34 | "env": { 35 | "BRANCH": "$(git branch --show-current)" 36 | }, 37 | "steps": [ 38 | { 39 | "exec": "git checkout -b scratch", 40 | "name": "save current HEAD in \"scratch\" branch" 41 | }, 42 | { 43 | "exec": "git checkout $BRANCH" 44 | }, 45 | { 46 | "exec": "git fetch origin", 47 | "name": "fetch latest changes from origin" 48 | }, 49 | { 50 | "exec": "git reset --hard origin/$BRANCH", 51 | "name": "hard reset to origin commit" 52 | }, 53 | { 54 | "exec": "git clean -fdx", 55 | "name": "clean all untracked files" 56 | }, 57 | { 58 | "say": "ready to rock! (unpushed commits are under the \"scratch\" branch)" 59 | } 60 | ], 61 | "condition": "git diff --exit-code > /dev/null" 62 | }, 63 | "compile": { 64 | "name": "compile", 65 | "description": "Only compile" 66 | }, 67 | "default": { 68 | "name": "default", 69 | "description": "Synthesize project files", 70 | "steps": [ 71 | { 72 | "exec": "node .projenrc.js" 73 | } 74 | ] 75 | }, 76 | "deploy": { 77 | "name": "deploy", 78 | "description": "Deploys your CDK app to the AWS cloud", 79 | "steps": [ 80 | { 81 | "exec": "cdk deploy" 82 | } 83 | ] 84 | }, 85 | "destroy": { 86 | "name": "destroy", 87 | "description": "Destroys your cdk app in the AWS cloud", 88 | "steps": [ 89 | { 90 | "exec": "cdk destroy" 91 | } 92 | ] 93 | }, 94 | "diff": { 95 | "name": "diff", 96 | "description": "Diffs the currently deployed app against your code", 97 | "steps": [ 98 | { 99 | "exec": "cdk diff" 100 | } 101 | ] 102 | }, 103 | "eject": { 104 | "name": "eject", 105 | "description": "Remove projen from the project", 106 | "env": { 107 | "PROJEN_EJECTING": "true" 108 | }, 109 | "steps": [ 110 | { 111 | "spawn": "default" 112 | } 113 | ] 114 | }, 115 | "eslint": { 116 | "name": "eslint", 117 | "description": "Runs eslint against the codebase", 118 | "steps": [ 119 | { 120 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools .projenrc.js" 121 | } 122 | ] 123 | }, 124 | "gitpod:prebuild": { 125 | "name": "gitpod:prebuild", 126 | "description": "Prebuild setup for Gitpod", 127 | "steps": [ 128 | { 129 | "exec": "yarn install --frozen-lockfile --check-files" 130 | }, 131 | { 132 | "exec": "npx projen compile" 133 | } 134 | ] 135 | }, 136 | "package": { 137 | "name": "package", 138 | "description": "Creates the distribution package" 139 | }, 140 | "post-compile": { 141 | "name": "post-compile", 142 | "description": "Runs after successful compilation", 143 | "steps": [ 144 | { 145 | "spawn": "synth:silent" 146 | } 147 | ] 148 | }, 149 | "post-upgrade": { 150 | "name": "post-upgrade", 151 | "description": "Runs after upgrading dependencies" 152 | }, 153 | "pre-compile": { 154 | "name": "pre-compile", 155 | "description": "Prepare the project for compilation" 156 | }, 157 | "synth": { 158 | "name": "synth", 159 | "description": "Synthesizes your cdk app into cdk.out", 160 | "steps": [ 161 | { 162 | "exec": "cdk synth" 163 | } 164 | ] 165 | }, 166 | "synth:silent": { 167 | "name": "synth:silent", 168 | "description": "Synthesizes your cdk app into cdk.out and suppresses the template in stdout (part of \"yarn build\")", 169 | "steps": [ 170 | { 171 | "exec": "cdk synth > /dev/null" 172 | } 173 | ] 174 | }, 175 | "test": { 176 | "name": "test", 177 | "description": "Run tests", 178 | "steps": [ 179 | { 180 | "exec": "jest --passWithNoTests --all --updateSnapshot" 181 | }, 182 | { 183 | "spawn": "eslint" 184 | } 185 | ] 186 | }, 187 | "test:update": { 188 | "name": "test:update", 189 | "description": "Update jest snapshots", 190 | "steps": [ 191 | { 192 | "exec": "jest --updateSnapshot" 193 | } 194 | ] 195 | }, 196 | "test:watch": { 197 | "name": "test:watch", 198 | "description": "Run jest in watch mode", 199 | "steps": [ 200 | { 201 | "exec": "jest --watch" 202 | } 203 | ] 204 | }, 205 | "upgrade": { 206 | "name": "upgrade", 207 | "description": "upgrade dependencies", 208 | "env": { 209 | "CI": "0" 210 | }, 211 | "steps": [ 212 | { 213 | "exec": "yarn upgrade npm-check-updates" 214 | }, 215 | { 216 | "exec": "npm-check-updates --dep dev --upgrade --target=minor" 217 | }, 218 | { 219 | "exec": "npm-check-updates --dep optional --upgrade --target=minor" 220 | }, 221 | { 222 | "exec": "npm-check-updates --dep peer --upgrade --target=minor" 223 | }, 224 | { 225 | "exec": "npm-check-updates --dep prod --upgrade --target=minor" 226 | }, 227 | { 228 | "exec": "npm-check-updates --dep bundle --upgrade --target=minor" 229 | }, 230 | { 231 | "exec": "yarn install --check-files" 232 | }, 233 | { 234 | "exec": "yarn upgrade" 235 | }, 236 | { 237 | "exec": "npx projen" 238 | }, 239 | { 240 | "spawn": "post-upgrade" 241 | } 242 | ] 243 | }, 244 | "watch": { 245 | "name": "watch", 246 | "description": "Watches changes in your source code and rebuilds and deploys to the current account", 247 | "steps": [ 248 | { 249 | "exec": "cdk deploy --hotswap" 250 | }, 251 | { 252 | "exec": "cdk watch" 253 | } 254 | ] 255 | } 256 | }, 257 | "env": { 258 | "PATH": "$(npx -c \"node -e \\\"console.log(process.env.PATH)\\\"\")" 259 | }, 260 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 261 | } 262 | -------------------------------------------------------------------------------- /.projenrc.js: -------------------------------------------------------------------------------- 1 | const { awscdk, DevEnvironmentDockerImage, Gitpod } = require('projen'); 2 | 3 | const AUTOMATION_TOKEN = 'PROJEN_GITHUB_TOKEN'; 4 | 5 | const project = new awscdk.AwsCdkTypeScriptApp({ 6 | cdkVersion: '1.95.2', 7 | defaultReleaseBranch: 'main', 8 | name: 'aws-lambda-layer-kubectl', 9 | cdkDependencies: [ 10 | '@aws-cdk/lambda-layer-kubectl', 11 | '@aws-cdk/aws-lambda', 12 | ], 13 | depsUpgradeOptions: { 14 | ignoreProjen: false, 15 | workflowOptions: { 16 | labels: ['auto-approve', 'auto-merge'], 17 | secret: AUTOMATION_TOKEN, 18 | }, 19 | }, 20 | autoApproveOptions: { 21 | secret: 'GITHUB_TOKEN', 22 | allowedUsernames: ['pahud'], 23 | }, 24 | }); 25 | 26 | const common_exclude = [ 27 | 'cdk.out', 28 | 'cdk.context.json', 29 | 'LICENSE', 30 | 'images', 31 | 'yarn-error.log', 32 | 'packaged.yaml', 33 | 'layer.zip', 34 | 'coverage', 35 | ]; 36 | 37 | project.package.addField('resolutions', { 38 | 'pac-resolver': '^5.0.0', 39 | 'set-value': '^4.0.1', 40 | 'ansi-regex': '^5.0.1', 41 | }); 42 | 43 | 44 | const gitpodPrebuild = project.addTask('gitpod:prebuild', { 45 | description: 'Prebuild setup for Gitpod', 46 | }); 47 | // install and compile only, do not test or package. 48 | gitpodPrebuild.exec('yarn install --frozen-lockfile --check-files'); 49 | gitpodPrebuild.exec('npx projen compile'); 50 | 51 | let gitpod = new Gitpod(project, { 52 | dockerImage: DevEnvironmentDockerImage.fromImage('public.ecr.aws/pahudnet/gitpod-workspace:latest'), 53 | prebuilds: { 54 | addCheck: true, 55 | addBadge: true, 56 | addLabel: true, 57 | branches: true, 58 | pullRequests: true, 59 | pullRequestsFromForks: true, 60 | }, 61 | }); 62 | 63 | gitpod.addCustomTask({ 64 | init: 'yarn gitpod:prebuild', 65 | // always upgrade after init 66 | command: 'npx projen upgrade', 67 | }); 68 | 69 | gitpod.addVscodeExtensions( 70 | 'dbaeumer.vscode-eslint', 71 | 'ms-azuretools.vscode-docker', 72 | 'AmazonWebServices.aws-toolkit-vscode', 73 | ); 74 | 75 | 76 | project.npmignore.exclude(...common_exclude); 77 | project.gitignore.exclude(...common_exclude); 78 | 79 | project.synth(); 80 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: minimal 3 | 4 | 5 | services: 6 | - docker 7 | 8 | script: 9 | - make build 10 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check [existing open](https://github.com/aws-samples/aws-lambda-layer-kubectl/issues), or [recently closed](https://github.com/aws-samples/aws-lambda-layer-kubectl/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws-samples/aws-lambda-layer-kubectl/labels/help%20wanted) issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](https://github.com/aws-samples/aws-lambda-layer-kubectl/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![build](https://github.com/aws-samples/aws-lambda-layer-kubectl/actions/workflows/build.yml/badge.svg)](https://github.com/aws-samples/aws-lambda-layer-kubectl/actions/workflows/build.yml) 2 | 3 | 4 | 5 | # lambda-layer-kubectl 6 | 7 | AWS CDK(Cloud Development Kit) comes with [lambda-layer-kubectl](https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/lambda-layer-kubectl) which allows you to build your private AWS Lambda layer with **kubectl** executable. Ths repository demonstrates how to create your own AWS Lambda layer with kubectl in AWS CDK. 8 | 9 | 10 | ## Basic Usage 11 | 12 | ```ts 13 | import { App, CfnOutput, Construct, Stack, StackProps } from '@aws-cdk/core'; 14 | import * as layer from '@aws-cdk/lambda-layer-kubectl'; 15 | 16 | export class MyStack extends Stack { 17 | constructor(scope: Construct, id: string, props: StackProps = {}) { 18 | super(scope, id, props); 19 | 20 | const kubectlLayer = new layer.KubectlLayer(this, 'KubectlLayer'); 21 | new CfnOutput(this, 'LayerVersionArn', { value: kubectlLayer.layerVersionArn }) 22 | 23 | } 24 | } 25 | 26 | const devEnv = { 27 | account: process.env.CDK_DEFAULT_ACCOUNT, 28 | region: process.env.CDK_DEFAULT_REGION, 29 | }; 30 | 31 | const app = new App(); 32 | 33 | new MyStack(app, 'kubectl-layer-stack', { env: devEnv }); 34 | 35 | app.synth(); 36 | ``` 37 | 38 | After deployment, the AWS Lambda layer version ARN will be returned and you can use this ARN in your Lambda functions in the same AWS region. 39 | 40 | ``` 41 | Outputs: 42 | kubectl-layer-stack.LayerVersionArn = arn:aws:lambda:us-east-1:123456789012:layer:KubectlLayer600207B5:1 43 | ``` 44 | 45 | ## Customize your layer 46 | 47 | The [kubectlLayer](https://github.com/aws/aws-cdk/blob/6e2a3e0f855221df98f78f6465586d5524f5c7d5/packages/%40aws-cdk/lambda-layer-kubectl/lib/kubectl-layer.ts#L10-L20) from AWS CDK upstream does not allow you to pass custom Dockerfile(see the [build-in Dockerfile](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/lambda-layer-kubectl/layer/Dockerfile)). To customize the layer, we simply create our own `KubectlLayer` construct class in our CDK application with our custom `Dockerfile`. 48 | 49 | ```sh 50 | cd src/custom-layer 51 | # edit and customize the Dockerfile under the `custom-layer` directory 52 | # generate the layer.zip from Dockerfile 53 | bash build.sh 54 | ``` 55 | 56 | Now prepare your custom `KubectlLayer` construct class and run `cdk deploy` to generate your own layer. 57 | 58 | 59 | ```ts 60 | import { App, CfnOutput, Construct, Stack, StackProps } from '@aws-cdk/core'; 61 | import * as customlayer from './custom-layer/custom-layer' 62 | 63 | export class CustomLayderStack extends Stack { 64 | constructor(scope: Construct, id: string, props: StackProps = {}) { 65 | super(scope, id, props); 66 | 67 | const kubectlLayer = new customlayer.KubectlLayer(this, 'CustomKubectlLayer'); 68 | new CfnOutput(this, 'LayerVersionArn', { value: kubectlLayer.layerVersionArn }) 69 | 70 | } 71 | } 72 | 73 | const devEnv = { 74 | account: process.env.CDK_DEFAULT_ACCOUNT, 75 | region: process.env.CDK_DEFAULT_REGION, 76 | }; 77 | 78 | const app = new App(); 79 | 80 | new CustomLayderStack(app, 'custom-kubectl-layer-stack', { env: devEnv }); 81 | 82 | app.synth(); 83 | ``` 84 | 85 | 86 | ## License Summary 87 | 88 | This sample code is made available under the MIT-0 license. See the LICENSE file. 89 | -------------------------------------------------------------------------------- /cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node -P tsconfig.json --prefer-ts-exts src/main.ts", 3 | "context": { 4 | "aws-cdk:enableDiffNoFail": true, 5 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 6 | "@aws-cdk/core:enableStackNameDuplicates": true, 7 | "@aws-cdk/core:stackRelativeExports": true, 8 | "@aws-cdk/aws-ecr-assets:dockerIgnoreSupport": true, 9 | "@aws-cdk/aws-secretsmanager:parseOwnedSecretName": true, 10 | "@aws-cdk/aws-kms:defaultKeyPolicies": true, 11 | "@aws-cdk/aws-s3:grantWriteWithoutAcl": true, 12 | "@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount": true, 13 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 14 | "@aws-cdk/aws-efs:defaultEncryptionAtRest": true, 15 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 16 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true 17 | }, 18 | "output": "cdk.out", 19 | "build": "npx projen bundle", 20 | "watch": { 21 | "include": [ 22 | "src/**/*.ts", 23 | "test/**/*.ts" 24 | ], 25 | "exclude": [ 26 | "README.md", 27 | "cdk*.json", 28 | "**/*.d.ts", 29 | "**/*.js", 30 | "tsconfig.json", 31 | "package*.json", 32 | "yarn.lock", 33 | "node_modules" 34 | ] 35 | }, 36 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 37 | } 38 | -------------------------------------------------------------------------------- /images/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-lambda-layer-kubectl/27cfed24633a84cf77978cdeaaa230bd4f3add46/images/01.png -------------------------------------------------------------------------------- /images/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-lambda-layer-kubectl/27cfed24633a84cf77978cdeaaa230bd4f3add46/images/02.png -------------------------------------------------------------------------------- /images/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-lambda-layer-kubectl/27cfed24633a84cf77978cdeaaa230bd4f3add46/images/03.png -------------------------------------------------------------------------------- /images/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-lambda-layer-kubectl/27cfed24633a84cf77978cdeaaa230bd4f3add46/images/04.png -------------------------------------------------------------------------------- /images/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-lambda-layer-kubectl/27cfed24633a84cf77978cdeaaa230bd4f3add46/images/05.png -------------------------------------------------------------------------------- /images/cross-accounts-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-lambda-layer-kubectl/27cfed24633a84cf77978cdeaaa230bd4f3add46/images/cross-accounts-01.png -------------------------------------------------------------------------------- /images/sam-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-lambda-layer-kubectl/27cfed24633a84cf77978cdeaaa230bd4f3add46/images/sam-deploy.png -------------------------------------------------------------------------------- /images/sam-layer-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-lambda-layer-kubectl/27cfed24633a84cf77978cdeaaa230bd4f3add46/images/sam-layer-deploy.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aws-lambda-layer-kubectl", 3 | "scripts": { 4 | "build": "npx projen build", 5 | "bundle": "npx projen bundle", 6 | "clobber": "npx projen clobber", 7 | "compile": "npx projen compile", 8 | "default": "npx projen default", 9 | "deploy": "npx projen deploy", 10 | "destroy": "npx projen destroy", 11 | "diff": "npx projen diff", 12 | "eject": "npx projen eject", 13 | "eslint": "npx projen eslint", 14 | "gitpod:prebuild": "npx projen gitpod:prebuild", 15 | "package": "npx projen package", 16 | "post-compile": "npx projen post-compile", 17 | "post-upgrade": "npx projen post-upgrade", 18 | "pre-compile": "npx projen pre-compile", 19 | "synth": "npx projen synth", 20 | "synth:silent": "npx projen synth:silent", 21 | "test": "npx projen test", 22 | "test:update": "npx projen test:update", 23 | "test:watch": "npx projen test:watch", 24 | "upgrade": "npx projen upgrade", 25 | "watch": "npx projen watch", 26 | "projen": "npx projen" 27 | }, 28 | "devDependencies": { 29 | "@aws-cdk/assert": "^1.95.2", 30 | "@types/jest": "^27.4.1", 31 | "@types/node": "^12", 32 | "@typescript-eslint/eslint-plugin": "^5", 33 | "@typescript-eslint/parser": "^5", 34 | "aws-cdk": "^1.95.2", 35 | "esbuild": "^0.14.31", 36 | "eslint": "^8", 37 | "eslint-import-resolver-node": "^0.3.6", 38 | "eslint-import-resolver-typescript": "^2.7.1", 39 | "eslint-plugin-import": "^2.26.0", 40 | "jest": "^27.5.1", 41 | "jest-junit": "^13", 42 | "json-schema": "^0.4.0", 43 | "npm-check-updates": "^12", 44 | "projen": "^0.54.7", 45 | "ts-jest": "^27.1.4", 46 | "ts-node": "^9", 47 | "typescript": "^4.6.3" 48 | }, 49 | "dependencies": { 50 | "@aws-cdk/aws-lambda": "^1.95.2", 51 | "@aws-cdk/core": "^1.95.2", 52 | "@aws-cdk/lambda-layer-kubectl": "^1.95.2", 53 | "constructs": "^3.2.27" 54 | }, 55 | "license": "Apache-2.0", 56 | "version": "0.0.0", 57 | "jest": { 58 | "testMatch": [ 59 | "/src/**/__tests__/**/*.ts?(x)", 60 | "/(test|src)/**/?(*.)+(spec|test).ts?(x)" 61 | ], 62 | "clearMocks": true, 63 | "collectCoverage": true, 64 | "coverageReporters": [ 65 | "json", 66 | "lcov", 67 | "clover", 68 | "cobertura", 69 | "text" 70 | ], 71 | "coverageDirectory": "coverage", 72 | "coveragePathIgnorePatterns": [ 73 | "/node_modules/" 74 | ], 75 | "testPathIgnorePatterns": [ 76 | "/node_modules/" 77 | ], 78 | "watchPathIgnorePatterns": [ 79 | "/node_modules/" 80 | ], 81 | "reporters": [ 82 | "default", 83 | [ 84 | "jest-junit", 85 | { 86 | "outputDirectory": "test-reports" 87 | } 88 | ] 89 | ], 90 | "preset": "ts-jest", 91 | "globals": { 92 | "ts-jest": { 93 | "tsconfig": "tsconfig.dev.json" 94 | } 95 | } 96 | }, 97 | "resolutions": { 98 | "pac-resolver": "^5.0.0", 99 | "set-value": "^4.0.1", 100 | "ansi-regex": "^5.0.1" 101 | }, 102 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 103 | } -------------------------------------------------------------------------------- /src/custom-layer/Dockerfile: -------------------------------------------------------------------------------- 1 | # base lambda image 2 | FROM public.ecr.aws/lambda/provided:latest 3 | 4 | # 5 | # versions 6 | # 7 | 8 | # KUBECTL_VERSION should not be changed at the moment, see https://github.com/aws/aws-cdk/issues/15736 9 | # Version 1.21.0 is not compatible with version 1.20 (and lower) of the server. 10 | ARG KUBECTL_VERSION=1.20.0 11 | ARG HELM_VERSION=3.5.4 12 | 13 | USER root 14 | RUN mkdir -p /opt 15 | WORKDIR /tmp 16 | 17 | # 18 | # tools 19 | # 20 | 21 | RUN yum update -y \ 22 | && yum install -y zip unzip wget tar gzip 23 | 24 | # 25 | # kubectl 26 | # 27 | 28 | RUN mkdir -p /opt/kubectl 29 | RUN cd /opt/kubectl && curl -LO "https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl" 30 | RUN chmod +x /opt/kubectl/kubectl 31 | 32 | # 33 | # helm 34 | # 35 | 36 | RUN mkdir -p /tmp/helm && wget -qO- https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz | tar -xvz -C /tmp/helm 37 | RUN mkdir -p /opt/helm && cp /tmp/helm/linux-amd64/helm /opt/helm/helm 38 | 39 | # 40 | # create the bundle 41 | # 42 | 43 | RUN cd /opt \ 44 | && zip --symlinks -r ../layer.zip * \ 45 | && echo "/layer.zip is ready" \ 46 | && ls -alh /layer.zip; 47 | 48 | WORKDIR / 49 | -------------------------------------------------------------------------------- /src/custom-layer/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | cd $(dirname $0) 5 | 6 | echo ">> Building AWS Lambda layer inside a docker image..." 7 | 8 | TAG='aws-lambda-layer' 9 | 10 | docker build -t ${TAG} . 11 | 12 | echo ">> Extrating layer.zip from the build container..." 13 | CONTAINER=$(docker run -d ${TAG} false) 14 | docker cp ${CONTAINER}:/layer.zip layer.zip 15 | 16 | echo ">> Stopping container..." 17 | docker rm -f ${CONTAINER} 18 | echo ">> layer.zip is ready" 19 | -------------------------------------------------------------------------------- /src/custom-layer/custom-layer.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto'; 2 | import * as fs from 'fs'; 3 | import * as path from 'path'; 4 | import * as lambda from '@aws-cdk/aws-lambda'; 5 | import { Construct } from '@aws-cdk/core'; 6 | 7 | /** 8 | * An AWS Lambda layer that includes `kubectl` and `helm`. 9 | */ 10 | export class KubectlLayer extends lambda.LayerVersion { 11 | constructor(scope: Construct, id: string) { 12 | super(scope, id, { 13 | code: lambda.Code.fromAsset(path.join(__dirname, 'layer.zip'), { 14 | // we hash the Dockerfile (it contains the tools versions) because hashing the zip is non-deterministic 15 | assetHash: hashFile(path.join(__dirname, 'Dockerfile')), 16 | }), 17 | description: 'custom layer with /opt/kubectl/kubectl and /opt/helm/helm', 18 | }); 19 | } 20 | } 21 | 22 | function hashFile(fileName: string) { 23 | return crypto 24 | .createHash('sha256') 25 | .update(fs.readFileSync(fileName)) 26 | .digest('hex'); 27 | } 28 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { App, CfnOutput, Construct, Stack, StackProps } from '@aws-cdk/core'; 2 | import * as layer from '@aws-cdk/lambda-layer-kubectl'; 3 | import * as customlayer from './custom-layer/custom-layer'; 4 | 5 | export class LayerStack extends Stack { 6 | constructor(scope: Construct, id: string, props: StackProps = {}) { 7 | super(scope, id, props); 8 | 9 | const kubectlLayer = new layer.KubectlLayer(this, 'KubectlLayer'); 10 | new CfnOutput(this, 'LayerVersionArn', { value: kubectlLayer.layerVersionArn }); 11 | 12 | } 13 | } 14 | 15 | export class CustomLayerStack extends Stack { 16 | constructor(scope: Construct, id: string, props: StackProps = {}) { 17 | super(scope, id, props); 18 | 19 | const kubectlLayer = new customlayer.KubectlLayer(this, 'CustomKubectlLayer'); 20 | new CfnOutput(this, 'LayerVersionArn', { value: kubectlLayer.layerVersionArn }); 21 | 22 | } 23 | } 24 | 25 | // for development, use account/region from cdk cli 26 | const devEnv = { 27 | account: process.env.CDK_DEFAULT_ACCOUNT, 28 | region: process.env.CDK_DEFAULT_REGION, 29 | }; 30 | 31 | const app = new App(); 32 | 33 | new LayerStack(app, 'kubectl-layer-stack', { env: devEnv }); 34 | // new CustomLayerStack(app, 'custom-kubectl-layer-stack', { env: devEnv }); 35 | 36 | app.synth(); 37 | -------------------------------------------------------------------------------- /test/main.test.ts: -------------------------------------------------------------------------------- 1 | import '@aws-cdk/assert/jest'; 2 | import { App } from '@aws-cdk/core'; 3 | import { LayerStack } from '../src/main'; 4 | 5 | test('Layer with basic configuration', () => { 6 | const app = new App(); 7 | const stack = new LayerStack(app, 'test'); 8 | 9 | expect(stack).toHaveResource('AWS::Lambda::LayerVersion'); 10 | }); 11 | -------------------------------------------------------------------------------- /tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "alwaysStrict": true, 4 | "declaration": true, 5 | "esModuleInterop": true, 6 | "experimentalDecorators": true, 7 | "inlineSourceMap": true, 8 | "inlineSources": true, 9 | "lib": [ 10 | "es2019" 11 | ], 12 | "module": "CommonJS", 13 | "noEmitOnError": false, 14 | "noFallthroughCasesInSwitch": true, 15 | "noImplicitAny": true, 16 | "noImplicitReturns": true, 17 | "noImplicitThis": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "resolveJsonModule": true, 21 | "strict": true, 22 | "strictNullChecks": true, 23 | "strictPropertyInitialization": true, 24 | "stripInternal": true, 25 | "target": "ES2019" 26 | }, 27 | "include": [ 28 | ".projenrc.js", 29 | "src/**/*.ts", 30 | "test/**/*.ts" 31 | ], 32 | "exclude": [ 33 | "node_modules" 34 | ], 35 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 36 | } 37 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "outDir": "lib", 5 | "alwaysStrict": true, 6 | "declaration": true, 7 | "esModuleInterop": true, 8 | "experimentalDecorators": true, 9 | "inlineSourceMap": true, 10 | "inlineSources": true, 11 | "lib": [ 12 | "es2019" 13 | ], 14 | "module": "CommonJS", 15 | "noEmitOnError": false, 16 | "noFallthroughCasesInSwitch": true, 17 | "noImplicitAny": true, 18 | "noImplicitReturns": true, 19 | "noImplicitThis": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "resolveJsonModule": true, 23 | "strict": true, 24 | "strictNullChecks": true, 25 | "strictPropertyInitialization": true, 26 | "stripInternal": true, 27 | "target": "ES2019" 28 | }, 29 | "include": [ 30 | "src/**/*.ts" 31 | ], 32 | "exclude": [ 33 | "cdk.out" 34 | ], 35 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 36 | } 37 | --------------------------------------------------------------------------------