├── .devcontainer ├── devcontainer.json └── postCreateCommand.sh ├── .eslintignore ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── ci.yaml │ ├── docbuild.yml │ ├── e2e.yaml │ ├── linkcheck.json │ ├── markdown-link-check.yaml │ └── stale_issue_pr.yaml ├── .gitignore ├── .nvmrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── aws-quickstart-eks-blueprints-1.13.1.tgz ├── bin ├── asg.ts ├── backstage.ts ├── batch.ts ├── bottlerocket.ts ├── crossplane-argocd-gitops.ts ├── custom-networking-ipv4.ts ├── data-at-rest-encryption.ts ├── datadog.ts ├── dynatrace-operator.ts ├── ecr-image-scanning.ts ├── eks-config-rules.ts ├── emr.ts ├── fargate.ts ├── generative-ai-showcase.ts ├── generic-cluster-provider.ts ├── gmaestro.ts ├── gpu.ts ├── graviton.ts ├── guardduty.ts ├── import-cluster.ts ├── instana-operator.ts ├── ipv6.ts ├── jupyterhub.ts ├── karpenter.ts ├── kasten.ts ├── keptn-control-plane.ts ├── komodor.ts ├── konveyor.ts ├── kubecost.ts ├── kubeflow.ts ├── kubeshark.ts ├── multi-cluster-conformitron.ts ├── multi-region.ts ├── multi-team.ts ├── newrelic.ts ├── nginx.ts ├── paralus.ts ├── pipeline-multienv-gitops.ts ├── pipeline-multienv-monitoring.ts ├── pipeline.ts ├── rafay.ts ├── secure-ingress-cognito.ts ├── securityhub.ts ├── snyk.ts ├── starter.ts ├── windows.ts └── workloads-codecommit.ts ├── cdk.json ├── ci └── buildspec.yml ├── docs ├── index.md └── patterns │ ├── backstage.md │ ├── batch.md │ ├── crossplane-argocd-gitops.md │ ├── custom-networking-with-ipv4.md │ ├── generative-ai │ └── showcase.md │ ├── gmaestro.md │ ├── graviton.md │ ├── images │ ├── AMG - Metrics from AMP.png │ ├── AMG - Metrics from CloudWatch.png │ ├── Cognito-Kubecost-1.png │ ├── Cognito-Kubecost-2.png │ ├── Cognito-Signup-1.png │ ├── Cognito-Signup-2.png │ ├── Cognito-Signup-3.png │ ├── ConformitronDashboard1.png │ ├── ConformitronDashboard2.png │ ├── ConformitronDashboard3.png │ ├── CostOptimizationEventBridge.png │ ├── CostOptimizationEventBridge2.png │ ├── CostOptimizationEventBridge3.png │ ├── CostOptimizationSSM1.png │ ├── CostOptimizationSSM2.png │ ├── Custom-NW-Eni-Console.png │ ├── Custom-NW-IPv4-Instance-view.png │ ├── Custom-NW-IPv4.png │ ├── Custom-nw-bar-chart.png │ ├── Explore AMG.png │ ├── Explore CW.png │ ├── XRAY - Service Map.png │ ├── XRAY - Traces.png │ ├── amd-add-on.png │ ├── argocd-cc-workloads.png │ ├── argocd-cc.png │ ├── arm-add-on.png │ ├── aws_secret_codepipeline.png │ ├── backstage-console-output.png │ ├── backstage-diagram.png │ ├── backstage-kubectl-output.png │ ├── backstage-screen.png │ ├── codepipeline1.png │ ├── codepipeline2.png │ ├── conformitron.png │ ├── crossplane-argocd-gitops.png │ ├── custom-nw-mng.png │ ├── generativeai-showcase-architecture.jpg │ ├── generativeai-showcase-demo-output.jpg │ ├── gmaestro-config-file.png │ ├── gmaestro-generate-config-file.png │ ├── gmaestro-recommendations.png │ ├── instana-agent.png │ ├── konveyor-architecture.png │ ├── konveyor-cdk-output.png │ ├── konveyor-home.png │ ├── konveyor-login.png │ ├── secure-ingress-kubecost-new.png │ ├── secure-ingress-kubecost.png │ └── setup_amg-cross-account.png │ ├── instana.md │ ├── jupyterhub.md │ ├── karpenter.md │ ├── konveyor.md │ ├── kubeflow.md │ ├── kubeshark.md │ ├── multi-cluster-conformitron.md │ ├── nginx.md │ ├── observability │ ├── existing-eks-apiserver-observability.md │ ├── existing-eks-awsnative-observability.md │ ├── existing-eks-mixed-observability.md │ ├── existing-eks-nginx-observability.md │ ├── existing-eks-opensource-observability.md │ ├── multi-acc-new-eks-mixed-observability.md │ ├── multi-account-monitoring.md │ ├── single-new-eks-apiserver-opensource-observability.md │ ├── single-new-eks-awsnative-fargate-observability.md │ ├── single-new-eks-gpu-opensource-observability.md │ ├── single-new-eks-graviton-opensource-observability.md │ ├── single-new-eks-java-opensource-observability.md │ ├── single-new-eks-mixed-observability.md │ ├── single-new-eks-native.md │ ├── single-new-eks-nginx-opensource-observability.md │ └── single-new-eks-opensource.md │ ├── paralus.md │ ├── pipeline-multi-env-gitops.md │ ├── secureingresscognito.md │ ├── security │ ├── eks-config-rules.md │ ├── encryption-at-rest.md │ ├── guardduty.md │ ├── image-scanning.md │ └── securityhub.md │ ├── windows.md │ └── workloads-codecommit.md ├── jest.config.js ├── lib ├── amp-monitoring │ └── index.ts ├── argo-config-managent │ └── index.ts ├── aws-batch-on-eks-construct │ └── index.ts ├── backstage-construct │ ├── backstage-secret-addon.ts │ ├── database-credentials.ts │ ├── index.ts │ └── rds-database-instance.ts ├── bottlerocket-construct │ └── index.ts ├── cloudwatch-monitoring │ └── index.ts ├── common │ ├── construct-utils.ts │ └── default-main.ts ├── crossplane-argocd-gitops │ ├── custom-addons │ │ ├── crossplane-helm-provider-addon.ts │ │ ├── crossplane-k8s-provider-addon.ts │ │ ├── custom-iam-role-creator.ts │ │ ├── upbound-crossplane-addon.ts │ │ └── upbound-crossplane-eks-provider-addon.ts │ ├── management-cluster-builder.ts │ ├── multi-cluster-options.ts │ └── multi-cluster-pipeline.ts ├── custom-networking-ipv4-construct │ └── index.ts ├── datadog-construct │ └── index.ts ├── dynatrace-construct │ └── index.ts ├── emr-eks │ └── index.ts ├── fargate-construct │ └── index.ts ├── generative-ai-showcase │ ├── deployment │ │ └── showcase-deployment.ytpl │ ├── index.ts │ └── python │ │ ├── Dockerfile │ │ ├── requirements.txt │ │ ├── showcase_app.py │ │ ├── showcase_examples.py │ │ └── showcase_lib.py ├── generic-cluster-construct │ └── index.ts ├── gmaestro-construct │ └── index.ts ├── gpu-construct │ └── index.ts ├── graviton-construct │ └── index.ts ├── import-cluster │ └── index.ts ├── instana-construct │ └── index.ts ├── ipv6-construct │ └── index.ts ├── jupyterhub-construct │ └── index.ts ├── karpenter-construct │ └── index.ts ├── kasten-k10-construct │ └── index.ts ├── keptn-construct │ └── index.ts ├── komodor-construct │ └── index.ts ├── konveyor-construct │ └── index.ts ├── kubecost-construct │ └── index.ts ├── kubeflow-construct │ └── index.ts ├── kubeshark-construct │ └── index.ts ├── multi-account-monitoring │ ├── amg-iam-setup.ts │ ├── amp-iam-setup.ts │ ├── cloudwatch-iam-setup.ts │ ├── index.ts │ └── pipeline.ts ├── multi-cluster-construct │ ├── cluster-secret-store-addon.ts │ ├── clusterMapping.ts │ ├── grafana-monitor-builder.ts │ ├── grafana-operator-secret-addon.ts │ ├── multi-cluster-builder.ts │ ├── pipeline.ts │ └── resources │ │ ├── amp-config │ │ ├── alerting-rules.yml │ │ ├── apiserver │ │ │ └── recording-rules.yml │ │ ├── istio │ │ │ ├── alerting-rules.yml │ │ │ └── recording-rules.yml │ │ ├── java │ │ │ ├── alerting-rules.yml │ │ │ └── recording-rules.yml │ │ ├── nginx │ │ │ └── alerting-rules.yml │ │ └── recording-rules.yml │ │ ├── cost-optimization │ │ ├── scaleDownEksToZero.yml │ │ └── scaleUpEksToOne.yml │ │ └── otel-collector-config.yml ├── multi-region-construct │ └── index.ts ├── multi-team-construct │ └── index.ts ├── newrelic-construct │ └── index.ts ├── nginx-ingress-construct │ └── index.ts ├── paralus-construct │ └── index.ts ├── pipeline-multi-env-gitops │ └── index.ts ├── pipeline-stack │ └── index.ts ├── rafay-construct │ └── index.ts ├── secure-ingress-auth-cognito │ ├── index.ts │ └── lambda │ │ └── lambda_function.py ├── security │ ├── data-at-rest-encryption │ │ └── index.ts │ ├── eks-config-rules │ │ ├── config-setup.ts │ │ └── index.ts │ ├── guardduty-construct │ │ ├── guardduty-setup.ts │ │ └── index.ts │ ├── image-vulnerability-scanning │ │ ├── image-scanning-setup.ts │ │ └── index.ts │ └── securityhub-construct │ │ └── index.ts ├── snyk-construct │ └── index.ts ├── starter-construct │ └── index.ts ├── teams │ ├── index.ts │ ├── multi-account-monitoring │ │ ├── index.ts │ │ ├── team-geordi.ts │ │ └── team-platform.ts │ ├── pipeline-multi-env-gitops │ │ ├── index.ts │ │ ├── team-backend-crystal.ts │ │ ├── team-backend-frontend.ts │ │ ├── team-backend-nodejs.ts │ │ └── team-platform.ts │ ├── team-batch │ │ └── index.ts │ ├── team-burnham │ │ ├── index.ts │ │ └── restrict-ingress-egress-burnham.yaml │ ├── team-emr-on-eks │ │ └── index.ts │ ├── team-platform │ │ └── index.ts │ ├── team-riker │ │ ├── index.ts │ │ └── restrict-ingress-egress-riker.yaml │ ├── team-scan │ │ └── index.ts │ └── team-troi │ │ └── index.ts ├── windows-construct │ ├── index.ts │ └── vpc-cni │ │ └── index.ts └── workloads-codecommit-construct │ ├── codecommit-credentials.ts │ ├── index.ts │ ├── lambda │ └── index.js │ └── workloads-codecommit-repo-stack.ts ├── mkdocs.yml ├── package.json └── tsconfig.json /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/vscode/devcontainers/base:ubuntu", 3 | "features": { 4 | "ghcr.io/devcontainers/features/node:1": {}, 5 | "ghcr.io/devcontainers/features/aws-cli:1": {}, 6 | "ghcr.io/devcontainers-contrib/features/aws-cdk:2": { 7 | "version": "2.133.0" 8 | } 9 | }, 10 | "postCreateCommand": ".devcontainer/postCreateCommand.sh", 11 | "workspaceFolder": "/home/vscode/cdk-eks-blueprints-patterns", 12 | "workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/cdk-eks-blueprints-patterns,type=bind", 13 | "hostRequirements": { 14 | "cpus": 2 15 | }, 16 | "remoteEnv": { 17 | "PATH": "${containerEnv:PATH}:/home/vscode/cdk-eks-blueprints-patterns" 18 | } 19 | } -------------------------------------------------------------------------------- /.devcontainer/postCreateCommand.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # For Kubectl AMD64 / x86_64 4 | [ $(uname -m) = x86_64 ] && curl -sLO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" 5 | # For Kubectl ARM64 6 | [ $(uname -m) = aarch64 ] && curl -sLO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl" 7 | chmod +x ./kubectl 8 | sudo mv ./kubectl /usr/local/bin/kubectl 9 | 10 | # For Helm 11 | curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 12 | chmod 700 get_helm.sh 13 | echo "Installing 'helm' utility ..." 14 | ./get_helm.sh 15 | rm -rf get_helm.sh 16 | 17 | # setup autocomplete for kubectl and alias k 18 | mkdir $HOME/.kube 19 | echo "source <(kubectl completion bash)" >> $HOME/.bashrc 20 | echo "alias k=kubectl" >> $HOME/.bashrc 21 | echo "complete -F __start_kubectl k" >> $HOME/.bashrc 22 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | dist 4 | 5 | coverage 6 | 7 | cdk.out 8 | 9 | .eslintrc.js 10 | 11 | jest.config.js 12 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | plugins: [ 5 | '@typescript-eslint', 6 | ], 7 | extends: [ 8 | 'eslint:recommended', 9 | 'plugin:@typescript-eslint/recommended' 10 | ], 11 | rules: { 12 | "@typescript-eslint/no-explicit-any": "off", 13 | "@typescript-eslint/explicit-module-boundary-types": "off", 14 | "@typescript-eslint/no-non-null-assertion": "off", 15 | "@typescript-eslint/no-unused-vars": [1, {"argsIgnorePattern": "^_"}], 16 | indent: ['error', 4], 17 | "prefer-const": "off", 18 | "semi": ['error',"always"], 19 | }, 20 | }; -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | - Device: [e.g. iPhone6] 30 | - OS: [e.g. iOS8.1] 31 | - Browser [e.g. stock browser, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.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/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: macos-14 12 | 13 | strategy: 14 | matrix: 15 | node-version: [18] 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | 25 | - name: Cache node modules 26 | uses: actions/cache@v2 27 | env: 28 | cache-name: cache-node-modules 29 | with: 30 | # npm cache files are stored in `~/.npm` on Linux/macOS 31 | path: ~/.npm 32 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 33 | restore-keys: | 34 | ${{ runner.os }}-build-${{ env.cache-name }}- 35 | ${{ runner.os }}-build- 36 | ${{ runner.os }}- 37 | 38 | - name: Install Deps 39 | run: make deps 40 | 41 | - name: Run Linter 42 | run: make lint 43 | 44 | - name: Build TSC 45 | run: make build 46 | 47 | - name: Run CDK List 48 | run: make list 49 | 50 | - name: Run CDK Synth 51 | run: make test-all -------------------------------------------------------------------------------- /.github/workflows/docbuild.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: 5 | - master 6 | - main 7 | permissions: 8 | contents: write 9 | jobs: 10 | deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-python@v4 15 | with: 16 | python-version: 3.x 17 | - run: pip install mkdocs-material 18 | - run: pip install mkdocs-embed-external-markdown 19 | - run: mkdocs gh-deploy --force 20 | -------------------------------------------------------------------------------- /.github/workflows/e2e.yaml: -------------------------------------------------------------------------------- 1 | name: "E2E Pipeline for CDK Observability Accelerator" 2 | on: 3 | issue_comment: 4 | types: [created] 5 | jobs: 6 | checkPermissions: 7 | runs-on: ubuntu-latest 8 | if: github.event.issue.pull_request && contains(github.event.comment.body, '/do-e2e-test') # check the comment if it contains the keywords 9 | steps: 10 | - id: checkUserPermissions 11 | uses: actions-cool/check-user-permission@main 12 | with: 13 | require: 'admin' 14 | outputs: 15 | run_test: ${{ steps.checkUserPermissions.outputs.require-result }} 16 | e2ePipeline: 17 | runs-on: ubuntu-latest 18 | if: github.event.issue.pull_request && contains(github.event.comment.body, '/do-e2e-test') && needs.checkPermissions.outputs.run_test == 'true' 19 | needs: 20 | - checkPermissions 21 | permissions: 22 | id-token: write # This is required for requesting the JWT 23 | contents: read 24 | steps: 25 | - name: Dump GitHub context 26 | env: 27 | GITHUB_CONTEXT: ${{ toJson(github) }} 28 | run: | 29 | echo "$GITHUB_CONTEXT" 30 | - name: Get PR branch 31 | uses: xt0rted/pull-request-comment-branch@v1 32 | id: comment-branch 33 | - name: Set latest commit status as pending 34 | uses: myrotvorets/set-commit-status-action@master 35 | with: 36 | sha: ${{ steps.comment-branch.outputs.head_sha }} 37 | token: ${{ secrets.CI_TOKEN }} 38 | status: pending 39 | - name: Configure AWS Credentials 40 | uses: aws-actions/configure-aws-credentials@v4 41 | with: 42 | role-to-assume: arn:aws:iam::867286930927:role/BlueprintsCodeBuildRole 43 | role-session-name: codebuildsession 44 | aws-region: ${{ vars.AWS_REGION }} 45 | - name: Run CodeBuild 46 | uses: aws-actions/aws-codebuild-run-build@v1 47 | with: 48 | project-name: cdk-pattern-test 49 | # buildspec-override: path/to/buildspec.yaml or inline buildspec definition 50 | # compute-type-override: compute-type 51 | # environment-type-override: environment-type 52 | # image-override: ecr-image-uri 53 | env-vars-for-codebuild: | 54 | PR_NUMBER, 55 | COMMIT_ID, 56 | PATTERN_NAME 57 | env: 58 | PR_NUMBER: ${{ github.event.issue.number }} 59 | COMMIT_ID: ${{ steps.comment-branch.outputs.head_sha }} 60 | PATTERN_NAME: ${{ github.event.comment.body }} 61 | - name: Set latest commit status as ${{ job.status }} 62 | uses: myrotvorets/set-commit-status-action@master 63 | if: always() 64 | with: 65 | sha: ${{ steps.comment-branch.outputs.head_sha }} 66 | token: ${{ secrets.CI_TOKEN }} 67 | status: ${{ job.status }} 68 | 69 | -------------------------------------------------------------------------------- /.github/workflows/linkcheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "timeout": "5s", 3 | "retryOn429": true, 4 | "retryCount": 5, 5 | "fallbackRetryDelay": "30s", 6 | "aliveStatusCodes": [200, 206], 7 | "httpHeaders": [ 8 | { 9 | "urls": ["https://help.github.com/"], 10 | "headers": { 11 | "Accept-Encoding": "zstd, br, gzip, deflate" 12 | } 13 | } 14 | ], 15 | "ignorePatterns": [ 16 | { 17 | "pattern": [ 18 | "localhost" 19 | ] 20 | }, 21 | { 22 | "pattern": [ 23 | "127.0.0.1" 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /.github/workflows/markdown-link-check.yaml: -------------------------------------------------------------------------------- 1 | name: Check Markdown links 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - "**/*.md" 9 | 10 | pull_request: 11 | branches: 12 | - main 13 | paths: 14 | - "**/*.md" 15 | 16 | jobs: 17 | markdown-link-check: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v3 21 | - uses: actions/setup-node@v3 22 | with: 23 | node-version: '18.x' 24 | - name: install markdown-link-check 25 | run: npm install -g markdown-link-check@3.10.2 26 | - name: markdown-link-check version 27 | run: npm list -g markdown-link-check 28 | - name: Run markdown-link-check on MD files 29 | run: find docs -name "*.md" | xargs -n 1 markdown-link-check -q -c .github/workflows/linkcheck.json 30 | -------------------------------------------------------------------------------- /.github/workflows/stale_issue_pr.yaml: -------------------------------------------------------------------------------- 1 | name: 'Stale issue & PR handler' 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | issues: write 12 | pull-requests: write 13 | steps: 14 | - uses: actions/stale@main 15 | id: stale 16 | with: 17 | ascending: true 18 | close-issue-message: 'Issue closed due to inactivity.' 19 | close-pr-message: 'Pull request closed due to inactivity.' 20 | days-before-close: 60 21 | days-before-stale: 90 22 | stale-issue-label: stale 23 | stale-pr-label: stale 24 | # Not stale if have this labels 25 | exempt-issue-labels: 'bug,enhancement,"feature request"' 26 | exempt-pr-labels: 'bug,enhancement' 27 | operations-per-run: 100 28 | stale-issue-message: | 29 | This issue has been automatically marked as stale because it has been open 60 days 30 | with no activity. Remove stale label or comment or this issue will be closed in 10 days 31 | stale-pr-message: | 32 | This PR has been automatically marked as stale because it has been open 60 days 33 | with no activity. Remove stale label or comment or this PR will be closed in 10 days 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | !jest.config.js 2 | *.d.ts 3 | node_modules 4 | .vscode 5 | 6 | .classpath.txt 7 | .idea 8 | .settings 9 | .vscode 10 | *.iml 11 | 12 | # CDK asset staging directory 13 | .cdk.staging 14 | cdk.out 15 | cdk.json 16 | dist 17 | *.swp 18 | cdk.context.json 19 | package-lock.json 20 | yarn.lock 21 | 22 | # mkdocs artifact 23 | site 24 | # macOS extraneous file 25 | .DS_STORE 26 | 27 | # Python virtual env directory 28 | *.venv* 29 | 30 | *otel-collector-config-new.yml -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 12.18.2 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Libraries 4 | TSC := node node_modules/.bin/tsc 5 | ESLINT := node node_modules/.bin/eslint 6 | CDK := node node_modules/.bin/cdk 7 | pattern: pattern_name := $(firstword $(filter-out pattern, $(MAKECMDGOALS))) 8 | pattern: pattern_command := $(subst pattern $(pattern_name), , $(MAKECMDGOALS)) 9 | 10 | pattern_files := $(notdir $(wildcard bin/*.ts)) 11 | formatted_pattern_names := $(patsubst %.ts,%,$(pattern_files)) 12 | 13 | # Dependecies 14 | HOMEBREW_LIBS := nvm typescript argocd 15 | 16 | list: 17 | @$ echo "To work with patterns use: \n\t$$ make pattern " 18 | @$ echo "Example:\n\t$$ make pattern fargate deploy \n\nPatterns: \n" 19 | @$ $(foreach pattern, $(formatted_pattern_names), echo "\t$(pattern)";) 20 | 21 | deps: bootstrap 22 | npm install 23 | 24 | lint: 25 | $(ESLINT) . --ext .js,.jsx,.ts,.tsx 26 | 27 | lint-fix: 28 | $(ESLINT) . --ext .js,.jsx,.ts,.tsx --fix 29 | 30 | build: 31 | rm -rf dist && $(TSC) --skipLibCheck 32 | 33 | compile: 34 | $(TSC) --build --incremental 35 | 36 | mkdocs: 37 | mkdocs serve 38 | 39 | pattern: 40 | @echo $(pattern_name) performing $(pattern_command) 41 | $(CDK) --app "npx ts-node bin/$(pattern_name).ts" $(if $(pattern_command),$(pattern_command), list) 42 | @: 43 | %: 44 | @: 45 | 46 | test-all: 47 | @for pattern in $(formatted_pattern_names) ; do \ 48 | echo "Building pattern $$pattern"; \ 49 | $(CDK) --app "npx ts-node bin/$$pattern.ts" list || exit 1 ;\ 50 | done 51 | 52 | bootstrap: 53 | @for LIB in $(HOMEBREW_LIBS) ; do \ 54 | LIB=$$LIB make check-lib ; \ 55 | done 56 | 57 | check-lib: 58 | ifeq ($(shell brew ls --versions $(LIB)),) 59 | @echo Installing $(LIB) via Homebrew 60 | @brew install $(LIB) 61 | else 62 | @echo $(LIB) is already installed, skipping. 63 | endif 64 | -------------------------------------------------------------------------------- /aws-quickstart-eks-blueprints-1.13.1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/aws-quickstart-eks-blueprints-1.13.1.tgz -------------------------------------------------------------------------------- /bin/asg.ts: -------------------------------------------------------------------------------- 1 | import 'source-map-support/register'; 2 | import * as cdk from 'aws-cdk-lib'; 3 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 4 | 5 | import { configureApp } from "../lib/common/construct-utils"; 6 | 7 | const app = configureApp(); 8 | 9 | const spotInterruptHandlerAddOn = new blueprints.addons.AwsNodeTerminationHandlerAddOn({ 10 | version: "0.25.1", 11 | repository: 'oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler' 12 | }); 13 | 14 | const clusterProvider = new blueprints.AsgClusterProvider({ 15 | version: cdk.aws_eks.KubernetesVersion.V1_30, 16 | minSize: 1, maxSize: 1, spotPrice: "0.10", 17 | machineImageType: cdk.aws_eks.MachineImageType.BOTTLEROCKET, 18 | id: "asg-spot", 19 | name: "asg-spot", 20 | spotInterruptHandler: false 21 | }); 22 | 23 | const blueprint = blueprints.EksBlueprint.builder() 24 | .region("us-west-2") 25 | .version("auto") 26 | .clusterProvider(clusterProvider) 27 | .addOns(spotInterruptHandlerAddOn) 28 | .build(app, 'asg-test'); -------------------------------------------------------------------------------- /bin/backstage.ts: -------------------------------------------------------------------------------- 1 | import { BackstageConstruct } from '../lib/backstage-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new BackstageConstruct(app, 'backstage-stack'); 7 | -------------------------------------------------------------------------------- /bin/batch.ts: -------------------------------------------------------------------------------- 1 | import BatchConstruct from '../lib/aws-batch-on-eks-construct'; 2 | import { batchTeam } from '../lib/teams/team-batch'; 3 | import { configureApp } from '../lib/common/construct-utils'; 4 | 5 | const app = configureApp(); 6 | 7 | //------------------------------------------- 8 | // Single cluster with Batch on EKS deployed 9 | //------------------------------------------- 10 | new BatchConstruct().build(app, 'batch', [batchTeam]); -------------------------------------------------------------------------------- /bin/bottlerocket.ts: -------------------------------------------------------------------------------- 1 | import BottleRocketConstruct from '../lib/bottlerocket-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | //------------------------------------------- 7 | // Single cluster with Bottlerocket nodes. 8 | //------------------------------------------- 9 | new BottleRocketConstruct().build(app, 'bottlerocket'); -------------------------------------------------------------------------------- /bin/crossplane-argocd-gitops.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import * as cdk from 'aws-cdk-lib'; 3 | import { errorHandler } from '../lib/common/construct-utils'; 4 | import MultiClusterPipelineConstruct from "../lib/crossplane-argocd-gitops/multi-cluster-pipeline"; 5 | 6 | const app = new cdk.App(); 7 | 8 | new MultiClusterPipelineConstruct().buildAsync(app, "crossplane-argocd-gitops").catch((e) => { 9 | errorHandler(app, "Pipeline construct failed because of error: ", e); 10 | }); 11 | -------------------------------------------------------------------------------- /bin/custom-networking-ipv4.ts: -------------------------------------------------------------------------------- 1 | import CustomNetworkingIPv4Construct from '../lib/custom-networking-ipv4-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | new CustomNetworkingIPv4Construct(app, 'custom-networking-ipv4'); -------------------------------------------------------------------------------- /bin/data-at-rest-encryption.ts: -------------------------------------------------------------------------------- 1 | import EncryptionAtRestConstruct from "../lib/security/data-at-rest-encryption"; 2 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 3 | 4 | 5 | //-------------------------------------------------------------------------- 6 | // Security Patterns 7 | //-------------------------------------------------------------------------- 8 | 9 | const app = configureApp(); 10 | new EncryptionAtRestConstruct().buildAsync(app, "data-at-rest-encryption").catch((e) => { 11 | errorHandler(app, "EncryptionAtRestConstruct is not setup due to missing secrets for ArgoCD admin pwd", e); 12 | }); 13 | -------------------------------------------------------------------------------- /bin/datadog.ts: -------------------------------------------------------------------------------- 1 | import DatadogConstruct from '../lib/datadog-construct'; 2 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new DatadogConstruct().buildAsync(app, 'datadog').catch((error) => { 7 | errorHandler(app, "Datadog pattern is not setup due to missing secrets: " + error); 8 | }); -------------------------------------------------------------------------------- /bin/dynatrace-operator.ts: -------------------------------------------------------------------------------- 1 | import DynatraceOperatorConstruct from '../lib/dynatrace-construct'; 2 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new DynatraceOperatorConstruct().buildAsync(app, "dynatrace-operator").catch((e) => { 7 | errorHandler(app, "Dynatrace pattern is not setup due to missing secrets for dynatrace-tokens.", e); 8 | }); -------------------------------------------------------------------------------- /bin/ecr-image-scanning.ts: -------------------------------------------------------------------------------- 1 | 2 | import { ImageScanningSetupStack } from "../lib/security/image-vulnerability-scanning/image-scanning-setup"; 3 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 4 | import ImageScanningWorkloadConstruct from "../lib/security/image-vulnerability-scanning"; 5 | 6 | const app = configureApp(); 7 | 8 | new ImageScanningSetupStack(app, "image-scanning-setup"); 9 | 10 | new ImageScanningWorkloadConstruct().buildAsync(app, "image-scanning-workload").catch((e) => { 11 | errorHandler(app, "ImageScanningWorkloadConstruct is not setup due to missing secrets for ArgoCD admin pwd", e); 12 | }); -------------------------------------------------------------------------------- /bin/eks-config-rules.ts: -------------------------------------------------------------------------------- 1 | import { configureApp } from '../lib/common/construct-utils'; 2 | import { EksConfigRulesSetup } from '../lib/security/eks-config-rules'; 3 | import { EksConfigSetup } from '../lib/security/eks-config-rules/config-setup'; 4 | 5 | 6 | const app = configureApp(); 7 | 8 | new EksConfigSetup(app, 'eks-config-setup'); 9 | 10 | new EksConfigRulesSetup(app, 'eks-config-rules-setup'); 11 | -------------------------------------------------------------------------------- /bin/emr.ts: -------------------------------------------------------------------------------- 1 | import EmrEksConstruct from '../lib/emr-eks'; 2 | import { dataTeam } from '../lib/teams/team-emr-on-eks'; 3 | import { configureApp } from '../lib/common/construct-utils'; 4 | 5 | const app = configureApp(); 6 | 7 | new EmrEksConstruct().build(app, 'emrOnEks', [dataTeam]); -------------------------------------------------------------------------------- /bin/fargate.ts: -------------------------------------------------------------------------------- 1 | 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | import FargateConstruct from '../lib/fargate-construct'; 4 | 5 | new FargateConstruct(configureApp(), 'fargate'); -------------------------------------------------------------------------------- /bin/generative-ai-showcase.ts: -------------------------------------------------------------------------------- 1 | import GenAIShowcase from "../lib/generative-ai-showcase"; 2 | import { configureApp } from "../lib/common/construct-utils"; 3 | 4 | const app = configureApp(); 5 | 6 | new GenAIShowcase(app, 'generative-ai-showcase'); 7 | -------------------------------------------------------------------------------- /bin/generic-cluster-provider.ts: -------------------------------------------------------------------------------- 1 | import { configureApp } from '../lib/common/construct-utils'; 2 | import GenericClusterConstruct from '../lib/generic-cluster-construct'; 3 | 4 | const app = configureApp(); 5 | 6 | //------------------------------------------- 7 | // Single cluster with custom configuration. 8 | //------------------------------------------- 9 | new GenericClusterConstruct().build(app, 'generic-cluster'); -------------------------------------------------------------------------------- /bin/gmaestro.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import GmaestroConstruct from '../lib/gmaestro-construct'; 3 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 4 | 5 | const app = configureApp(); 6 | 7 | new GmaestroConstruct().buildAsync(app, 'gmaestro').catch((error) => { 8 | errorHandler(app, "Gmaestro is not setup due to missing secrets: " + error); 9 | }); 10 | -------------------------------------------------------------------------------- /bin/gpu.ts: -------------------------------------------------------------------------------- 1 | import { configureApp } from "../lib/common/construct-utils"; 2 | import GpuConstruct from "../lib/gpu-construct"; 3 | 4 | const app = configureApp(); 5 | 6 | new GpuConstruct().build(app, "gpu"); 7 | -------------------------------------------------------------------------------- /bin/graviton.ts: -------------------------------------------------------------------------------- 1 | import { configureApp } from "../lib/common/construct-utils"; 2 | import GravitonConstruct from "../lib/graviton-construct"; 3 | 4 | const app = configureApp(); 5 | 6 | new GravitonConstruct().build(app, "graviton"); 7 | -------------------------------------------------------------------------------- /bin/guardduty.ts: -------------------------------------------------------------------------------- 1 | import { GuardDutySetupStack } from "../lib/security/guardduty-construct/guardduty-setup"; 2 | import GuardDutyWorkloadConstruct from "../lib/security/guardduty-construct"; 3 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 4 | 5 | const app = configureApp(); 6 | 7 | new GuardDutySetupStack(app, "guardduty-setup"); 8 | 9 | new GuardDutyWorkloadConstruct().buildAsync(app, "guardduty").catch((e) => { 10 | errorHandler(app, "GuardDutyWorkloadConstruct is not setup due to missing secrets for ArgoCD admin pwd", e); 11 | }); 12 | -------------------------------------------------------------------------------- /bin/import-cluster.ts: -------------------------------------------------------------------------------- 1 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 2 | import { ImportClusterConstruct } from '../lib/import-cluster'; 3 | 4 | 5 | 6 | const app = configureApp(); 7 | 8 | //------------------------------------------- 9 | // Multiple clusters, multiple regions. 10 | //------------------------------------------- 11 | 12 | new ImportClusterConstruct().build(app).catch((error) => { 13 | errorHandler(app, "Import cluster construct failed to import cluster", error); 14 | }); -------------------------------------------------------------------------------- /bin/instana-operator.ts: -------------------------------------------------------------------------------- 1 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 2 | import InstanaConstruct from '../lib/instana-construct'; 3 | 4 | const app = configureApp(); 5 | 6 | new InstanaConstruct().buildAsync(app, "instana-operator").catch((error) => { 7 | errorHandler(app, "Instana pattern is not setup due to missing secrets: " + error); 8 | }); -------------------------------------------------------------------------------- /bin/ipv6.ts: -------------------------------------------------------------------------------- 1 | import { configureApp } from "../lib/common/construct-utils"; 2 | import IpV6Construct from "../lib/ipv6-construct"; 3 | 4 | const app = configureApp(); 5 | 6 | new IpV6Construct().build(app, "ipv6"); 7 | -------------------------------------------------------------------------------- /bin/jupyterhub.ts: -------------------------------------------------------------------------------- 1 | 2 | import JupyterHubConstruct from '../lib/jupyterhub-construct'; 3 | import { configureApp } from '../lib/common/construct-utils'; 4 | 5 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 6 | const region = process.env.CDK_DEFAULT_REGION!; 7 | 8 | const app = configureApp(); 9 | 10 | new JupyterHubConstruct(app, 'jupyterhub', { env: { account, region } }); -------------------------------------------------------------------------------- /bin/karpenter.ts: -------------------------------------------------------------------------------- 1 | import KarpenterConstruct from "../lib/karpenter-construct"; 2 | import { configureApp } from "../lib/common/construct-utils"; 3 | 4 | const app = configureApp(); 5 | 6 | new KarpenterConstruct(app, 'karpenter'); 7 | -------------------------------------------------------------------------------- /bin/kasten.ts: -------------------------------------------------------------------------------- 1 | 2 | import KastenK10Construct from '../lib/kasten-k10-construct'; 3 | import { configureApp } from '../lib/common/construct-utils'; 4 | 5 | const app = configureApp(); 6 | 7 | new KastenK10Construct(app, 'kasten'); -------------------------------------------------------------------------------- /bin/keptn-control-plane.ts: -------------------------------------------------------------------------------- 1 | import KeptnControlPlaneConstruct from '../lib/keptn-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new KeptnControlPlaneConstruct(app, 'keptn'); -------------------------------------------------------------------------------- /bin/komodor.ts: -------------------------------------------------------------------------------- 1 | // import KomodorConstruct from '../lib/komodor-construct'; 2 | // import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | // const app = configureApp(); 5 | 6 | // new KomodorConstruct(app, 'komodor'); -------------------------------------------------------------------------------- /bin/konveyor.ts: -------------------------------------------------------------------------------- 1 | import { KonveyorConstruct } from "../lib/konveyor-construct"; 2 | import { configureApp } from "../lib/common/construct-utils"; 3 | 4 | const app = configureApp(); 5 | 6 | new KonveyorConstruct(app, 'konveyor-stack'); -------------------------------------------------------------------------------- /bin/kubecost.ts: -------------------------------------------------------------------------------- 1 | import KubecostConstruct from '../lib/kubecost-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new KubecostConstruct(app, 'kubecost'); -------------------------------------------------------------------------------- /bin/kubeflow.ts: -------------------------------------------------------------------------------- 1 | import KubeflowConstruct from '../lib/kubeflow-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new KubeflowConstruct(app, 'kubeflow'); -------------------------------------------------------------------------------- /bin/kubeshark.ts: -------------------------------------------------------------------------------- 1 | import KubesharkConstruct from '../lib/kubeshark-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new KubesharkConstruct(app, 'kubeshark'); -------------------------------------------------------------------------------- /bin/multi-cluster-conformitron.ts: -------------------------------------------------------------------------------- 1 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 2 | import { PipelineMultiCluster } from '../lib/multi-cluster-construct/pipeline'; 3 | 4 | 5 | const app = configureApp(); 6 | 7 | //------------------------------------------- 8 | // Multiple clusters, multiple regions. 9 | //------------------------------------------- 10 | 11 | new PipelineMultiCluster().buildAsync(app).catch((error) => { 12 | errorHandler(app, "Multi cluster pattern is not setup. It may be due to missing secrets: ", error); 13 | }); -------------------------------------------------------------------------------- /bin/multi-region.ts: -------------------------------------------------------------------------------- 1 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 2 | import MultiRegionConstruct from '../lib/multi-region-construct'; 3 | 4 | 5 | const app = configureApp(); 6 | 7 | //------------------------------------------- 8 | // Multiple clusters, multiple regions. 9 | //------------------------------------------- 10 | 11 | new MultiRegionConstruct().buildAsync(app, 'multi-region').catch((error) => { 12 | errorHandler(app, "Multi region pattern is not setup. It may be due to missing secrets: ", error); 13 | }); -------------------------------------------------------------------------------- /bin/multi-team.ts: -------------------------------------------------------------------------------- 1 | import { configureApp } from '../lib/common/construct-utils'; 2 | import MultiTeamConstruct from '../lib/multi-team-construct'; 3 | 4 | const app = configureApp(); 5 | 6 | //------------------------------------------- 7 | // Single Cluster with multiple teams. 8 | //------------------------------------------- 9 | 10 | new MultiTeamConstruct(app, 'multi-team'); -------------------------------------------------------------------------------- /bin/newrelic.ts: -------------------------------------------------------------------------------- 1 | import NewRelicConstruct from '../lib/newrelic-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new NewRelicConstruct(app, 'newrelic-cluster'); 7 | -------------------------------------------------------------------------------- /bin/nginx.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import NginxIngressConstruct from '../lib/nginx-ingress-construct'; 3 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 4 | 5 | const app = configureApp(); 6 | 7 | new NginxIngressConstruct().buildAsync(app, 'nginx').catch((e) => { 8 | errorHandler(app, "NGINX Ingress pattern is not setup. This maybe due to missing secrets for ArgoCD admin pwd.", e); 9 | }); 10 | -------------------------------------------------------------------------------- /bin/paralus.ts: -------------------------------------------------------------------------------- 1 | import ParalusConstruct from '../lib/paralus-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new ParalusConstruct(app, 'paralus'); -------------------------------------------------------------------------------- /bin/pipeline-multienv-gitops.ts: -------------------------------------------------------------------------------- 1 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 2 | import PipelineMultiEnvGitops, { populateWithContextDefaults } from '../lib/pipeline-multi-env-gitops'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | 5 | 6 | // CDK Default Environment - default account and region 7 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 8 | const region = process.env.CDK_DEFAULT_REGION!; 9 | const env: cdk.Environment = { account: account, region: region }; 10 | 11 | const app = configureApp(); 12 | // These different CDK environments are meant to be used for multi-region/account usage, 13 | // where the pipeline, dev cluster, and prod cluster are deployed in seperate environments 14 | const { devEnv, pipelineEnv, prodEnv }: 15 | { devEnv: cdk.Environment; pipelineEnv: cdk.Environment; prodEnv: cdk.Environment; } = 16 | populateWithContextDefaults(app, account, region); 17 | 18 | //-------------------------------------------------------------------------- 19 | // Multiple clusters, multiple reginos ,multiple teams, GitOps bootstrapped. 20 | //-------------------------------------------------------------------------- 21 | new PipelineMultiEnvGitops() 22 | .buildAsync( 23 | app, 24 | 'pipeline-multi-env', 25 | { 26 | devTestEnv: devEnv, 27 | pipelineEnv: pipelineEnv, 28 | prodEnv: prodEnv, 29 | }, 30 | { env } 31 | ) 32 | .catch((e) => { 33 | errorHandler( 34 | app, 35 | 'Pipeline pattern is not setup due to missing secrets for GitHub access.', 36 | e 37 | ); 38 | }); -------------------------------------------------------------------------------- /bin/pipeline-multienv-monitoring.ts: -------------------------------------------------------------------------------- 1 | 2 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 3 | import { PipelineMultiEnvMonitoring } from '../lib/multi-account-monitoring'; 4 | 5 | const app = configureApp(); 6 | 7 | //-------------------------------------------------------------------------- 8 | // Multiple clusters, multiple accounts, pipeline and Monitoring 9 | //-------------------------------------------------------------------------- 10 | new PipelineMultiEnvMonitoring() 11 | .buildAsync(app) 12 | .catch((e) => { 13 | errorHandler(app, "Multi Account Monitoring pattern is not setup due to missing secrets for GitHub \ 14 | access and/or CDK Context. See Multi Account Monitoring in the readme for instructions", e); 15 | }); -------------------------------------------------------------------------------- /bin/pipeline.ts: -------------------------------------------------------------------------------- 1 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 2 | import PipelineConstruct from '../lib/pipeline-stack'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | 5 | //------------------------------------------- 6 | // Multiple clusters with deployment pipeline. 7 | //------------------------------------------- 8 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 9 | const region = process.env.CDK_DEFAULT_REGION!; 10 | const env: cdk.Environment = { account: account, region: region }; 11 | const app = configureApp(); 12 | 13 | 14 | new PipelineConstruct().buildAsync(app, { env }).catch((e) => { 15 | errorHandler(app, "Pipeline pattern is not setup due to missing secrets for GitHub access.", e); 16 | }); 17 | -------------------------------------------------------------------------------- /bin/rafay.ts: -------------------------------------------------------------------------------- 1 | 2 | import RafayConstruct from '../lib/rafay-construct'; 3 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 4 | 5 | const app = configureApp(); 6 | 7 | new RafayConstruct().buildAsync(app, 'rafay-cluster').catch((error) => { 8 | errorHandler(app, "Rafay pattern is not setup due to missing secrets: " + error); 9 | }); -------------------------------------------------------------------------------- /bin/secure-ingress-cognito.ts: -------------------------------------------------------------------------------- 1 | import { SecureIngressCognito } from '../lib/secure-ingress-auth-cognito'; 2 | import { configureApp, errorHandler } from '../lib/common/construct-utils'; 3 | 4 | //-------------------------------------------------------------------------- 5 | // Single Cluster, Secure Ingress Auth using cognito 6 | //-------------------------------------------------------------------------- 7 | 8 | const app = configureApp(); 9 | 10 | new SecureIngressCognito() 11 | .buildAsync(app, 'secure-ingress') 12 | .catch((e) => { 13 | errorHandler(app, "Secure Ingress Auth pattern is not setup due to missing secrets for ArgoCD admin pwd. \ 14 | See Secure Ingress Auth in the readme for instructions", e); 15 | }); 16 | -------------------------------------------------------------------------------- /bin/securityhub.ts: -------------------------------------------------------------------------------- 1 | import { configureApp } from '../lib/common/construct-utils'; 2 | import { SecurityHubStackSetup } from '../lib/security/securityhub-construct'; 3 | 4 | const app = configureApp(); 5 | new SecurityHubStackSetup(app, 'securityhub-setup'); -------------------------------------------------------------------------------- /bin/snyk.ts: -------------------------------------------------------------------------------- 1 | import SnykConstruct from '../lib/snyk-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new SnykConstruct(app, 'snyk-monitor'); -------------------------------------------------------------------------------- /bin/starter.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | import StarterConstruct from '../lib/starter-construct'; 4 | 5 | const app = configureApp(); 6 | 7 | new StarterConstruct().build(app, 'starter-construct'); 8 | -------------------------------------------------------------------------------- /bin/windows.ts: -------------------------------------------------------------------------------- 1 | import { configureApp } from "../lib/common/construct-utils"; 2 | import WindowsConstruct from "../lib/windows-construct"; 3 | 4 | const app = configureApp(); 5 | 6 | new WindowsConstruct().build(app, "windows"); 7 | -------------------------------------------------------------------------------- /bin/workloads-codecommit.ts: -------------------------------------------------------------------------------- 1 | import WorkloadsCodeCommitConstruct from '../lib/workloads-codecommit-construct'; 2 | import { configureApp } from '../lib/common/construct-utils'; 3 | 4 | const app = configureApp(); 5 | 6 | new WorkloadsCodeCommitConstruct(app, 'workloads-codecommit'); 7 | -------------------------------------------------------------------------------- /cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node dist/lib/common/default-main.js", 3 | "context": { 4 | "conformitron.amp.endpoint": "https://aps-workspaces.us-east-1.amazonaws.com/workspaces/ws-77b8828d-0985-49e0-9268-2e0e8f3ba758/", 5 | "conformitron.amp.arn":"arn:aws:aps:us-east-1:975050283200:workspace/ws-77b8828d-0985-49e0-9268-2e0e8f3ba758", 6 | "conformitron.amg.endpoint": "https://g-75bcfc519c.grafana-workspace.us-east-1.amazonaws.com", 7 | "conformitron.version": ["1.28","1.29","1.30"], 8 | "fluxRepository": { 9 | "name": "grafana-dashboards", 10 | "namespace": "grafana-operator", 11 | "repository": { 12 | "repoUrl": "https://github.com/aws-observability/aws-observability-accelerator", 13 | "name": "grafana-dashboards", 14 | "targetRevision": "main", 15 | "path": "./artifacts/grafana-operator-manifests/eks/infrastructure" 16 | }, 17 | "values": { 18 | "GRAFANA_CLUSTER_DASH_URL" : "https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/grafana-dashboards/eks/infrastructure/cluster.json", 19 | "GRAFANA_KUBELET_DASH_URL" : "https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/grafana-dashboards/eks/infrastructure/kubelet.json", 20 | "GRAFANA_NSWRKLDS_DASH_URL" : "https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/grafana-dashboards/eks/infrastructure/namespace-workloads.json", 21 | "GRAFANA_NODEEXP_DASH_URL" : "https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/grafana-dashboards/eks/infrastructure/nodeexporter-nodes.json", 22 | "GRAFANA_NODES_DASH_URL" : "https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/grafana-dashboards/eks/infrastructure/nodes.json", 23 | "GRAFANA_WORKLOADS_DASH_URL" : "https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/grafana-dashboards/eks/infrastructure/workloads.json" 24 | }, 25 | "kustomizations": [ 26 | { 27 | "kustomizationPath": "./artifacts/grafana-operator-manifests/eks/infrastructure" 28 | } 29 | ] 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ci/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | CONTEXT_LOCATION: 5 | COMMIT_ID: 6 | PR_NUMBER: 7 | PATTERN_NAME: 8 | phases: 9 | install: 10 | runtime-versions: 11 | nodejs: 18 12 | commands: 13 | - n 20.10.0 14 | - | 15 | if [ ! -z "${COMMIT_ID}" ]; then 16 | git fetch origin pull/${PR_NUMBER}/head:pr 17 | git checkout main 18 | # git merge needs user details, but we don't push anything, so the contents are unimportant 19 | git -c "user.name=CI Bot" -c "user.email=dev@null" merge --no-edit ${COMMIT_ID} 20 | fi 21 | - npm i 22 | - make build 23 | pre_build: 24 | commands: 25 | - | 26 | [ -z "$CONTEXT_LOCATION" ] || aws s3 cp $CONTEXT_LOCATION . 27 | build: 28 | commands: 29 | - export AWS_REGION=us-east-2 && make pattern "${PATTERN_NAME#/do-e2e-test } --verbose --all --require-approval never --force" 30 | # finally: 31 | # - make destroy-all 32 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --8<-- "README.md" -------------------------------------------------------------------------------- /docs/patterns/batch.md: -------------------------------------------------------------------------------- 1 | # AWS Batch on Amazon EKS Pattern 2 | 3 | ## Objective 4 | 5 | AWS Batch helps you run batch computing workloads on AWS. Using Amazon EKS as the compute resource, you can now schedule and scale batch workloads into new or existing EKS cluster. As part of the deployment, AWS Batch doesn't create, administer, or perform lifecycle operations of the EKS cluster, but will only scale up and down the nodes maanged by AWS Batch and run pods on those nodes to complete batch jobs. 6 | 7 | The objective of this pattern is to deploy AWS Batch on Amazon EKS using EKS Blueprints with the following features in place: 8 | - Batch addon implemented 9 | - Batch Team defined with a sample compute environment and job queue (as defined under `lib/teams/team-batch`) - This can be customized based on your needs 10 | - Fluent Bit addon implemented to monitor AWS Batch on Amazon EKS jobs using CloudWatch, with the proper permissions for sending logs -------------------------------------------------------------------------------- /docs/patterns/images/AMG - Metrics from AMP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/AMG - Metrics from AMP.png -------------------------------------------------------------------------------- /docs/patterns/images/AMG - Metrics from CloudWatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/AMG - Metrics from CloudWatch.png -------------------------------------------------------------------------------- /docs/patterns/images/Cognito-Kubecost-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Cognito-Kubecost-1.png -------------------------------------------------------------------------------- /docs/patterns/images/Cognito-Kubecost-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Cognito-Kubecost-2.png -------------------------------------------------------------------------------- /docs/patterns/images/Cognito-Signup-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Cognito-Signup-1.png -------------------------------------------------------------------------------- /docs/patterns/images/Cognito-Signup-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Cognito-Signup-2.png -------------------------------------------------------------------------------- /docs/patterns/images/Cognito-Signup-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Cognito-Signup-3.png -------------------------------------------------------------------------------- /docs/patterns/images/ConformitronDashboard1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/ConformitronDashboard1.png -------------------------------------------------------------------------------- /docs/patterns/images/ConformitronDashboard2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/ConformitronDashboard2.png -------------------------------------------------------------------------------- /docs/patterns/images/ConformitronDashboard3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/ConformitronDashboard3.png -------------------------------------------------------------------------------- /docs/patterns/images/CostOptimizationEventBridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/CostOptimizationEventBridge.png -------------------------------------------------------------------------------- /docs/patterns/images/CostOptimizationEventBridge2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/CostOptimizationEventBridge2.png -------------------------------------------------------------------------------- /docs/patterns/images/CostOptimizationEventBridge3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/CostOptimizationEventBridge3.png -------------------------------------------------------------------------------- /docs/patterns/images/CostOptimizationSSM1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/CostOptimizationSSM1.png -------------------------------------------------------------------------------- /docs/patterns/images/CostOptimizationSSM2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/CostOptimizationSSM2.png -------------------------------------------------------------------------------- /docs/patterns/images/Custom-NW-Eni-Console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Custom-NW-Eni-Console.png -------------------------------------------------------------------------------- /docs/patterns/images/Custom-NW-IPv4-Instance-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Custom-NW-IPv4-Instance-view.png -------------------------------------------------------------------------------- /docs/patterns/images/Custom-NW-IPv4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Custom-NW-IPv4.png -------------------------------------------------------------------------------- /docs/patterns/images/Custom-nw-bar-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Custom-nw-bar-chart.png -------------------------------------------------------------------------------- /docs/patterns/images/Explore AMG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Explore AMG.png -------------------------------------------------------------------------------- /docs/patterns/images/Explore CW.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/Explore CW.png -------------------------------------------------------------------------------- /docs/patterns/images/XRAY - Service Map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/XRAY - Service Map.png -------------------------------------------------------------------------------- /docs/patterns/images/XRAY - Traces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/XRAY - Traces.png -------------------------------------------------------------------------------- /docs/patterns/images/amd-add-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/amd-add-on.png -------------------------------------------------------------------------------- /docs/patterns/images/argocd-cc-workloads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/argocd-cc-workloads.png -------------------------------------------------------------------------------- /docs/patterns/images/argocd-cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/argocd-cc.png -------------------------------------------------------------------------------- /docs/patterns/images/arm-add-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/arm-add-on.png -------------------------------------------------------------------------------- /docs/patterns/images/aws_secret_codepipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/aws_secret_codepipeline.png -------------------------------------------------------------------------------- /docs/patterns/images/backstage-console-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/backstage-console-output.png -------------------------------------------------------------------------------- /docs/patterns/images/backstage-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/backstage-diagram.png -------------------------------------------------------------------------------- /docs/patterns/images/backstage-kubectl-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/backstage-kubectl-output.png -------------------------------------------------------------------------------- /docs/patterns/images/backstage-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/backstage-screen.png -------------------------------------------------------------------------------- /docs/patterns/images/codepipeline1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/codepipeline1.png -------------------------------------------------------------------------------- /docs/patterns/images/codepipeline2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/codepipeline2.png -------------------------------------------------------------------------------- /docs/patterns/images/conformitron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/conformitron.png -------------------------------------------------------------------------------- /docs/patterns/images/crossplane-argocd-gitops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/crossplane-argocd-gitops.png -------------------------------------------------------------------------------- /docs/patterns/images/custom-nw-mng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/custom-nw-mng.png -------------------------------------------------------------------------------- /docs/patterns/images/generativeai-showcase-architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/generativeai-showcase-architecture.jpg -------------------------------------------------------------------------------- /docs/patterns/images/generativeai-showcase-demo-output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/generativeai-showcase-demo-output.jpg -------------------------------------------------------------------------------- /docs/patterns/images/gmaestro-config-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/gmaestro-config-file.png -------------------------------------------------------------------------------- /docs/patterns/images/gmaestro-generate-config-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/gmaestro-generate-config-file.png -------------------------------------------------------------------------------- /docs/patterns/images/gmaestro-recommendations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/gmaestro-recommendations.png -------------------------------------------------------------------------------- /docs/patterns/images/instana-agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/instana-agent.png -------------------------------------------------------------------------------- /docs/patterns/images/konveyor-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/konveyor-architecture.png -------------------------------------------------------------------------------- /docs/patterns/images/konveyor-cdk-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/konveyor-cdk-output.png -------------------------------------------------------------------------------- /docs/patterns/images/konveyor-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/konveyor-home.png -------------------------------------------------------------------------------- /docs/patterns/images/konveyor-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/konveyor-login.png -------------------------------------------------------------------------------- /docs/patterns/images/secure-ingress-kubecost-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/secure-ingress-kubecost-new.png -------------------------------------------------------------------------------- /docs/patterns/images/secure-ingress-kubecost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/secure-ingress-kubecost.png -------------------------------------------------------------------------------- /docs/patterns/images/setup_amg-cross-account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/docs/patterns/images/setup_amg-cross-account.png -------------------------------------------------------------------------------- /docs/patterns/kubeflow.md: -------------------------------------------------------------------------------- 1 | # Kubeflow on EKS 2 | The Kubeflow project is dedicated to making deployments of machine learning (ML) workflows on Kubernetes simple, portable and scalable. 3 | Our goal is not to recreate other services, but to provide a straightforward way to deploy best-of-breed open-source systems for ML to diverse infrastructures. 4 | Anywhere you are running Kubernetes, you should be able to run Kubeflow. 5 | 6 | This pattern deploys the following resources: 7 | 8 | - Creates EKS Cluster Control plane with public endpoint (for demo purpose only) with a managed node group 9 | - Deploys supporting add-ons: ClusterAutoScaler, AwsLoadBalancerController, VpcCni, CoreDns, KubeProxy, EbsCsiDriver, CertManagerAddOn, KubeStateMetricsAddOn, PrometheusNodeExporterAddOn, AdotCollectorAddOn, AmpAddOn, 10 | - Deploy Kubeflow on the EKS cluster 11 | 12 | 13 | ## Prerequisites: 14 | 15 | Ensure that you have installed the following tools on your machine. 16 | 17 | 1. [aws cli](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) 18 | 2. [kubectl](https://Kubernetes.io/docs/tasks/tools/) 19 | 3. [cdk](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_install) 20 | 4. [npm](https://docs.npmjs.com/cli/v8/commands/npm-install) 21 | 22 | 23 | 24 | ## Deploy EKS Cluster with Amazon EKS Blueprints for CDK 25 | 26 | Clone the repository 27 | 28 | ```sh 29 | git clone https://github.com/aws-samples/cdk-eks-blueprints-patterns.git 30 | ``` 31 | 32 | Updating npm 33 | 34 | ```sh 35 | npm install -g npm@latest 36 | ``` 37 | 38 | To view patterns and deploy kubeflow pattern 39 | 40 | ```sh 41 | make list 42 | cdk bootstrap 43 | make pattern kubeflow deploy 44 | ``` 45 | 46 | 47 | ## Verify the resources 48 | 49 | 50 | Run update-kubeconfig command. You should be able to get the command from CDK output message. More information can be found at https://aws-quickstart.github.io/cdk-eks-blueprints/getting-started/#cluster-access 51 | ```sh 52 | aws eks update-kubeconfig --name --region --role-arn arn:aws:iam::xxxxxxxxx:role/kubeflow-blueprint-kubeflowblueprintMastersRole0C1-saJBO 53 | ``` 54 | 55 | Let’s verify the resources created by Steps above. 56 | ```sh 57 | kubectl get nodes # Output shows the EKS Managed Node group nodes 58 | 59 | kubectl get ns | kubeflow # Output shows kubeflow namespace 60 | 61 | kubectl get pods --namespace=kubeflow-pipelines # Output shows kubeflow pods 62 | ``` 63 | 64 | 65 | ## Execute Machine learning jobs on Kubeflow 66 | log into Kubeflow pipeline UI by creating a port-forward to the ml-pipeline-ui service
67 | 68 | ```sh 69 | kubectl port-forward svc/ml-pipeline-ui 9000:80 -n =kubeflow-pipelines 70 | 71 | ``` 72 | and open this browser: http://localhost:9000/#/pipelines 73 | more pipeline examples can be found at https://www.kubeflow.org/docs/components/pipelines/legacy-v1/tutorials/ 74 | 75 | 76 | ## Cleanup 77 | 78 | To clean up your EKS Blueprints, run the following commands: 79 | 80 | 81 | ```sh 82 | cdk destroy kubeflow-blueprint 83 | 84 | ``` 85 | 86 | ## Disclaimer 87 | This pattern relies on an open source NPM package eks-blueprints-cdk-kubeflow-ext. Please refer to the package npm site for more information. 88 | https://www.npmjs.com/package/eks-blueprints-cdk-kubeflow-ext 89 | -------------------------------------------------------------------------------- /docs/patterns/observability/existing-eks-apiserver-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/existing-eks-observability-accelerators/existing-eks-apiserver-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/existing-eks-awsnative-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/existing-eks-observability-accelerators/existing-eks-awsnative-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/existing-eks-mixed-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/existing-eks-observability-accelerators/existing-eks-mixed-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/existing-eks-nginx-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/existing-eks-observability-accelerators/existing-eks-nginx-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/existing-eks-opensource-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/existing-eks-observability-accelerators/existing-eks-opensource-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/multi-acc-new-eks-mixed-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/multi-new-eks-observability-accelerators/multi-acc-new-eks-mixed-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-apiserver-opensource-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-apiserver-opensource-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-awsnative-fargate-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-awsnative-fargate-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-gpu-opensource-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-gpu-opensource-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-graviton-opensource-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-graviton-opensource-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-java-opensource-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-java-opensource-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-mixed-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-mixed-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-native.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-awsnative-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-nginx-opensource-observability.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-nginx-opensource-observability.md', '') }} -------------------------------------------------------------------------------- /docs/patterns/observability/single-new-eks-opensource.md: -------------------------------------------------------------------------------- 1 | {{ external_markdown('https://raw.githubusercontent.com/aws-observability/cdk-aws-observability-accelerator/main/docs/patterns/single-new-eks-observability-accelerators/single-new-eks-opensource-observability.md', '') }} -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ['/test'], 3 | testMatch: ['**/*.test.ts'], 4 | transform: { 5 | '^.+\\.tsx?$': 'ts-jest' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /lib/amp-monitoring/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | 3 | // Blueprints Lib 4 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 5 | import * as amp from 'aws-cdk-lib/aws-aps'; 6 | 7 | // Team implementations 8 | import * as team from '../teams/multi-account-monitoring'; 9 | 10 | /** 11 | * Demonstrates how to leverage more than one node group along with Fargate profiles. 12 | */ 13 | export default class AmpMonitoringConstruct { 14 | build(scope: Construct, id: string, account?: string, region?: string ) { 15 | // Setup platform team 16 | const accountID = account ?? process.env.CDK_DEFAULT_ACCOUNT! ; 17 | const awsRegion = region ?? process.env.CDK_DEFAULT_REGION! ; 18 | 19 | const stackID = `${id}-blueprint`; 20 | this.create(scope, accountID, awsRegion) 21 | .build(scope, stackID); 22 | } 23 | 24 | create(scope: Construct, account?: string, region?: string ) { 25 | // Setup platform team 26 | const accountID = account ?? process.env.CDK_DEFAULT_ACCOUNT! ; 27 | const awsRegion = region ?? process.env.CDK_DEFAULT_REGION! ; 28 | const ampWorkspaceName = "multi-account-monitoring"; 29 | const ampPrometheusEndpoint = (blueprints.getNamedResource(ampWorkspaceName) as unknown as amp.CfnWorkspace).attrPrometheusEndpoint; 30 | 31 | return blueprints.EksBlueprint.builder() 32 | .account(accountID) 33 | .region(awsRegion) 34 | .version('auto') 35 | .resourceProvider(ampWorkspaceName, new blueprints.CreateAmpProvider(ampWorkspaceName, ampWorkspaceName)) 36 | .addOns( 37 | new blueprints.AwsLoadBalancerControllerAddOn, 38 | new blueprints.CertManagerAddOn, 39 | new blueprints.KubeStateMetricsAddOn, 40 | new blueprints.PrometheusNodeExporterAddOn, 41 | new blueprints.AdotCollectorAddOn, 42 | new blueprints.addons.AmpAddOn({ 43 | ampPrometheusEndpoint: ampPrometheusEndpoint, 44 | }), 45 | new blueprints.XrayAdotAddOn, 46 | new blueprints.NginxAddOn, 47 | new blueprints.ClusterAutoScalerAddOn, 48 | new blueprints.SecretsStoreAddOn 49 | ) 50 | .teams(new team.TeamGeordi, new team.CorePlatformTeam); 51 | } 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /lib/argo-config-managent/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/cdk-eks-blueprints-patterns/7af3d9f96bc62755082b07482b9582f8765f3919/lib/argo-config-managent/index.ts -------------------------------------------------------------------------------- /lib/aws-batch-on-eks-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { BatchEksTeam } from '@aws-quickstart/eks-blueprints'; 4 | import { PolicyStatement, Effect } from 'aws-cdk-lib/aws-iam'; 5 | 6 | export default class BatchOnEKSConstruct { 7 | build(scope: Construct, id: string, teams: BatchEksTeam[]) { 8 | 9 | const batchIamPolicy = new PolicyStatement({ 10 | effect: Effect.ALLOW, 11 | actions: [ 12 | "cloudwatch:PutMetricData", 13 | "ec2:DescribeVolumes", 14 | "ec2:DescribeTags", 15 | "logs:PutLogEvents", 16 | "logs:DescribeLogStreams", 17 | "logs:DescribeLogGroups", 18 | "logs:CreateLogStream", 19 | "logs:CreateLogGroup" 20 | ], 21 | resources: ["*"], 22 | }); 23 | const stackID = `${id}-blueprint`; 24 | blueprints.EksBlueprint.builder() 25 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 26 | .region(process.env.CDK_DEFAULT_REGION!) 27 | .addOns( 28 | new blueprints.AwsBatchAddOn(), 29 | new blueprints.AwsForFluentBitAddOn({ 30 | iamPolicies:[batchIamPolicy], 31 | values: { 32 | cloudWatch: { 33 | enabled: true, 34 | region: process.env.CDK_DEFAULT_REGION!, 35 | logGroupName: '/aws/batch/batch-team-a-logs' 36 | }, 37 | tolerations: [{ 38 | "key": "batch.amazonaws.com/batch-node", "operator": "Exists" 39 | }] 40 | } 41 | }) 42 | ) 43 | .teams(...teams) 44 | .version('auto') 45 | .build(scope, stackID); 46 | } 47 | } -------------------------------------------------------------------------------- /lib/backstage-construct/database-credentials.ts: -------------------------------------------------------------------------------- 1 | import { Secret,ISecret } from 'aws-cdk-lib/aws-secretsmanager'; 2 | import { ResourceContext, ResourceProvider } from '@aws-quickstart/eks-blueprints'; 3 | 4 | export interface DatabaseInstanceCredentialsProviderProps { 5 | /** 6 | * The username for the database secret 7 | */ 8 | username: string, 9 | } 10 | 11 | export class DatabaseInstanceCredentialsProvider implements ResourceProvider { 12 | readonly props: DatabaseInstanceCredentialsProviderProps; 13 | 14 | constructor(props: DatabaseInstanceCredentialsProviderProps) { 15 | this.props = props; 16 | } 17 | 18 | provide(context: ResourceContext): ISecret { 19 | return new Secret(context.scope, "database-secret", { 20 | generateSecretString: { 21 | secretStringTemplate: JSON.stringify({ 22 | username: this.props.username, 23 | }), 24 | excludePunctuation: true, 25 | includeSpace: false, 26 | generateStringKey: "password" 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/backstage-construct/rds-database-instance.ts: -------------------------------------------------------------------------------- 1 | import * as rds from 'aws-cdk-lib/aws-rds'; 2 | import { ISecret } from 'aws-cdk-lib/aws-secretsmanager'; 3 | import { IVpc, Peer, SecurityGroup, SubnetType, Port } from 'aws-cdk-lib/aws-ec2'; 4 | import { ResourceContext, ResourceProvider } from '@aws-quickstart/eks-blueprints'; 5 | 6 | export interface DatabaseInstanceProviderProps { 7 | /** 8 | * Name of the VPC registered as a resource 9 | */ 10 | vpcResourceName: string, 11 | 12 | /** 13 | * Port to be used by the database 14 | */ 15 | databaseInstancePort: number, 16 | 17 | /** 18 | * The name of the Secret registered as a resource 19 | */ 20 | databaseSecretResourceName: string 21 | } 22 | 23 | export class DatabaseInstanceProvider implements ResourceProvider { 24 | readonly props: DatabaseInstanceProviderProps; 25 | 26 | constructor(props: DatabaseInstanceProviderProps) { 27 | this.props = props; 28 | } 29 | 30 | provide(context: ResourceContext): rds.IDatabaseInstance { 31 | const id = context.scope.node.id; 32 | 33 | const databaseCredentialsSecret = context.get(this.props.databaseSecretResourceName); 34 | if (databaseCredentialsSecret === undefined) { 35 | throw new Error("Database Secret not found in context"); 36 | } 37 | 38 | const vpc = context.get(this.props.vpcResourceName); 39 | if (vpc === undefined) { 40 | throw new Error("VPC not found in context"); 41 | } 42 | 43 | const dbSecurityGroup = new SecurityGroup(context.scope, id+"-security-group", { 44 | vpc: vpc 45 | }); 46 | 47 | dbSecurityGroup.addIngressRule(Peer.ipv4(vpc.vpcCidrBlock), Port.tcp(this.props.databaseInstancePort), "Connect from within VPC"); 48 | 49 | const rdsConfig: rds.DatabaseInstanceProps = { 50 | engine: rds.DatabaseInstanceEngine.POSTGRES, 51 | vpc, 52 | vpcSubnets: { 53 | subnetType: SubnetType.PRIVATE_WITH_EGRESS, 54 | }, 55 | securityGroups: [dbSecurityGroup], 56 | credentials: rds.Credentials.fromSecret(databaseCredentialsSecret), 57 | }; 58 | 59 | return new rds.DatabaseInstance(context.scope, id+"-database-instance", rdsConfig); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/bottlerocket-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as eks from 'aws-cdk-lib/aws-eks'; 2 | import { Construct } from 'constructs'; 3 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 4 | import * as team from '../teams'; 5 | 6 | /** 7 | * Bottlerocket pattern shows how to specify the OS for the node group 8 | * and leverage container-optimized Bottlerocket OS: https://aws.amazon.com/bottlerocket/ 9 | */ 10 | export default class BottlerocketConstruct { 11 | 12 | build(scope: Construct, id: string) { 13 | 14 | const stackID = `${id}-blueprint`; 15 | const accountID = process.env.CDK_DEFAULT_ACCOUNT!; 16 | const platformTeam = new team.TeamPlatform(accountID); 17 | 18 | const clusterProvider = new blueprints.MngClusterProvider({ 19 | version: eks.KubernetesVersion.V1_25, 20 | amiType: eks.NodegroupAmiType.BOTTLEROCKET_X86_64 21 | }); 22 | 23 | blueprints.EksBlueprint.builder() 24 | .account(accountID) 25 | .region('us-east-1') 26 | .clusterProvider(clusterProvider) 27 | .addOns( 28 | new blueprints.AwsLoadBalancerControllerAddOn, 29 | new blueprints.CertManagerAddOn, 30 | new blueprints.AdotCollectorAddOn, 31 | new blueprints.AppMeshAddOn, 32 | new blueprints.ClusterAutoScalerAddOn, 33 | new blueprints.NginxAddOn, 34 | new blueprints.ArgoCDAddOn, 35 | new blueprints.CalicoOperatorAddOn, 36 | new blueprints.MetricsServerAddOn, 37 | new blueprints.CloudWatchAdotAddOn, 38 | new blueprints.SecretsStoreAddOn 39 | ) 40 | .teams(platformTeam) 41 | .build(scope, stackID); 42 | } 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/cloudwatch-monitoring/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | 3 | // Blueprints Lib 4 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 5 | import { cloudWatchDeploymentMode } from '@aws-quickstart/eks-blueprints'; 6 | 7 | // Team implementation 8 | import * as team from '../teams/multi-account-monitoring'; 9 | 10 | /** 11 | * Demonstration of how to use CloudWatch Adot add-on. 12 | */ 13 | export default class CloudWatchMonitoringConstruct { 14 | 15 | build(scope: Construct, id: string, account?: string, region?: string ) { 16 | // Setup platform team 17 | const accountID = account ?? process.env.CDK_DEFAULT_ACCOUNT! ; 18 | const awsRegion = region ?? process.env.CDK_DEFAULT_REGION! ; 19 | 20 | const stackID = `${id}-blueprint`; 21 | this.create(scope, accountID, awsRegion) 22 | .build(scope, stackID); 23 | } 24 | 25 | create(scope: Construct, account?: string, region?: string ) { 26 | // Setup platform team 27 | const accountID = account ?? process.env.CDK_DEFAULT_ACCOUNT! ; 28 | const awsRegion = region ?? process.env.CDK_DEFAULT_REGION! ; 29 | 30 | const cloudWatchAdotAddOn = new blueprints.addons.CloudWatchAdotAddOn({ 31 | deploymentMode: cloudWatchDeploymentMode.DEPLOYMENT, 32 | namespace: 'default', 33 | name: 'adot-collector-cloudwatch', 34 | metricsNameSelectors: ['apiserver_request_.*', 'container_memory_.*', 'container_threads', 'otelcol_process_.*', 'ho11y*'], 35 | podLabelRegex: 'frontend|downstream(.*)' 36 | }); 37 | 38 | return blueprints.EksBlueprint.builder() 39 | .account(accountID) 40 | .region(awsRegion) 41 | .version('auto') 42 | .addOns( 43 | new blueprints.AwsLoadBalancerControllerAddOn, 44 | new blueprints.CertManagerAddOn, 45 | new blueprints.KubeStateMetricsAddOn, 46 | new blueprints.PrometheusNodeExporterAddOn, 47 | new blueprints.AdotCollectorAddOn, 48 | cloudWatchAdotAddOn, 49 | new blueprints.XrayAdotAddOn, 50 | new blueprints.NginxAddOn, 51 | new blueprints.ClusterAutoScalerAddOn, 52 | new blueprints.SecretsStoreAddOn 53 | ) 54 | .teams(new team.TeamGeordi, new team.CorePlatformTeam); 55 | } 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /lib/common/construct-utils.ts: -------------------------------------------------------------------------------- 1 | import { utils } from "@aws-quickstart/eks-blueprints"; 2 | import { HelmAddOn } from '@aws-quickstart/eks-blueprints'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | 5 | export const logger = utils.logger; 6 | 7 | export function errorHandler(app: cdk.App, message: string, error?: Error) { 8 | logger.info(message); 9 | if(error){ 10 | logger.error(error.name, error.message, error.stack); 11 | } 12 | new EmptyStack(app); 13 | } 14 | 15 | export function configureApp(logLevel? : number): cdk.App { 16 | logger.settings.minLevel = logLevel ?? 2; // debug., 3 info 17 | logger.settings.hideLogPositionForProduction = true; 18 | utils.userLog.info("=== Run make compile before each run, if any code modification was made. === \n\n"); 19 | 20 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 21 | const region = process.env.CDK_DEFAULT_REGION!; 22 | 23 | HelmAddOn.validateHelmVersions = true; 24 | 25 | return new cdk.App({context: { account, region }}); 26 | } 27 | 28 | export async function prevalidateSecrets(pattern: string, region?: string, ...secrets: string[]) { 29 | for(let secret of secrets) { 30 | try { 31 | await utils.validateSecret(secret, region ?? process.env.CDK_DEFAULT_REGION!); 32 | } 33 | catch(error) { 34 | throw new Error(`${secret} secret must be setup for the ${pattern} pattern to work`); 35 | } 36 | } 37 | } 38 | 39 | export class EmptyStack extends cdk.Stack { 40 | constructor(scope: cdk.App, ...message: string[]) { 41 | super(scope, "empty-error-stack"); 42 | if(message) { 43 | message.forEach(m => logger.info(m)); 44 | } 45 | } 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /lib/common/default-main.ts: -------------------------------------------------------------------------------- 1 | import { EmptyStack, configureApp } from "./construct-utils"; 2 | 3 | const app = configureApp(); 4 | 5 | new EmptyStack(app, "To work with patterns use:", 6 | "$ make list # to list all patterns", 7 | "$ make pattern ", 8 | "Example:", 9 | "$ make pattern fargate deploy"); -------------------------------------------------------------------------------- /lib/crossplane-argocd-gitops/custom-addons/crossplane-helm-provider-addon.ts: -------------------------------------------------------------------------------- 1 | import 'source-map-support/register'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import * as eks from "aws-cdk-lib/aws-eks"; 4 | import { Construct } from 'constructs'; 5 | import { dependable } from '@aws-quickstart/eks-blueprints/dist/utils'; 6 | import { UpboundCrossplaneAddOn } from './upbound-crossplane-addon'; 7 | 8 | export class CrossplaneHelmProviderAddon implements blueprints.ClusterAddOn { 9 | id?: string | undefined; 10 | readonly helmProviderVersion: string; 11 | constructor(helmProviderVersion: string) { 12 | this.helmProviderVersion = helmProviderVersion; 13 | } 14 | 15 | @dependable(UpboundCrossplaneAddOn.name) 16 | deploy(clusterInfo: blueprints.ClusterInfo): void | Promise { 17 | const cluster = clusterInfo.cluster; 18 | 19 | const roleBinding = { 20 | apiVersion: "rbac.authorization.k8s.io/v1", 21 | kind: "ClusterRoleBinding", 22 | metadata: { 23 | name: "helm-provider" 24 | }, 25 | subjects: [ 26 | { 27 | kind: "ServiceAccount", 28 | name: "helm-provider", 29 | namespace: "upbound-system" 30 | } 31 | ], 32 | roleRef: { 33 | kind: "ClusterRole", 34 | name: "cluster-admin", 35 | apiGroup: "rbac.authorization.k8s.io" 36 | } 37 | }; 38 | 39 | const runtimeConfig = { 40 | apiVersion: "pkg.crossplane.io/v1beta1", 41 | kind: "DeploymentRuntimeConfig", 42 | metadata: { 43 | name: "helm-runtime-config" 44 | }, 45 | spec: { 46 | deploymentTemplate: { 47 | spec: { 48 | replicas: 1, 49 | selector: {}, 50 | template: {} 51 | } 52 | }, 53 | serviceAccountTemplate: { 54 | metadata: { name: "helm-provider" } 55 | } 56 | } 57 | }; 58 | 59 | const provider = { 60 | apiVersion: "pkg.crossplane.io/v1", 61 | kind: "Provider", 62 | metadata: { name: "helm-provider" }, 63 | spec: { 64 | package: 'xpkg.upbound.io/crossplane-contrib/provider-helm:'+this.helmProviderVersion, 65 | runtimeConfigRef: { 66 | name: "helm-runtime-config" 67 | } 68 | } 69 | }; 70 | 71 | const runtimeHelmConfig = new eks.KubernetesManifest(clusterInfo.cluster.stack, "runtimeHelmConfig", { 72 | cluster: cluster, 73 | manifest: [roleBinding, runtimeConfig] 74 | }); 75 | 76 | const awsHelmProvider = new eks.KubernetesManifest(clusterInfo.cluster.stack, "providerHelmResource", { 77 | cluster: cluster, 78 | manifest: [provider] 79 | }); 80 | 81 | awsHelmProvider.node.addDependency(runtimeHelmConfig); 82 | return Promise.resolve(runtimeHelmConfig); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/crossplane-argocd-gitops/custom-addons/crossplane-k8s-provider-addon.ts: -------------------------------------------------------------------------------- 1 | import 'source-map-support/register'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import * as eks from "aws-cdk-lib/aws-eks"; 4 | import { Construct } from 'constructs'; 5 | import { dependable } from '@aws-quickstart/eks-blueprints/dist/utils'; 6 | import { UpboundCrossplaneAddOn } from './upbound-crossplane-addon'; 7 | 8 | export class CrossplaneK8sProviderAddon implements blueprints.ClusterAddOn { 9 | id?: string | undefined; 10 | readonly k8sProviderVersion: string; 11 | constructor(k8sProviderVersion: string) { 12 | this.k8sProviderVersion = k8sProviderVersion; 13 | } 14 | 15 | @dependable(UpboundCrossplaneAddOn.name) 16 | deploy(clusterInfo: blueprints.ClusterInfo): void | Promise { 17 | const cluster = clusterInfo.cluster; 18 | 19 | const roleBinding = { 20 | apiVersion: "rbac.authorization.k8s.io/v1", 21 | kind: "ClusterRoleBinding", 22 | metadata: { name: "kubernetes-provider" }, 23 | subjects: [ 24 | { 25 | kind: "ServiceAccount", 26 | name: "kubernetes-provider", 27 | namespace: "upbound-system" 28 | } 29 | ], 30 | roleRef: { 31 | kind: "ClusterRole", 32 | name: "cluster-admin", 33 | apiGroup: "rbac.authorization.k8s.io" 34 | } 35 | }; 36 | 37 | const runtimeConfig = { 38 | apiVersion: "pkg.crossplane.io/v1beta1", 39 | kind: "DeploymentRuntimeConfig", 40 | metadata: { 41 | name: "kubernetes-runtime-config" 42 | }, 43 | spec: { 44 | deploymentTemplate: { 45 | spec: { 46 | replicas: 1, 47 | selector: {}, 48 | template: {} 49 | } 50 | }, 51 | serviceAccountTemplate: { 52 | metadata: { name: "kubernetes-provider" } 53 | } 54 | } 55 | }; 56 | 57 | const providerK8sResource = { 58 | apiVersion: "pkg.crossplane.io/v1", 59 | kind: "Provider", 60 | metadata: { name: "kubernetes-provider" }, 61 | spec: { 62 | package: 'xpkg.upbound.io/crossplane-contrib/provider-kubernetes:'+this.k8sProviderVersion, 63 | runtimeConfigRef: { 64 | name: "kubernetes-runtime-config" 65 | } 66 | } 67 | }; 68 | 69 | const runtimeK8sConfig = new eks.KubernetesManifest(clusterInfo.cluster.stack, "runtimeK8sConfig", { 70 | cluster: cluster, 71 | manifest: [roleBinding, runtimeConfig] 72 | }); 73 | 74 | const awsK8sProvider = new eks.KubernetesManifest(clusterInfo.cluster.stack, "awsK8sProvider", { 75 | cluster: cluster, 76 | manifest: [providerK8sResource] 77 | }); 78 | 79 | awsK8sProvider.node.addDependency(runtimeK8sConfig); 80 | 81 | return Promise.resolve(runtimeK8sConfig); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/crossplane-argocd-gitops/custom-addons/custom-iam-role-creator.ts: -------------------------------------------------------------------------------- 1 | 2 | import * as iam from 'aws-cdk-lib/aws-iam'; 3 | import { IManagedPolicy } from 'aws-cdk-lib/aws-iam'; 4 | 5 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 6 | 7 | export class CreateNamedRoleProvider implements blueprints.ResourceProvider { 8 | 9 | /** 10 | * Constructor to create role provider. 11 | * @param roleId role id 12 | * @param assumedBy @example new iam.ServicePrincipal('ec2.amazonaws.com') 13 | * @param policies 14 | */ 15 | constructor(private roleId: string, private roleName: string, private assumedBy: iam.IPrincipal, private policies?: IManagedPolicy[]){} 16 | 17 | provide(context: blueprints.ResourceContext): iam.Role { 18 | return new iam.Role(context.scope, this.roleId, { 19 | assumedBy: this.assumedBy, 20 | managedPolicies: this.policies, 21 | roleName: this.roleName 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/crossplane-argocd-gitops/custom-addons/upbound-crossplane-addon.ts: -------------------------------------------------------------------------------- 1 | import 'source-map-support/register'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { Construct } from 'constructs'; 4 | import { Values } from "@aws-quickstart/eks-blueprints/dist/spi"; 5 | import { merge } from "ts-deepmerge"; 6 | import { createNamespace } from '@aws-quickstart/eks-blueprints/dist/utils'; 7 | import { Policy, PolicyDocument} from 'aws-cdk-lib/aws-iam'; 8 | import * as cdk from 'aws-cdk-lib'; 9 | 10 | /** 11 | * User provided options for the Helm Chart 12 | */ 13 | export interface UpboundCrossplaneAddOnProps extends blueprints.HelmAddOnUserProps { 14 | /** 15 | * To Create Namespace using CDK 16 | */ 17 | createNamespace?: boolean; 18 | } 19 | 20 | const defaultProps: blueprints.HelmAddOnProps = { 21 | name: 'uxp', 22 | release: 'blueprints-addon-uxp', 23 | namespace: 'upbound-system', 24 | chart: 'universal-crossplane', 25 | version: '1.14.5-up.1', 26 | repository: 'https://charts.upbound.io/stable', 27 | values: {}, 28 | }; 29 | 30 | export class UpboundCrossplaneAddOn extends blueprints.HelmAddOn { 31 | 32 | readonly options: UpboundCrossplaneAddOnProps; 33 | 34 | constructor( props?: UpboundCrossplaneAddOnProps) { 35 | super({...defaultProps, ...props}); 36 | 37 | this.options = this.props as UpboundCrossplaneAddOnProps; 38 | } 39 | 40 | deploy(clusterInfo: blueprints.ClusterInfo): void | Promise { 41 | const cluster = clusterInfo.cluster; 42 | 43 | // Create the `upbound-system` namespace. 44 | const ns = createNamespace(this.options.namespace!, cluster, true); 45 | 46 | // Create the CrossPlane AWS Provider IRSA. 47 | const serviceAccountName = "provider-aws"; 48 | const sa = cluster.addServiceAccount(serviceAccountName, { 49 | name: serviceAccountName, 50 | namespace: this.options.namespace!, 51 | }); 52 | sa.node.addDependency(ns); 53 | sa.role.attachInlinePolicy(new Policy(cluster.stack, 'eks-connect-policy', { 54 | document: PolicyDocument.fromJson({ 55 | "Version": "2012-10-17", 56 | "Statement": [ 57 | { 58 | "Effect": "Allow", 59 | "Action": ["sts:AssumeRole"], 60 | "Resource": `arn:aws:iam::${cluster.stack.account}:role/eks-workload-connector-role` 61 | }, 62 | { 63 | "Effect": "Allow", 64 | "Action": ["eks:*"], 65 | "Resource": `*` 66 | } 67 | ] 68 | })})); 69 | 70 | clusterInfo.addAddOnContext(UpboundCrossplaneAddOn.name, { 71 | arn: sa.role.roleArn 72 | }); 73 | 74 | new cdk.CfnOutput(cluster.stack, 'providerawssaiamrole', 75 | { 76 | value: sa.role.roleArn, 77 | description: 'provider AWS IAM role', 78 | exportName : 'providerawssaiamrole' 79 | }); 80 | 81 | let values: Values = this.options.values ?? {}; 82 | values = merge(values, values); 83 | 84 | const chart = this.addHelmChart(clusterInfo, values, false, true); 85 | chart.node.addDependency(sa); 86 | return Promise.resolve(chart); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/crossplane-argocd-gitops/management-cluster-builder.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import * as eks from 'aws-cdk-lib/aws-eks'; 4 | import { ObservabilityBuilder } from '@aws-quickstart/eks-blueprints'; 5 | import { UpboundCrossplaneAddOn } from './custom-addons/upbound-crossplane-addon'; 6 | import { UpboundCrossplaneEKSProviderAddOn } from './custom-addons/upbound-crossplane-eks-provider-addon'; 7 | import { CrossplaneK8sProviderAddon } from './custom-addons/crossplane-k8s-provider-addon'; 8 | import { CrossplaneHelmProviderAddon } from './custom-addons/crossplane-helm-provider-addon'; 9 | // import { TeamSpoc } from './custom-addons/secret-provider-secret'; 10 | 11 | 12 | const gitUrl = 'https://github.com/ajpaws/eks-blueprints-workloads.git'; 13 | const k8sProviderVersion = 'v0.13.0'; 14 | const UpboundEKSProviderVersion = 'v1.1.0'; 15 | const helmProviderVersion = 'v0.19.0'; 16 | 17 | 18 | export default class ManagementClusterBuilder { 19 | readonly account: string; 20 | readonly region: string; 21 | 22 | constructor(account: string,region: string) { 23 | this.account = account; 24 | this.region = region; 25 | } 26 | 27 | create(scope: Construct, id: string, mngProps: blueprints.MngClusterProviderProps) { 28 | blueprints.HelmAddOn.validateHelmVersions = false; 29 | 30 | const addOns: Array = [ 31 | new blueprints.addons.ExternalsSecretsAddOn, 32 | new UpboundCrossplaneAddOn, 33 | new UpboundCrossplaneEKSProviderAddOn(UpboundEKSProviderVersion), 34 | new CrossplaneK8sProviderAddon(k8sProviderVersion), 35 | new CrossplaneHelmProviderAddon(helmProviderVersion), 36 | new blueprints.SecretsStoreAddOn, 37 | new blueprints.ArgoCDAddOn({ 38 | bootstrapRepo: { 39 | repoUrl: gitUrl, 40 | path: `./crossplane-argocd-gitops/envs/dev`, 41 | targetRevision: 'main' 42 | }, 43 | bootstrapValues: { 44 | clusterA: { 45 | clusterName: 'workload-amd-1-29-blueprint' 46 | }, 47 | clusterB: { 48 | clusterName: 'workload-arm-1-29-blueprint' 49 | }, 50 | common: { 51 | providerConfigAWSName: 'common-provider-config-aws', 52 | eksConnectorRoleName: 'eks-workload-connector-role', 53 | accountId: `${process.env.CDK_DEFAULT_ACCOUNT}`, 54 | region: `${process.env.CDK_DEFAULT_REGION}`, 55 | crossplaneNamespace: 'upbound-system' 56 | } 57 | }, 58 | }), 59 | ]; 60 | 61 | const clusterProvider = new blueprints.MngClusterProvider({...mngProps, 62 | clusterName:id 63 | }); 64 | 65 | return ObservabilityBuilder.builder() 66 | .clusterProvider(clusterProvider) 67 | .version(eks.KubernetesVersion.V1_29) 68 | .enableNativePatternAddOns() 69 | .enableControlPlaneLogging() 70 | .addOns(...addOns); 71 | } 72 | } 73 | 74 | 75 | -------------------------------------------------------------------------------- /lib/crossplane-argocd-gitops/multi-cluster-options.ts: -------------------------------------------------------------------------------- 1 | import {CapacityType, KubernetesVersion} from "aws-cdk-lib/aws-eks"; 2 | import * as ec2 from "aws-cdk-lib/aws-ec2"; 3 | import * as eks from "aws-cdk-lib/aws-eks"; 4 | 5 | export const K8S_VERSIONS_PROD : KubernetesVersion[] = [KubernetesVersion.V1_27, KubernetesVersion.V1_28, KubernetesVersion.V1_29]; 6 | 7 | export const K8S_VERSIONS_DEV : KubernetesVersion[] = [ KubernetesVersion.of("1.29")]; 8 | 9 | 10 | export interface MultiClusterOptions { 11 | readonly account: string; 12 | readonly region: string; 13 | minSize?: number; 14 | maxSize?: number; 15 | desiredSize?: number; 16 | gitHubSecret?: string; 17 | nodeGroupCapacityType: CapacityType; 18 | instanceTypes?: ec2.InstanceType[]; 19 | amiType?: eks.NodegroupAmiType; 20 | k8sVersions: KubernetesVersion[]; 21 | } 22 | -------------------------------------------------------------------------------- /lib/custom-networking-ipv4-construct/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import { Construct } from 'constructs'; 3 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 4 | import * as ec2 from "aws-cdk-lib/aws-ec2"; 5 | import { KubernetesVersion, NodegroupAmiType } from 'aws-cdk-lib/aws-eks'; 6 | import * as eks from "aws-cdk-lib/aws-eks"; 7 | 8 | export default class CustomNetworkingIPv4Construct { 9 | constructor(scope: Construct, id: string) { 10 | const stackId = `${id}-blueprint`; 11 | 12 | const mngProps = { 13 | version: KubernetesVersion.V1_25, 14 | endpointAccess: eks.EndpointAccess.PUBLIC_AND_PRIVATE, 15 | instanceTypes: [new ec2.InstanceType('m5.large')], 16 | amiType: NodegroupAmiType.AL2_X86_64, 17 | desiredSize: 2, 18 | maxSize: 3, 19 | vpcSubnets: [{ subnetType: ec2.SubnetType.PUBLIC }] 20 | }; 21 | 22 | 23 | const clusterProvider = new blueprints.MngClusterProvider(mngProps); 24 | 25 | blueprints.EksBlueprint.builder() 26 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 27 | .region(process.env.CDK_DEFAULT_REGION) 28 | .addOns(new blueprints.VpcCniAddOn({ 29 | customNetworkingConfig: { 30 | subnets: [ 31 | blueprints.getNamedResource("secondary-cidr-subnet-0"), 32 | blueprints.getNamedResource("secondary-cidr-subnet-1"), 33 | blueprints.getNamedResource("secondary-cidr-subnet-2"), 34 | ] 35 | }, 36 | awsVpcK8sCniCustomNetworkCfg: true, 37 | eniConfigLabelDef: 'topology.kubernetes.io/zone' 38 | }), 39 | new blueprints.AwsLoadBalancerControllerAddOn(), 40 | new blueprints.CoreDnsAddOn(), 41 | new blueprints.KubeProxyAddOn(), 42 | ) 43 | .resourceProvider(blueprints.GlobalResources.Vpc, new blueprints.VpcProvider(undefined, { 44 | primaryCidr: "10.2.0.0/16", 45 | secondaryCidr: "100.64.0.0/16", 46 | secondarySubnetCidrs: ["100.64.0.0/24", "100.64.1.0/24", "100.64.2.0/24"] 47 | })) 48 | 49 | .clusterProvider(clusterProvider) 50 | .build(scope, stackId); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/datadog-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { DatadogAddOn } from '@datadog/datadog-eks-blueprints-addon'; 4 | import { prevalidateSecrets } from '../common/construct-utils'; 5 | 6 | const SECRET_API_KEY = 'datadog-api-key'; 7 | 8 | export default class DatadogConstruct { 9 | 10 | async buildAsync(scope: Construct, id: string) { 11 | 12 | await prevalidateSecrets(DatadogConstruct.name, process.env.CDK_DEFAULT_REGION!, SECRET_API_KEY); 13 | 14 | const stackID = `${id}-blueprint`; 15 | 16 | const addOns: Array = [ 17 | new DatadogAddOn({ 18 | apiKeyAWSSecret: SECRET_API_KEY 19 | }) 20 | ]; 21 | 22 | blueprints.EksBlueprint.builder() 23 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 24 | .region(process.env.CDK_DEFAULT_REGION!) 25 | .version('auto') 26 | .addOns(...addOns) 27 | .build(scope, stackID); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/dynatrace-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { EksBlueprint } from '@aws-quickstart/eks-blueprints'; 2 | import { DynatraceAddOn } from '@dynatrace/dynatrace-eks-blueprints-addon'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | import { prevalidateSecrets } from '../common/construct-utils'; 5 | 6 | export default class DynatraceOperatorConstruct { 7 | 8 | async buildAsync(scope: cdk.App, id: string) { 9 | await prevalidateSecrets(DynatraceOperatorConstruct.name, undefined, 'dynatrace-tokens'); 10 | // AddOns for the cluster 11 | const stackId = `${id}-blueprint`; 12 | 13 | const DynatraceOperator = new DynatraceAddOn(); 14 | 15 | EksBlueprint.builder() 16 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 17 | .region(process.env.CDK_DEFAULT_REGION) 18 | .version('auto') 19 | .addOns(DynatraceOperator) 20 | .build(scope, stackId); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /lib/emr-eks/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | EksBlueprint, 3 | AwsLoadBalancerControllerAddOn, 4 | CertManagerAddOn, 5 | ClusterAutoScalerAddOn, 6 | CoreDnsAddOn, 7 | EbsCsiDriverAddOn, 8 | EmrEksAddOn, 9 | EmrEksTeam, 10 | KubeProxyAddOn, 11 | MetricsServerAddOn, 12 | VpcCniAddOn 13 | } from '@aws-quickstart/eks-blueprints'; 14 | 15 | import * as cdk from 'aws-cdk-lib'; 16 | 17 | export default class EmrEksConstruct { 18 | 19 | build(scope: cdk.App, id: string, teams: EmrEksTeam[]) { 20 | 21 | const stackId = `${id}-blueprint`; 22 | 23 | EksBlueprint.builder().addOns( 24 | new AwsLoadBalancerControllerAddOn, 25 | new VpcCniAddOn(), 26 | new CoreDnsAddOn(), 27 | new MetricsServerAddOn, 28 | new ClusterAutoScalerAddOn, 29 | new CertManagerAddOn, 30 | new EbsCsiDriverAddOn, 31 | new KubeProxyAddOn, 32 | new EmrEksAddOn 33 | ).teams( 34 | ...teams 35 | ) 36 | .version('auto') 37 | .build(scope, stackId); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /lib/fargate-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as eks from 'aws-cdk-lib/aws-eks'; 3 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 4 | import * as team from '../teams'; 5 | 6 | /** 7 | * Demonstrates how to use Fargate cluster provider. 8 | * Along with the specified profiles, Fargate cluster automatically creates 9 | * a default profile with selectors for the default namespace. 10 | */ 11 | export default class FargateConstruct { 12 | constructor(scope: Construct, id: string) { 13 | // Setup platform team 14 | const accountID = process.env.CDK_DEFAULT_ACCOUNT!; 15 | const platformTeam = new team.TeamPlatform(accountID); 16 | 17 | const fargateProfiles: Map = new Map([ 18 | ["team1", { selectors: [{ namespace: "team1" }] }] 19 | ]); 20 | 21 | const stackID = `${id}-blueprint`; 22 | const clusterProvider = new blueprints.FargateClusterProvider({ 23 | fargateProfiles, 24 | version: eks.KubernetesVersion.V1_25 25 | }); 26 | 27 | blueprints.EksBlueprint.builder() 28 | .account(accountID) 29 | .clusterProvider(clusterProvider) 30 | .teams(platformTeam) 31 | .addOns( 32 | new blueprints.VpcCniAddOn(), 33 | new blueprints.AwsLoadBalancerControllerAddOn, 34 | new blueprints.AppMeshAddOn, 35 | new blueprints.NginxAddOn, 36 | new blueprints.ArgoCDAddOn, 37 | new blueprints.MetricsServerAddOn 38 | ) 39 | .build(scope, stackID); 40 | } 41 | } 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /lib/generative-ai-showcase/deployment/showcase-deployment.ytpl: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: bedrock-showcase-model 5 | namespace: "{{namespace}}" 6 | labels: 7 | app: bedrock-showcase-model 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: bedrock-showcase-model 13 | template: 14 | metadata: 15 | labels: 16 | app: bedrock-showcase-model 17 | spec: 18 | serviceAccountName: bedrock-service-account 19 | containers: 20 | - name: bedrock-showcase-model 21 | image: "{{imageName}}:{{imageTag}}" 22 | imagePullPolicy: IfNotPresent 23 | env: 24 | - name: BWB_ENDPOINT_URL 25 | value: "https://bedrock.{{region}}.amazonaws.com/" 26 | - name: BWB_PROFILE_NAME 27 | value: "default" 28 | - name: BWB_REGION_NAME 29 | value: "{{region}}" 30 | ports: 31 | - containerPort: 8501 32 | volumeMounts: 33 | - mountPath: /dev/shm 34 | name: dshm 35 | volumes: 36 | - emptyDir: 37 | sizeLimit: 1Gi 38 | medium: Memory 39 | name: dshm 40 | --- 41 | apiVersion: v1 42 | kind: Service 43 | metadata: 44 | name: bedrock-showcase-model-service 45 | namespace: "{{namespace}}" 46 | spec: 47 | ports: 48 | - protocol: TCP 49 | port: 80 50 | targetPort: 8501 51 | type: NodePort 52 | selector: 53 | app: bedrock-showcase-model 54 | --- 55 | apiVersion: networking.k8s.io/v1 56 | kind: Ingress 57 | metadata: 58 | name: bedrock-showcase-model-ingress 59 | namespace: "{{namespace}}" 60 | annotations: 61 | alb.ingress.kubernetes.io/scheme: internet-facing 62 | alb.ingress.kubernetes.io/target-type: ip 63 | spec: 64 | ingressClassName: alb 65 | rules: 66 | - http: 67 | paths: 68 | - path: / 69 | pathType: Prefix 70 | backend: 71 | service: 72 | name: bedrock-showcase-model-service 73 | port: 74 | number: 80 75 | -------------------------------------------------------------------------------- /lib/generative-ai-showcase/index.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationTeam, BedrockBuilder, ClusterInfo } from "@aws-quickstart/eks-blueprints"; 2 | import * as blueprints from "@aws-quickstart/eks-blueprints"; 3 | import * as spi from '@aws-quickstart/eks-blueprints/dist/spi'; 4 | import { Construct } from "constructs"; 5 | import { loadYaml, readYamlDocument } from "@aws-quickstart/eks-blueprints/dist/utils"; 6 | import { KubectlProvider, ManifestDeployment } from "@aws-quickstart/eks-blueprints/dist/addons/helm-addon/kubectl-provider"; 7 | 8 | export default class GenAIShowcase { 9 | constructor(scope: Construct, id: string) { 10 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 11 | const region = process.env.CDK_DEFAULT_REGION!; 12 | const stackID = `${id}-blueprint`; 13 | 14 | const bedrockTeamProps: blueprints.teams.BedrockTeamProps = { 15 | name: blueprints.utils.valueFromContext(scope, "bedrock.pattern.name", "showcase"), 16 | namespace: blueprints.utils.valueFromContext(scope, "bedrock.pattern.namespace", "bedrock"), 17 | createNamespace: true, 18 | serviceAccountName: 'bedrock-service-account', 19 | extensionFunction: extensionFunction 20 | }; 21 | 22 | BedrockBuilder.builder() 23 | .account(account) 24 | .region(region) 25 | .version('auto') 26 | .addBedrockTeam(bedrockTeamProps) 27 | .build(scope, stackID); 28 | } 29 | } 30 | 31 | function extensionFunction(team: ApplicationTeam, clusterInfo: ClusterInfo) { 32 | const values: spi.Values = { 33 | namespace: team.teamProps.namespace, 34 | imageName: blueprints.utils.valueFromContext(clusterInfo.cluster, "bedrock.pattern.image.name", undefined), 35 | imageTag: blueprints.utils.valueFromContext(clusterInfo.cluster, "bedrock.pattern.image.tag", undefined), 36 | region: clusterInfo.cluster.stack.region 37 | }; 38 | 39 | // Apply manifest 40 | const doc = readYamlDocument(__dirname + '/deployment/showcase-deployment.ytpl'); 41 | const manifest = doc.split("---").map((e: any) => loadYaml(e)); 42 | 43 | const manifestDeployment: ManifestDeployment = { 44 | name: team.teamProps.name, 45 | namespace: team.teamProps.namespace!, 46 | manifest, 47 | values 48 | }; 49 | const manifestConstruct = new KubectlProvider(clusterInfo).addManifest(manifestDeployment); 50 | manifestConstruct.node.addDependency(team.serviceAccount); 51 | } -------------------------------------------------------------------------------- /lib/generative-ai-showcase/python/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.9.15 2 | WORKDIR /opt 3 | RUN apt-get update \ 4 | && apt-get install -y unzip \ 5 | && apt-get install -y curl 6 | COPY requirements.txt . 7 | RUN pip install -r requirements.txt 8 | RUN curl https://d2eo22ngex1n9g.cloudfront.net/Documentation/SDK/bedrock-python-sdk.zip --output bedrock-python-sdk.zip 9 | RUN unzip bedrock-python-sdk.zip -d bedrock-python-sdk 10 | RUN pip install ./bedrock-python-sdk/botocore-*-py3-none-any.whl 11 | RUN pip install ./bedrock-python-sdk/boto3-*-py3-none-any.whl 12 | RUN pip install ./bedrock-python-sdk/awscli-*-py3-none-any.whl 13 | COPY *.py /opt/ 14 | EXPOSE 8501 15 | ENTRYPOINT ["streamlit", "run"] 16 | CMD ["/opt/showcase_app.py"] 17 | -------------------------------------------------------------------------------- /lib/generative-ai-showcase/python/requirements.txt: -------------------------------------------------------------------------------- 1 | langchain 2 | streamlit 3 | -------------------------------------------------------------------------------- /lib/generative-ai-showcase/python/showcase_app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import showcase_lib as glib 3 | import showcase_examples as examples 4 | 5 | st.set_page_config(page_title="Demo Showcase", layout="wide") 6 | 7 | st.title("Demo Showcase") 8 | 9 | col1, col2, col3 = st.columns(3) 10 | 11 | 12 | with col1: 13 | st.subheader("Prompt template") 14 | 15 | prompts_keys = list(examples.prompts) 16 | 17 | prompt_selection = st.selectbox("Select a prompt template:", prompts_keys) 18 | 19 | with st.expander("View prompt"): 20 | 21 | selected_prompt_template_text = examples.prompts[prompt_selection] 22 | 23 | prompt_text = st.text_area("Prompt template text:", value=selected_prompt_template_text, height=350) 24 | 25 | 26 | with col2: 27 | st.subheader("User input") 28 | inputs_keys = list(examples.inputs) 29 | 30 | input_selection = st.selectbox("Select an input example:", inputs_keys) 31 | 32 | selected_input_template_text = examples.inputs[input_selection] 33 | 34 | input_text = st.text_area("Input text:", value=selected_input_template_text, height=350) 35 | 36 | process_button = st.button("Run", type="primary") 37 | 38 | 39 | 40 | with col3: 41 | st.subheader("Result") 42 | 43 | if process_button: 44 | with st.spinner("Running..."): 45 | response_content = glib.get_text_response(user_input=input_text, template=prompt_text) 46 | 47 | st.write(response_content) 48 | -------------------------------------------------------------------------------- /lib/generative-ai-showcase/python/showcase_lib.py: -------------------------------------------------------------------------------- 1 | import os 2 | from langchain.llms.bedrock import Bedrock 3 | from langchain import PromptTemplate 4 | 5 | 6 | def get_llm(): 7 | 8 | model_kwargs = { 9 | "maxTokenCount": 1024, 10 | "stopSequences": [], 11 | "temperature": 0, 12 | "topP": 0.9 13 | } 14 | 15 | llm = Bedrock( 16 | # credentials_profile_name=os.environ.get("BWB_PROFILE_NAME"), #sets the profile name to use for AWS credentials (if not the default) 17 | region_name=os.environ.get("BWB_REGION_NAME"), #sets the region name (if not the default) 18 | endpoint_url=os.environ.get("BWB_ENDPOINT_URL"), #sets the endpoint URL (if necessary) 19 | model_id="amazon.titan-tg1-large", #use the Anthropic Claude model 20 | model_kwargs=model_kwargs) #configure the properties for Claude 21 | 22 | return llm 23 | 24 | 25 | def get_prompt(user_input, template): 26 | 27 | prompt_template = PromptTemplate.from_template(template) #this will automatically identify the input variables for the template 28 | 29 | prompt = prompt_template.format(user_input=user_input) 30 | 31 | return prompt 32 | 33 | 34 | def get_text_response(user_input, template): #text-to-text client function 35 | llm = get_llm() 36 | 37 | prompt = get_prompt(user_input, template) 38 | 39 | return llm.predict(prompt) #return a response to the prompt 40 | 41 | -------------------------------------------------------------------------------- /lib/generic-cluster-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as ec2 from 'aws-cdk-lib/aws-ec2'; 3 | import * as eks from 'aws-cdk-lib/aws-eks'; 4 | 5 | // Blueprints Lib 6 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 7 | 8 | // Team implementations 9 | import * as team from '../teams'; 10 | 11 | /** 12 | * Demonstrates how to leverage more than one node group along with Fargate profiles. 13 | */ 14 | export default class GenericClusterConstruct { 15 | build(scope: Construct, id: string) { 16 | // Setup platform team 17 | const accountID = process.env.CDK_DEFAULT_ACCOUNT!; 18 | const platformTeam = new team.TeamPlatform(accountID); 19 | 20 | const stackID = `${id}-blueprint`; 21 | 22 | const clusterProvider = new blueprints.GenericClusterProvider({ 23 | version: eks.KubernetesVersion.V1_25, 24 | managedNodeGroups: [ 25 | { 26 | id: "mng-ondemand", 27 | amiType: eks.NodegroupAmiType.AL2_X86_64, 28 | instanceTypes: [new ec2.InstanceType('m5.2xlarge')] 29 | }, 30 | { 31 | id: "mng2-spot", 32 | instanceTypes: [ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MEDIUM)], 33 | nodeGroupCapacityType: eks.CapacityType.SPOT 34 | } 35 | ], 36 | fargateProfiles: { 37 | "fp1": { 38 | fargateProfileName: "fp1", 39 | selectors: [{ namespace: "serverless1" }] 40 | }, 41 | "fp2": { 42 | fargateProfileName: "fp2", 43 | selectors: [{ namespace: "serverless2" }] 44 | } 45 | } 46 | }); 47 | 48 | blueprints.EksBlueprint.builder() 49 | .account(accountID) 50 | .region(process.env.CDK_DEFAULT_REGION!) 51 | .clusterProvider(clusterProvider) 52 | .addOns( 53 | new blueprints.AwsLoadBalancerControllerAddOn, 54 | new blueprints.CertManagerAddOn, 55 | new blueprints.AdotCollectorAddOn, 56 | new blueprints.AppMeshAddOn, 57 | new blueprints.NginxAddOn, 58 | new blueprints.ArgoCDAddOn, 59 | new blueprints.CalicoOperatorAddOn, 60 | new blueprints.MetricsServerAddOn, 61 | new blueprints.ClusterAutoScalerAddOn, 62 | new blueprints.CloudWatchAdotAddOn, 63 | new blueprints.XrayAdotAddOn, 64 | new blueprints.SecretsStoreAddOn 65 | ) 66 | .teams(platformTeam) 67 | .version('auto') 68 | .build(scope, stackID); 69 | } 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /lib/gmaestro-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 2 | import * as gmaestroAddOn from '@granulate/gmaestro-eks-blueprints-addon'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | import {prevalidateSecrets} from "../common/construct-utils"; 5 | 6 | 7 | export default class GmaestroConstruct { 8 | async buildAsync(scope: cdk.App, id: string) { 9 | const clientIdSecretName = process.env.MAESTRO_SECRET_NAME; 10 | if (clientIdSecretName === undefined) { 11 | throw new Error("secret must be setup for the gMaestro pattern pattern to work"); 12 | } 13 | await prevalidateSecrets(GmaestroConstruct.name, process.env.CDK_DEFAULT_REGION!, clientIdSecretName); 14 | 15 | const clusterName = blueprints.utils.valueFromContext(scope, "clusterName", undefined); 16 | const namespace = blueprints.utils.valueFromContext(scope, "namespace", undefined); 17 | if (clusterName === undefined || namespace === undefined) { 18 | throw new Error("clusterName and namespace must be setup for the gMaestro pattern pattern to work"); 19 | } 20 | 21 | const stackId = `${id}-blueprint`; 22 | 23 | let gmaestroAddOnProps = { 24 | clientIdSecretName: clientIdSecretName, 25 | clusterName: clusterName, 26 | createNamespace: true, 27 | namespace: namespace, 28 | } as gmaestroAddOn.GmaestroAddOnProps; 29 | 30 | const addOns: Array = [ 31 | new blueprints.MetricsServerAddOn(), 32 | new blueprints.addons.ClusterAutoScalerAddOn(), 33 | new gmaestroAddOn.GmaestroAddOn(gmaestroAddOnProps) 34 | ]; 35 | blueprints.EksBlueprint.builder() 36 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 37 | .region(process.env.CDK_DEFAULT_REGION) 38 | .addOns(...addOns) 39 | .build(scope, stackId); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/gpu-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as ec2 from "aws-cdk-lib/aws-ec2"; 2 | import * as eks from "aws-cdk-lib/aws-eks"; 3 | import { Construct } from "constructs"; 4 | import { GpuBuilder, GpuOptions } from "@aws-quickstart/eks-blueprints"; 5 | 6 | export default class GpuConstruct { 7 | build(scope: Construct, id: string) { 8 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 9 | const region = process.env.CDK_DEFAULT_REGION!; 10 | const stackID = `${id}-eks-blueprint`; 11 | 12 | const options: GpuOptions = { 13 | kubernetesVersion: eks.KubernetesVersion.of("1.27"), 14 | instanceClass: ec2.InstanceClass.G5, 15 | instanceSize: ec2.InstanceSize.XLARGE12 16 | }; 17 | 18 | const values = { 19 | driver: { 20 | enabled: true 21 | }, 22 | mig: { 23 | strategy: 'mixed' 24 | }, 25 | devicePlugin: { 26 | enabled: true, 27 | version: 'v0.13.0' 28 | }, 29 | migManager: { 30 | enabled: true, 31 | WITH_REBOOT: true 32 | }, 33 | toolkit: { 34 | version: 'v1.13.1-centos7' 35 | }, 36 | operator: { 37 | defaultRuntime: 'containerd' 38 | }, 39 | gfd: { 40 | version: 'v0.8.0' 41 | } 42 | }; 43 | 44 | GpuBuilder.builder(options) 45 | .account(account) 46 | .region(region) 47 | .enableGpu({values}) 48 | .build(scope, stackID); 49 | } 50 | } -------------------------------------------------------------------------------- /lib/graviton-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from "@aws-quickstart/eks-blueprints"; 2 | import { GravitonBuilder } from "@aws-quickstart/eks-blueprints"; 3 | import { CfnWorkspace } from "aws-cdk-lib/aws-aps"; 4 | import * as ec2 from "aws-cdk-lib/aws-ec2"; 5 | import * as eks from "aws-cdk-lib/aws-eks"; 6 | import { Construct } from "constructs"; 7 | 8 | export default class GravitonConstruct { 9 | build(scope: Construct, id: string) { 10 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 11 | const region = process.env.CDK_DEFAULT_REGION!; 12 | const stackID = `${id}-blueprint`; 13 | 14 | const ampWorkspaceName = "graviton-amp-workspaces"; 15 | const ampWorkspace: CfnWorkspace = 16 | blueprints.getNamedResource(ampWorkspaceName); 17 | 18 | const options: Partial = { 19 | version: eks.KubernetesVersion.of("1.27"), 20 | instanceTypes: [ec2.InstanceType.of(ec2.InstanceClass.M7G, ec2.InstanceSize.XLARGE)], 21 | desiredSize: 3, 22 | minSize: 2, 23 | maxSize: 5, 24 | }; 25 | 26 | GravitonBuilder.builder(options) 27 | .account(account) 28 | .region(region) 29 | .resourceProvider( 30 | blueprints.GlobalResources.Vpc, 31 | new blueprints.VpcProvider() 32 | ) 33 | .resourceProvider( 34 | "efs-file-system", 35 | new blueprints.CreateEfsFileSystemProvider({ 36 | name: "efs-file-systems", 37 | }) 38 | ) 39 | .resourceProvider( 40 | ampWorkspaceName, 41 | new blueprints.CreateAmpProvider( 42 | ampWorkspaceName, 43 | ampWorkspaceName 44 | ) 45 | ) 46 | .addOns( 47 | new blueprints.addons.IstioBaseAddOn(), 48 | new blueprints.addons.IstioControlPlaneAddOn(), 49 | new blueprints.addons.KubeStateMetricsAddOn(), 50 | new blueprints.addons.MetricsServerAddOn(), 51 | new blueprints.addons.PrometheusNodeExporterAddOn(), 52 | new blueprints.addons.ExternalsSecretsAddOn(), 53 | new blueprints.addons.SecretsStoreAddOn(), 54 | new blueprints.addons.CalicoOperatorAddOn(), 55 | new blueprints.addons.CertManagerAddOn(), 56 | new blueprints.addons.AdotCollectorAddOn(), 57 | new blueprints.addons.AmpAddOn({ 58 | ampPrometheusEndpoint: ampWorkspace.attrPrometheusEndpoint 59 | }), 60 | new blueprints.addons.CloudWatchLogsAddon({ 61 | logGroupPrefix: "/aws/eks/graviton-blueprint", 62 | }), 63 | new blueprints.addons.EfsCsiDriverAddOn(), 64 | new blueprints.addons.FluxCDAddOn(), 65 | new blueprints.addons.GrafanaOperatorAddon(), 66 | new blueprints.addons.XrayAdotAddOn() 67 | ) 68 | .build(scope, stackID); 69 | } 70 | } -------------------------------------------------------------------------------- /lib/import-cluster/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from "constructs"; 2 | import * as blueprints from "@aws-quickstart/eks-blueprints"; 3 | import { GlobalResources } from "@aws-quickstart/eks-blueprints"; 4 | import { TeamRikerSetup, TeamScan } from "../teams"; 5 | 6 | 7 | 8 | export class ImportClusterConstruct { 9 | 10 | /** 11 | * Create a blueprint that imports an existing cluster. 12 | * @param scope stack scope 13 | */ 14 | async build(scope: Construct) { 15 | 16 | /* 17 | *Modify these constants for your use case. 18 | */ 19 | const clusterName = "quickstart-cluster"; 20 | const kubectlRoleName = "awsqs-kubernetes-helm"; 21 | const region = process.env.CDK_DEFAULT_REGION!; 22 | 23 | const sdkCluster = await blueprints.describeCluster(clusterName, region); 24 | 25 | /** 26 | * Assumes the supplied role is registered in the target cluster for kubectl access. 27 | */ 28 | const importClusterProvider = blueprints.ImportClusterProvider.fromClusterAttributes(sdkCluster, blueprints.getResource(context => 29 | new blueprints.LookupRoleProvider(kubectlRoleName).provide(context))); 30 | 31 | const vpcId = sdkCluster.resourcesVpcConfig?.vpcId; 32 | 33 | blueprints.EksBlueprint.builder() 34 | .clusterProvider(importClusterProvider) 35 | .resourceProvider(GlobalResources.Vpc, new blueprints.VpcProvider(vpcId)) // Important! register cluster VPC 36 | .addOns(new blueprints.AppMeshAddOn()) 37 | .teams(new TeamRikerSetup(scope, "./lib/teams/team-riker/")) 38 | .teams(new TeamScan()) 39 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 40 | .region('us-east-2') 41 | .build(scope, "imported-cluster"); 42 | } 43 | } -------------------------------------------------------------------------------- /lib/instana-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { loadYaml } from "@aws-quickstart/eks-blueprints/dist/utils"; 2 | import * as cdk from "aws-cdk-lib"; 3 | import { InstanaOperatorAddon } from "@instana/aws-eks-blueprint-addon"; 4 | import { EksBlueprint, utils } from "@aws-quickstart/eks-blueprints"; 5 | import { prevalidateSecrets } from "../common/construct-utils"; 6 | 7 | export const instanaProps: { [key: string]: any } = {}; 8 | 9 | export default class InstanaConstruct { 10 | async buildAsync(scope: cdk.App, id: string) { 11 | try { 12 | await prevalidateSecrets(InstanaConstruct.name, undefined, 'instana-secret-params'); 13 | 14 | const secretParamName: string = utils.valueFromContext(scope, "secretParamName", undefined); 15 | //console.log(`secretParamName is ${secretParamName}`); 16 | if(secretParamName != undefined) { 17 | instanaProps.secretParamName = secretParamName; 18 | } 19 | const yamlObject = loadYaml(JSON.stringify(instanaProps)); 20 | //console.log(`instanaProps is ${yamlObject}`); 21 | const stackId = `${id}-blueprint`; 22 | const addOns = new InstanaOperatorAddon(yamlObject); 23 | EksBlueprint.builder() 24 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 25 | .region(process.env.CDK_DEFAULT_REGION!) 26 | .addOns(addOns) 27 | .version('auto') 28 | .build(scope, stackId); 29 | console.log("Blueprint built successfully."); 30 | } catch (error) { 31 | console.error("Error:", error); 32 | throw new Error(`environment variables must be setup for the instana-operator pattern to work`); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/ipv6-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { Construct } from "constructs"; 4 | import { IpFamily } from 'aws-cdk-lib/aws-eks'; 5 | 6 | export default class IpV6Construct { 7 | build(scope: Construct, id: string) { 8 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 9 | const region = process.env.CDK_DEFAULT_REGION!; 10 | const stackID = `${id}-blueprint`; 11 | 12 | const ipFamily = IpFamily.IP_V6; //IpFamily.IP_V6 is equivalent to "ipv6" 13 | // AddOns for the cluster. For ipv6 cluster, we haven't tested with all the addons except for the below addons. 14 | const addOns: Array = [ 15 | new blueprints.addons.VpcCniAddOn(), 16 | new blueprints.addons.KarpenterAddOn(), 17 | new blueprints.addons.SecretsStoreAddOn() 18 | ]; 19 | blueprints.EksBlueprint.builder() 20 | .account(account) 21 | .region(region) 22 | .version('auto') 23 | .ipFamily(ipFamily) 24 | .addOns(...addOns) 25 | .build(scope, stackID); 26 | } 27 | } -------------------------------------------------------------------------------- /lib/jupyterhub-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | 4 | import * as cdk from 'aws-cdk-lib'; 5 | 6 | export default class JupyterHubConstruct { 7 | constructor(scope: Construct, id: string, props: cdk.StackProps) { 8 | const stackId = `${id}-blueprint`; 9 | 10 | blueprints.EksBlueprint.builder() 11 | .account(props.env!.account!) 12 | .region(props.env!.region!) 13 | .version('auto') 14 | .addOns( 15 | new blueprints.EfsCsiDriverAddOn({replicaCount: 1}), 16 | new blueprints.VpcCniAddOn(), 17 | new blueprints.KubeProxyAddOn(), 18 | new blueprints.ClusterAutoScalerAddOn(), 19 | new blueprints.JupyterHubAddOn({ 20 | efsConfig:{ 21 | removalPolicy: cdk.RemovalPolicy.DESTROY, 22 | pvcName: "efs-persist", 23 | capacity: "120Gi", 24 | }, 25 | oidcConfig: { 26 | callbackUrl: blueprints.utils.valueFromContext(scope, "callbackUrl", "https://www.example.com/hub/oauth_callback"), 27 | authUrl: blueprints.utils.valueFromContext(scope, "authUrl", "https://yourid.oidcprovider.com/authorize"), 28 | tokenUrl: blueprints.utils.valueFromContext(scope, "tokenUrl", "https://yourid.oidcprovider.com/oauth/token"), 29 | userDataUrl: blueprints.utils.valueFromContext(scope, "userDataUrl", "https://yourid.oidcprovider.com/userinfo"), 30 | clientId: blueprints.utils.valueFromContext(scope, "clientId", "yourClientIdString"), 31 | clientSecret: blueprints.utils.valueFromContext(scope, "clientSecret", "yourClientSecretString"), 32 | scope: blueprints.utils.valueFromContext(scope, "scope",["openid","name","profile","email"]), 33 | usernameKey: blueprints.utils.valueFromContext(scope, "usernameKey", "name"), 34 | }, 35 | serviceType: blueprints.JupyterHubServiceType.CLUSTERIP, 36 | values: { 37 | prePuller: { 38 | hook: { enabled: false }, 39 | } 40 | } 41 | }) 42 | ) 43 | .build(scope, stackId); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/karpenter-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { EksBlueprint } from "@aws-quickstart/eks-blueprints"; 2 | import * as blueprints from "@aws-quickstart/eks-blueprints"; 3 | import { Construct } from "constructs"; 4 | export default class KarpenterConstruct { 5 | constructor(scope: Construct, id: string) { 6 | const account = process.env.CDK_DEFAULT_ACCOUNT!; 7 | const region = process.env.CDK_DEFAULT_REGION!; 8 | const stackID = `${id}-blueprint`; 9 | 10 | const karpenterAddOn = new blueprints.addons.KarpenterAddOn({ 11 | version: 'v0.33.1', 12 | nodePoolSpec: { 13 | requirements: [ 14 | { key: 'node.kubernetes.io/instance-type', operator: 'In', values: ['m5.large'] }, 15 | { key: 'topology.kubernetes.io/zone', operator: 'In', values: [`${region}a`,`${region}b`, `${region}c`]}, 16 | { key: 'kubernetes.io/arch', operator: 'In', values: ['amd64','arm64']}, 17 | { key: 'karpenter.sh/capacity-type', operator: 'In', values: ['on-demand']}, 18 | ], 19 | disruption: { 20 | consolidationPolicy: "WhenUnderutilized", 21 | expireAfter: "259200s" 22 | }, 23 | weight: 20, 24 | 25 | }, 26 | ec2NodeClassSpec:{ 27 | subnetSelectorTerms: [ 28 | { 29 | tags: { "Name": `${stackID}/${stackID}-vpc/*` } 30 | } 31 | ], 32 | securityGroupSelectorTerms: [ 33 | { 34 | tags: { [`kubernetes.io/cluster/${stackID}`]: "owned" } 35 | } 36 | ], 37 | 38 | amiFamily: "AL2" 39 | }, 40 | interruptionHandling: true, 41 | }); 42 | 43 | EksBlueprint.builder() 44 | .account(account) 45 | .region(region) 46 | .version('auto') 47 | .addOns( 48 | new blueprints.addons.AwsLoadBalancerControllerAddOn(), 49 | new blueprints.addons.VpcCniAddOn(), 50 | new blueprints.addons.CoreDnsAddOn(), 51 | new blueprints.addons.KubeProxyAddOn(), 52 | new blueprints.addons.CertManagerAddOn(), 53 | new blueprints.addons.KubeStateMetricsAddOn(), 54 | new blueprints.addons.SSMAgentAddOn(), 55 | new blueprints.addons.MetricsServerAddOn(), 56 | karpenterAddOn, 57 | ) 58 | .build(scope, stackID); 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/kasten-k10-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { KastenK10AddOn } from '@kastenhq/kasten-eks-blueprints-addon'; 4 | 5 | export default class KastenK10Construct { 6 | constructor(scope: Construct, id: string) { 7 | const stackId = `${id}-blueprint`; 8 | 9 | blueprints.EksBlueprint.builder() 10 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 11 | .region(process.env.CDK_DEFAULT_REGION) 12 | .version('auto') 13 | .addOns(new blueprints.ClusterAutoScalerAddOn, new KastenK10AddOn) 14 | .build(scope, stackId); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/keptn-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import { EksBlueprint } from '@aws-quickstart/eks-blueprints'; 3 | import { KeptnControlPlaneAddOn } from '@keptn/keptn-controlplane-eks-blueprints-addon'; 4 | 5 | export default class KeptnControlPlaneConstruct { 6 | 7 | constructor(scope: Construct, id: string) { 8 | // AddOns for the cluster 9 | const stackId = `${id}-blueprint`; 10 | 11 | const keptnControlPlane = new KeptnControlPlaneAddOn({ 12 | // uncomment after you setup the ssm secret keptn-secrets. 13 | // ssmSecretName: 'keptn-secrets' 14 | }); 15 | 16 | EksBlueprint.builder() 17 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 18 | .region(process.env.CDK_DEFAULT_REGION) 19 | .addOns(keptnControlPlane) 20 | .version('auto') 21 | .build(scope, stackId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/komodor-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 2 | import { KomodorAddOn } from '@komodor/komodor-eks-blueprints-addon'; 3 | import { Construct } from "constructs"; 4 | 5 | export default class KomodorConstruct extends Construct { 6 | constructor(scope: Construct, id: string) { 7 | super(scope, id); 8 | 9 | const stackId = `${id}-blueprint`; 10 | 11 | const addOns: Array = [ 12 | new KomodorAddOn({ 13 | clusterName: stackId, 14 | apiKey: "", //replace with your API key 15 | values: {} // add any custom Helm values 16 | }) 17 | ]; 18 | 19 | blueprints.EksBlueprint.builder() 20 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 21 | .region(process.env.CDK_DEFAULT_REGION) 22 | .addOns(...addOns) 23 | .version('auto') 24 | .build(scope, stackId); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/kubecost-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import { EksBlueprint } from '@aws-quickstart/eks-blueprints'; 3 | import { KubecostAddOn } from '@kubecost/kubecost-eks-blueprints-addon'; 4 | 5 | 6 | export default class KubecostConstruct { 7 | constructor(scope: Construct, id: string) { 8 | // AddOns for the cluster 9 | const stackId = `${id}-blueprint`; 10 | 11 | EksBlueprint.builder() 12 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 13 | .region(process.env.CDK_DEFAULT_REGION) 14 | .addOns(new KubecostAddOn()) 15 | .version('auto') 16 | .build(scope, stackId); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/kubeflow-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { KubeflowAddOn } from 'eks-blueprints-cdk-kubeflow-ext'; 4 | import * as amp from 'aws-cdk-lib/aws-aps'; 5 | import * as eks from 'aws-cdk-lib/aws-eks'; 6 | import * as ec2 from 'aws-cdk-lib/aws-ec2'; 7 | 8 | export default class KubeflowConstruct { 9 | constructor(scope: Construct, id: string) { 10 | const stackId = `${id}-blueprint`; 11 | const ampWorkspaceName = "kubeflow-monitoring"; 12 | const ampPrometheusEndpoint = (blueprints.getNamedResource(ampWorkspaceName) as unknown as amp.CfnWorkspace).attrPrometheusEndpoint; 13 | 14 | const mngProps: blueprints.MngClusterProviderProps = { 15 | version: eks.KubernetesVersion.V1_29, 16 | instanceTypes: [new ec2.InstanceType("m5.2xlarge")], 17 | amiType: eks.NodegroupAmiType.AL2_X86_64, 18 | desiredSize: 2, 19 | maxSize: 3, 20 | }; 21 | 22 | blueprints.EksBlueprint.builder() 23 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 24 | .region(process.env.CDK_DEFAULT_REGION) 25 | .resourceProvider(ampWorkspaceName, new blueprints.CreateAmpProvider(ampWorkspaceName, ampWorkspaceName)) 26 | .addOns( 27 | new blueprints.AwsLoadBalancerControllerAddOn(), 28 | new blueprints.ClusterAutoScalerAddOn(), 29 | new blueprints.VpcCniAddOn(), 30 | new blueprints.CoreDnsAddOn(), 31 | new blueprints.KubeProxyAddOn(), 32 | new blueprints.EbsCsiDriverAddOn(), 33 | new blueprints.CertManagerAddOn(), 34 | new blueprints.KubeStateMetricsAddOn(), 35 | new blueprints.MetricsServerAddOn(), 36 | new blueprints.PrometheusNodeExporterAddOn(), 37 | new blueprints.addons.IstioBaseAddOn({ 38 | version: "1.18.2" 39 | }), 40 | new blueprints.addons.IstioControlPlaneAddOn({ 41 | version: "1.18.2" 42 | }), 43 | new blueprints.addons.IstioIngressGatewayAddon({ 44 | version: "1.18.2" 45 | }), 46 | new blueprints.addons.IstioCniAddon({ 47 | version: "1.18.2" 48 | }), 49 | new blueprints.AdotCollectorAddOn(), 50 | new blueprints.addons.AmpAddOn({ 51 | ampPrometheusEndpoint: ampPrometheusEndpoint, 52 | }), 53 | new KubeflowAddOn({ 54 | namespace: 'kubeflow-pipelines' 55 | }) 56 | ) 57 | .clusterProvider(new blueprints.MngClusterProvider(mngProps)) 58 | .version('auto') 59 | .build(scope, stackId); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/kubeshark-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import { EksBlueprint } from '@aws-quickstart/eks-blueprints'; 3 | import { KubesharkAddOn } from 'kubeshark'; 4 | 5 | 6 | export default class KubesharkConstruct { 7 | constructor(scope: Construct, id: string) { 8 | // AddOns for the cluster 9 | const stackId = `${id}-blueprint`; 10 | 11 | EksBlueprint.builder() 12 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 13 | .region(process.env.CDK_DEFAULT_REGION) 14 | .addOns(new KubesharkAddOn()) 15 | .version('auto') 16 | .build(scope, stackId); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/multi-account-monitoring/amg-iam-setup.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as iam from 'aws-cdk-lib/aws-iam'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | 5 | /** 6 | * Defines properties for the AMG IAM setup. 7 | */ 8 | export interface AmgIamSetupStackProps extends cdk.StackProps { 9 | /** 10 | * Role to create for the AMG stack that grants access to the specified accounts for AMP and CloudWatch metrics. 11 | */ 12 | roleName: string, 13 | 14 | /** 15 | * Monitored accounts. These contain ampPrometheusDataSourceRole and cloudwatchPrometheusDataSourceRole roles 16 | * with trust relationship to the monitoring (AMG) account. 17 | */ 18 | accounts: string[] 19 | } 20 | 21 | /** 22 | * Stack provisions IAM in the moniitoring account with turst relationship to the monitored account for metrics. 23 | */ 24 | export class AmgIamSetupStack extends cdk.Stack { 25 | 26 | constructor(scope: Construct, id: string, props: AmgIamSetupStackProps) { 27 | super(scope, id, props); 28 | 29 | const role = new iam.Role(this, 'amg-iam-role', { 30 | roleName: props.roleName, 31 | assumedBy: new iam.ServicePrincipal('grafana.amazonaws.com'), 32 | description: 'Service Role for Amazon Managed Grafana', 33 | }); 34 | 35 | for (let i = 0; i < props.accounts.length; i++) { 36 | role.addToPolicy(new iam.PolicyStatement({ 37 | actions: [ 38 | "sts:AssumeRole" 39 | ], 40 | resources: [`arn:aws:iam::${props.accounts[i]}:role/ampPrometheusDataSourceRole`, 41 | `arn:aws:iam::${props.accounts[i]}:role/cloudwatchDataSourceRole` 42 | ], 43 | })); 44 | } 45 | 46 | new cdk.CfnOutput(this, 'AMGRole', { value: role ? role.roleArn : "none" }); 47 | } 48 | } -------------------------------------------------------------------------------- /lib/multi-account-monitoring/amp-iam-setup.ts: -------------------------------------------------------------------------------- 1 | import { NestedStack, NestedStackProps } from 'aws-cdk-lib'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { Construct } from 'constructs'; 4 | import * as iam from 'aws-cdk-lib/aws-iam'; 5 | import * as cdk from 'aws-cdk-lib'; 6 | 7 | /** 8 | * Stack the creates the role with trust relationship to the monitoring account to 9 | * get AMP metrics. 10 | */ 11 | export class AmpIamSetupStack extends NestedStack { 12 | 13 | public static builder(roleName: string, trustAccount: string): blueprints.NestedStackBuilder { 14 | return { 15 | build(scope: Construct, id: string, props: NestedStackProps) { 16 | return new AmpIamSetupStack(scope, id, props, roleName, trustAccount); 17 | } 18 | }; 19 | } 20 | 21 | constructor(scope: Construct, id: string, props: NestedStackProps, roleName: string, trustAccount: string) { 22 | super(scope, id, props); 23 | 24 | const role = new iam.Role(this, 'amp-iam-trust-role', { 25 | roleName: roleName, 26 | assumedBy: new iam.AccountPrincipal(trustAccount), 27 | description: 'AMP role to assume from central account', 28 | }); 29 | 30 | role.addToPolicy(new iam.PolicyStatement({ 31 | actions: [ 32 | "aps:ListWorkspaces", 33 | "aps:DescribeWorkspace", 34 | "aps:QueryMetrics", 35 | "aps:GetLabels", 36 | "aps:GetSeries", 37 | "aps:GetMetricMetadata", 38 | "xray:PutTraceSegments", 39 | "xray:PutTelemetryRecords", 40 | "xray:GetSamplingRules", 41 | "xray:GetSamplingTargets", 42 | "xray:GetSamplingStatisticSummaries", 43 | "xray:BatchGetTraces", 44 | "xray:GetServiceGraph", 45 | "xray:GetTraceGraph", 46 | "xray:GetTraceSummaries", 47 | "xray:GetGroups", 48 | "xray:GetGroup", 49 | "xray:ListTagsForResource", 50 | "xray:GetTimeSeriesServiceStatistics", 51 | "xray:GetInsightSummaries", 52 | "xray:GetInsight", 53 | "xray:GetInsightEvents", 54 | "xray:GetInsightImpactGraph", 55 | "ssm:GetParameter" 56 | ], 57 | resources: ["*"], 58 | })); 59 | 60 | new cdk.CfnOutput(this, 'AMPTrustRole', { value: role ? role.roleArn : "none" }); 61 | } 62 | } -------------------------------------------------------------------------------- /lib/multi-account-monitoring/cloudwatch-iam-setup.ts: -------------------------------------------------------------------------------- 1 | import { NestedStack, NestedStackProps } from 'aws-cdk-lib'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { Construct } from 'constructs'; 4 | import * as iam from 'aws-cdk-lib/aws-iam'; 5 | import * as cdk from 'aws-cdk-lib'; 6 | 7 | /** 8 | * Stack the creates the role with trust relationship to the monitoring account to 9 | * get CloudWatch metrics. 10 | */ 11 | export class CloudWatchIamSetupStack extends NestedStack { 12 | 13 | public static builder(roleName: string, trustAccount: string): blueprints.NestedStackBuilder { 14 | return { 15 | build(scope: Construct, id: string, props: NestedStackProps) { 16 | return new CloudWatchIamSetupStack(scope, id, props, roleName, trustAccount); 17 | } 18 | }; 19 | } 20 | 21 | constructor(scope: Construct, id: string, props: NestedStackProps, roleName: string, trustAccount: string) { 22 | super(scope, id, props); 23 | 24 | const role = new iam.Role(this, 'cloudwatch-iam-trust-role', { 25 | roleName: roleName, 26 | assumedBy: new iam.AccountPrincipal(trustAccount), 27 | description: 'CloudWatch role to assume from central account', 28 | }); 29 | 30 | role.addToPolicy(new iam.PolicyStatement({ 31 | actions: [ 32 | "cloudwatch:DescribeAlarmsForMetric", 33 | "cloudwatch:DescribeAlarmHistory", 34 | "cloudwatch:DescribeAlarms", 35 | "cloudwatch:ListMetrics", 36 | "cloudwatch:GetMetricStatistics", 37 | "cloudwatch:GetMetricData", 38 | "logs:DescribeLogGroups", 39 | "logs:GetLogGroupFields", 40 | "logs:StartQuery", 41 | "logs:StopQuery", 42 | "logs:GetQueryResults", 43 | "logs:GetLogEvents", 44 | "ec2:DescribeTags", 45 | "ec2:DescribeInstances", 46 | "ec2:DescribeRegions", 47 | "tag:GetResources", 48 | "xray:PutTraceSegments", 49 | "xray:PutTelemetryRecords", 50 | "xray:GetSamplingRules", 51 | "xray:GetSamplingTargets", 52 | "xray:GetSamplingStatisticSummaries", 53 | "xray:BatchGetTraces", 54 | "xray:GetServiceGraph", 55 | "xray:GetTraceGraph", 56 | "xray:GetTraceSummaries", 57 | "xray:GetGroups", 58 | "xray:GetGroup", 59 | "xray:ListTagsForResource", 60 | "xray:GetTimeSeriesServiceStatistics", 61 | "xray:GetInsightSummaries", 62 | "xray:GetInsight", 63 | "xray:GetInsightEvents", 64 | "xray:GetInsightImpactGraph", 65 | "ssm:GetParameter" 66 | ], 67 | resources: ["*"], 68 | })); 69 | 70 | new cdk.CfnOutput(this, 'CloudWatchTrustRole', { value: role ? role.roleArn : "none" }); 71 | } 72 | } -------------------------------------------------------------------------------- /lib/multi-account-monitoring/index.ts: -------------------------------------------------------------------------------- 1 | export { PipelineMultiEnvMonitoring } from './pipeline'; -------------------------------------------------------------------------------- /lib/multi-cluster-construct/cluster-secret-store-addon.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 2 | import * as eks from "aws-cdk-lib/aws-eks"; 3 | import { Construct } from 'constructs'; 4 | import { dependable } from '@aws-quickstart/eks-blueprints/dist/utils'; 5 | 6 | export class ClusterSecretStoreAddon implements blueprints.ClusterAddOn { 7 | id?: string | undefined; 8 | @dependable(blueprints.addons.ExternalsSecretsAddOn.name) 9 | deploy(clusterInfo: blueprints.ClusterInfo): void | Promise { 10 | const cluster = clusterInfo.cluster; 11 | 12 | const clusterSecretStore = new eks.KubernetesManifest(clusterInfo.cluster, "ClusterSecretStore", { 13 | cluster: cluster, 14 | manifest: [ 15 | { 16 | apiVersion: "external-secrets.io/v1beta1", 17 | kind: "ClusterSecretStore", 18 | metadata: {name: "eksa-secret-store"}, 19 | spec: { 20 | provider: { 21 | aws: { 22 | service: "SecretsManager", 23 | region: clusterInfo.cluster.stack.region, 24 | auth: { 25 | jwt: { 26 | serviceAccountRef: { 27 | name: "external-secrets-sa", 28 | namespace: "external-secrets", 29 | }, 30 | }, 31 | }, 32 | }, 33 | }, 34 | }, 35 | }, 36 | ], 37 | }); 38 | 39 | const clusterConfigMapStore = new eks.KubernetesManifest(clusterInfo.cluster, "ClusterConfigMap", { 40 | cluster: cluster, 41 | manifest: [ 42 | { 43 | apiVersion: "external-secrets.io/v1beta1", 44 | kind: "ClusterSecretStore", 45 | metadata: {name: "eksa-configmap-store"}, 46 | spec: { 47 | provider: { 48 | aws: { 49 | service: "ParameterStore", 50 | region: clusterInfo.cluster.stack.region, 51 | auth: { 52 | jwt: { 53 | serviceAccountRef: { 54 | name: "external-secrets-sa", 55 | namespace: "external-secrets", 56 | }, 57 | }, 58 | }, 59 | }, 60 | }, 61 | }, 62 | }, 63 | ], 64 | }); 65 | 66 | clusterConfigMapStore.node.addDependency(clusterSecretStore); 67 | return Promise.resolve(clusterSecretStore); 68 | } 69 | } -------------------------------------------------------------------------------- /lib/multi-cluster-construct/clusterMapping.ts: -------------------------------------------------------------------------------- 1 | import * as eks from 'aws-cdk-lib/aws-eks'; 2 | import * as ec2 from 'aws-cdk-lib/aws-ec2'; 3 | 4 | /** 5 | * Instance Mapping for fields such as chart, version, managed IAM policy. 6 | */ 7 | export interface InstanceMapping { 8 | amiType: eks.NodegroupAmiType, 9 | instanceType: ec2.InstanceType, 10 | } 11 | /** 12 | * List of all clusters deployed by conformitron 13 | */ 14 | export enum ClusterName { 15 | ARM = "arm", 16 | X86 = "x86", 17 | BR_X86 = "br-x86", 18 | BR_ARM = "br-arm", 19 | MONITORING = "grafana-monitoring" 20 | } 21 | 22 | 23 | export const clusterMappings : {[key in ClusterName]?: InstanceMapping } = { 24 | [ClusterName.ARM]: { 25 | amiType: eks.NodegroupAmiType.AL2_ARM_64, 26 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.M7G, ec2.InstanceSize.XLARGE2) 27 | }, 28 | [ClusterName.X86]: { 29 | amiType: eks.NodegroupAmiType.AL2_X86_64, 30 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE2) 31 | }, 32 | [ClusterName.BR_ARM]: { 33 | amiType: eks.NodegroupAmiType.BOTTLEROCKET_ARM_64, 34 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.M7G, ec2.InstanceSize.XLARGE2) 35 | }, 36 | [ClusterName.BR_X86]: { 37 | amiType: eks.NodegroupAmiType.BOTTLEROCKET_X86_64, 38 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE2) 39 | }, 40 | [ClusterName.MONITORING]: { 41 | amiType: eks.NodegroupAmiType.AL2_X86_64, 42 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE) 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /lib/multi-cluster-construct/grafana-operator-secret-addon.ts: -------------------------------------------------------------------------------- 1 | import 'source-map-support/register'; // to get better stack traces and debugging 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import * as eks from "aws-cdk-lib/aws-eks"; 4 | import { Construct } from 'constructs'; 5 | import { dependable } from '@aws-quickstart/eks-blueprints/dist/utils'; 6 | 7 | export class GrafanaOperatorSecretAddon implements blueprints.ClusterAddOn { 8 | id?: string | undefined; 9 | @dependable(blueprints.addons.ExternalsSecretsAddOn.name, blueprints.addons.GrafanaOperatorAddon.name) 10 | deploy(clusterInfo: blueprints.ClusterInfo): void | Promise { 11 | const cluster = clusterInfo.cluster; 12 | const secretStore = new eks.KubernetesManifest(clusterInfo.cluster.stack, "ClusterSecretStore", { 13 | cluster: cluster, 14 | manifest: [ 15 | { 16 | apiVersion: "external-secrets.io/v1beta1", 17 | kind: "ClusterSecretStore", 18 | metadata: { 19 | name: "ssm-parameter-store", 20 | namespace: "default" 21 | }, 22 | spec: { 23 | provider: { 24 | aws: { 25 | service: "ParameterStore", 26 | region: clusterInfo.cluster.stack.region, 27 | auth: { 28 | jwt: { 29 | serviceAccountRef: { 30 | name: "external-secrets-sa", 31 | namespace: "external-secrets", 32 | }, 33 | }, 34 | }, 35 | }, 36 | }, 37 | }, 38 | }, 39 | ], 40 | }); 41 | 42 | const externalSecret = new eks.KubernetesManifest(clusterInfo.cluster.stack, "ExternalSecret", { 43 | cluster: cluster, 44 | manifest: [ 45 | { 46 | apiVersion: "external-secrets.io/v1beta1", 47 | kind: "ExternalSecret", 48 | metadata: { 49 | name: "external-grafana-admin-credentials", 50 | namespace: "grafana-operator" 51 | }, 52 | spec: { 53 | secretStoreRef: { 54 | name: "ssm-parameter-store", 55 | kind: "ClusterSecretStore", 56 | }, 57 | target: { 58 | name: "grafana-admin-credentials" 59 | }, 60 | data: [ 61 | { 62 | secretKey: "GF_SECURITY_ADMIN_APIKEY", 63 | remoteRef: { 64 | key: "/grafana-api-key" 65 | }, 66 | }, 67 | ], 68 | }, 69 | }, 70 | ], 71 | }); 72 | externalSecret.node.addDependency(secretStore); 73 | return Promise.resolve(secretStore); 74 | } 75 | } -------------------------------------------------------------------------------- /lib/multi-cluster-construct/multi-cluster-builder.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | 3 | // Blueprints Lib 4 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 5 | import { ClusterSecretStoreAddon } from './cluster-secret-store-addon'; 6 | 7 | 8 | export default class MultiClusterBuilderConstruct { 9 | build(scope: Construct, id: string, account?: string, region?: string ) { 10 | // Setup platform team 11 | const accountID = account ?? process.env.CDK_DEFAULT_ACCOUNT! ; 12 | const awsRegion = region ?? process.env.CDK_DEFAULT_REGION! ; 13 | 14 | const stackID = `${id}-blueprint`; 15 | this.create(scope, accountID, awsRegion) 16 | .build(scope, stackID); 17 | } 18 | 19 | 20 | create(scope: Construct, account?: string, region?: string ) { 21 | // Setup platform team 22 | const accountID = account ?? process.env.CDK_DEFAULT_ACCOUNT! ; 23 | const awsRegion = region ?? process.env.CDK_DEFAULT_REGION! ; 24 | 25 | const ampEndpoint = blueprints.utils.valueFromContext(scope, "conformitron.amp.endpoint", "https://aps-workspaces..amazonaws.com/workspaces//"); 26 | 27 | const ampAddOnProps: blueprints.AmpAddOnProps = { 28 | ampPrometheusEndpoint: ampEndpoint, 29 | }; 30 | 31 | ampAddOnProps.openTelemetryCollector = { 32 | manifestPath: __dirname + '/resources/otel-collector-config-new.yml', 33 | manifestParameterMap: { 34 | logGroupName: `/aws/eks/conformitron/cluster`, 35 | logStreamName: `$NODE_NAME`, 36 | logRetentionDays: 30, 37 | awsRegion: region 38 | } 39 | }; 40 | 41 | 42 | 43 | return blueprints.ObservabilityBuilder.builder() 44 | .account(accountID) 45 | .region(awsRegion) 46 | .withAmpProps(ampAddOnProps) 47 | .enableOpenSourcePatternAddOns() 48 | .addOns( 49 | new blueprints.addons.FluxCDAddOn({ 50 | repositories:[{ 51 | name: "eks-cloud-addons-conformance", 52 | namespace: "flux-system", 53 | repository: { 54 | repoUrl: 'https://github.com/aws-samples/eks-anywhere-addons', 55 | targetRevision: "main", 56 | }, 57 | values: { 58 | }, 59 | kustomizations: [ 60 | {kustomizationPath: "./eks-anywhere-common/Addons/Core/Botkube"}, 61 | {kustomizationPath: "./eks-anywhere-common/Addons/Core/Kube-Observer"}, 62 | {kustomizationPath: "./eks-anywhere-common/Testers/"}, 63 | {kustomizationPath: "./eks-cloud/Testers"}, 64 | {kustomizationPath: "./eks-anywhere-common/Addons/Partner"}, 65 | {kustomizationPath: "./eks-cloud/Partner"}, 66 | ], 67 | }], 68 | }), 69 | new ClusterSecretStoreAddon(), 70 | new blueprints.addons.EbsCsiDriverAddOn(), 71 | new blueprints.addons.ClusterAutoScalerAddOn() 72 | ); 73 | } 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /lib/multi-cluster-construct/resources/amp-config/istio/recording-rules.yml: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: "istio.recording-rules" 3 | interval: 5s 4 | rules: 5 | - record: "workload:istio_requests_total" 6 | expr: | 7 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_requests_total) 8 | 9 | - record: "workload:istio_request_duration_milliseconds_count" 10 | expr: | 11 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_request_duration_milliseconds_count) 12 | 13 | - record: "workload:istio_request_duration_milliseconds_sum" 14 | expr: | 15 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_request_duration_milliseconds_sum) 16 | 17 | - record: "workload:istio_request_duration_milliseconds_bucket" 18 | expr: | 19 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_request_duration_milliseconds_bucket) 20 | 21 | - record: "workload:istio_request_bytes_count" 22 | expr: | 23 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_request_bytes_count) 24 | 25 | - record: "workload:istio_request_bytes_sum" 26 | expr: | 27 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_request_bytes_sum) 28 | 29 | - record: "workload:istio_request_bytes_bucket" 30 | expr: | 31 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_request_bytes_bucket) 32 | 33 | - record: "workload:istio_response_bytes_count" 34 | expr: | 35 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_response_bytes_count) 36 | 37 | - record: "workload:istio_response_bytes_sum" 38 | expr: | 39 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_response_bytes_sum) 40 | 41 | - record: "workload:istio_response_bytes_bucket" 42 | expr: | 43 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_response_bytes_bucket) 44 | 45 | - record: "workload:istio_tcp_sent_bytes_total" 46 | expr: | 47 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_tcp_sent_bytes_total) 48 | 49 | - record: "workload:istio_tcp_received_bytes_total" 50 | expr: | 51 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_tcp_received_bytes_total) 52 | 53 | - record: "workload:istio_tcp_connections_opened_total" 54 | expr: | 55 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_tcp_connections_opened_total) 56 | 57 | - record: "workload:istio_tcp_connections_closed_total" 58 | expr: | 59 | sum without(instance, kubernetes_namespace, kubernetes_pod_name) (istio_tcp_connections_closed_total) -------------------------------------------------------------------------------- /lib/multi-cluster-construct/resources/amp-config/java/alerting-rules.yml: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: default-alert 3 | rules: 4 | - alert: metric:alerting_rule 5 | expr: jvm_memory_bytes_used{job="java", area="heap"} / jvm_memory_bytes_max * 100 > 80 6 | for: 1m 7 | labels: 8 | severity: warning 9 | annotations: 10 | summary: "JVM heap warning" 11 | description: "JVM heap of instance `{{$labels.instance}}` from application `{{$labels.application}}` is above 80% for one minute. (current=`{{$value}}%`)" 12 | -------------------------------------------------------------------------------- /lib/multi-cluster-construct/resources/amp-config/java/recording-rules.yml: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: default-metric 3 | rules: 4 | - record: metric:recording_rule 5 | expr: avg(rate(container_cpu_usage_seconds_total[5m])) 6 | -------------------------------------------------------------------------------- /lib/multi-cluster-construct/resources/amp-config/nginx/alerting-rules.yml: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: Nginx-HTTP-4xx-error-rate 3 | rules: 4 | - alert: metric:alerting_rule 5 | expr: sum(rate(nginx_http_requests_total{status=~"^4.."}[1m])) / sum(rate(nginx_http_requests_total[1m])) * 100 > 5 6 | for: 1m 7 | labels: 8 | severity: critical 9 | annotations: 10 | summary: Nginx high HTTP 4xx error rate (instance {{ $labels.instance }}) 11 | description: "Too many HTTP requests with status 4xx (> 5%)\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" 12 | - name: Nginx-HTTP-5xx-error-rate 13 | rules: 14 | - alert: metric:alerting_rule 15 | expr: sum(rate(nginx_http_requests_total{status=~"^5.."}[1m])) / sum(rate(nginx_http_requests_total[1m])) * 100 > 5 16 | for: 1m 17 | labels: 18 | severity: critical 19 | annotations: 20 | summary: Nginx high HTTP 5xx error rate (instance {{ $labels.instance }}) 21 | description: "Too many HTTP requests with status 5xx (> 5%)\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" 22 | - name: Nginx-high-latency 23 | rules: 24 | - alert: metric:alerting_rule 25 | expr: histogram_quantile(0.99, sum(rate(nginx_http_request_duration_seconds_bucket[2m])) by (host, node)) > 3 26 | for: 2m 27 | labels: 28 | severity: warning 29 | annotations: 30 | summary: Nginx latency high (instance {{ $labels.instance }}) 31 | description: "Nginx p99 latency is higher than 3 seconds\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" -------------------------------------------------------------------------------- /lib/multi-cluster-construct/resources/cost-optimization/scaleUpEksToOne.yml: -------------------------------------------------------------------------------- 1 | schemaVersion: '0.3' 2 | description: |- 3 | --- 4 | # Scale down all conformitron EKS cluster to1 5 | assumeRole: arn:aws:iam::ACCOUNT_ID:role/SsmEksRole 6 | mainSteps: 7 | - name: scaleEKSClusterToOne 8 | action: aws:executeAwsApi 9 | nextStep: scaleEKSClusterToOne_1 10 | isEnd: false 11 | inputs: 12 | Service: eks 13 | Api: UpdateNodegroupConfig 14 | clusterName: arm-1-26-blueprint 15 | nodegroupName: eks-blueprints-mng 16 | scalingConfig: 17 | minSize: 1 18 | maxSize: 1 19 | desiredSize: 1 20 | - name: scaleEKSClusterToOne_1 21 | action: aws:executeAwsApi 22 | nextStep: scaleEKSClusterToOne_2 23 | isEnd: false 24 | inputs: 25 | Service: eks 26 | Api: UpdateNodegroupConfig 27 | clusterName: arm-1-27-blueprint 28 | nodegroupName: eks-blueprints-mng 29 | scalingConfig: 30 | minSize: 1 31 | maxSize: 1 32 | desiredSize: 1 33 | - name: scaleEKSClusterToOne_2 34 | action: aws:executeAwsApi 35 | nextStep: scaleEKSClusterToOne_3 36 | isEnd: false 37 | inputs: 38 | Service: eks 39 | Api: UpdateNodegroupConfig 40 | clusterName: arm-1-28-blueprint 41 | nodegroupName: eks-blueprints-mng 42 | scalingConfig: 43 | minSize: 1 44 | maxSize: 1 45 | desiredSize: 1 46 | - name: scaleEKSClusterToOne_3 47 | action: aws:executeAwsApi 48 | nextStep: scaleEKSClusterToOne_4 49 | isEnd: false 50 | inputs: 51 | Service: eks 52 | Api: UpdateNodegroupConfig 53 | clusterName: br-arm-1-28-blueprint 54 | nodegroupName: eks-blueprints-mng 55 | scalingConfig: 56 | minSize: 1 57 | maxSize: 1 58 | desiredSize: 1 59 | - name: scaleEKSClusterToOne_4 60 | action: aws:executeAwsApi 61 | nextStep: scaleEKSClusterToOne_5 62 | isEnd: false 63 | inputs: 64 | Service: eks 65 | Api: UpdateNodegroupConfig 66 | clusterName: br-x86-1-28-blueprint 67 | nodegroupName: eks-blueprints-mng 68 | scalingConfig: 69 | minSize: 1 70 | maxSize: 1 71 | desiredSize: 1 72 | - name: scaleEKSClusterToOne_5 73 | action: aws:executeAwsApi 74 | nextStep: scaleEKSClusterToOne_6 75 | isEnd: false 76 | inputs: 77 | Service: eks 78 | Api: UpdateNodegroupConfig 79 | clusterName: x86-1-26-blueprint 80 | nodegroupName: eks-blueprints-mng 81 | scalingConfig: 82 | minSize: 1 83 | maxSize: 1 84 | desiredSize: 1 85 | - name: scaleEKSClusterToOne_6 86 | action: aws:executeAwsApi 87 | nextStep: scaleEKSClusterToOne_7 88 | isEnd: false 89 | inputs: 90 | Service: eks 91 | Api: UpdateNodegroupConfig 92 | clusterName: x86-1-27-blueprint 93 | nodegroupName: eks-blueprints-mng 94 | scalingConfig: 95 | minSize: 1 96 | maxSize: 1 97 | desiredSize: 1 98 | - name: scaleEKSClusterToOne_7 99 | action: aws:executeAwsApi 100 | isEnd: true 101 | inputs: 102 | Service: eks 103 | Api: UpdateNodegroupConfig 104 | clusterName: x86-1-28-blueprint 105 | nodegroupName: eks-blueprints-mng 106 | scalingConfig: 107 | minSize: 1 108 | maxSize: 1 109 | desiredSize: 1 110 | -------------------------------------------------------------------------------- /lib/multi-team-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | // Blueprints Lib 3 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 4 | 5 | // Team implementations 6 | import * as team from '../teams'; 7 | const burnhamManifestDir = './lib/teams/team-burnham/'; 8 | const rikerManifestDir = './lib/teams/team-riker/'; 9 | const teamManifestDirList = [burnhamManifestDir,rikerManifestDir]; 10 | 11 | export default class MultiTeamConstruct { 12 | constructor(scope: Construct, id: string) { 13 | 14 | // Setup platform team 15 | const accountID = process.env.CDK_DEFAULT_ACCOUNT!; 16 | const platformTeam = new team.TeamPlatform(accountID); 17 | 18 | // Teams for the cluster. 19 | const teams: Array = [ 20 | platformTeam, 21 | new team.TeamTroiSetup, 22 | new team.TeamRikerSetup(scope, teamManifestDirList[1]), 23 | new team.TeamBurnhamSetup(scope, teamManifestDirList[0]) 24 | ]; 25 | 26 | // AddOns for the cluster. 27 | const addOns: Array = [ 28 | new blueprints.AwsLoadBalancerControllerAddOn, 29 | new blueprints.CertManagerAddOn, 30 | new blueprints.AdotCollectorAddOn, 31 | new blueprints.AppMeshAddOn, 32 | new blueprints.NginxAddOn, 33 | new blueprints.ArgoCDAddOn, 34 | new blueprints.CalicoOperatorAddOn, 35 | new blueprints.MetricsServerAddOn, 36 | new blueprints.ClusterAutoScalerAddOn, 37 | new blueprints.CloudWatchAdotAddOn, 38 | new blueprints.XrayAddOn, 39 | new blueprints.SecretsStoreAddOn 40 | ]; 41 | 42 | const stackID = `${id}-blueprint`; 43 | new blueprints.EksBlueprint(scope, { id: stackID, addOns, teams, version: 'auto' }, { 44 | env: { 45 | region: 'us-east-2', 46 | }, 47 | }); 48 | } 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /lib/newrelic-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 2 | import { NewRelicAddOn } from '@newrelic/newrelic-eks-blueprints-addon'; 3 | import { Construct } from "constructs"; 4 | 5 | 6 | export default class NewRelicConstruct extends Construct { 7 | constructor(scope: Construct, id: string) { 8 | super(scope, id); 9 | 10 | const stackId = `${id}-blueprint`; 11 | 12 | const addOns: Array = [ 13 | new blueprints.addons.SecretsStoreAddOn(), 14 | new NewRelicAddOn({ 15 | version: "4.2.0-beta", 16 | newRelicClusterName: id, 17 | // Uncomment "awsSecretName" after you create your secret in AWS Secrets Manager. 18 | // Required: nrLicenseKey 19 | // Optional: pixieDeployKey, pixieApiKey 20 | // 21 | // Format: 22 | // { 23 | // "pixieDeployKey": "px-dep-XXXX", 24 | // "pixieApiKey": "px-api-XXXX", 25 | // "nrLicenseKey": "XXXXNRAL" 26 | // } 27 | awsSecretName: "newrelic-pixie-combined", 28 | 29 | // Uncomment "installPixie" and "installPixieIntegration" if installing Pixie. 30 | // installPixie: true, 31 | // installPixieIntegration: true, 32 | 33 | // For additional install options, visit the New Relic addon docs: 34 | // https://github.com/newrelic-experimental/newrelic-eks-blueprints-addon 35 | }) 36 | ]; 37 | 38 | blueprints.EksBlueprint.builder() 39 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 40 | .region(process.env.CDK_DEFAULT_REGION) 41 | .version('auto') 42 | .addOns(...addOns) 43 | .build(scope, stackId); 44 | } 45 | } -------------------------------------------------------------------------------- /lib/paralus-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | import { ParalusAddOn } from '@paralus/paralus-eks-blueprints-addon'; 4 | 5 | export default class ParalusConstruct { 6 | constructor(scope: Construct, id: string) { 7 | // AddOns for the cluster 8 | const stackId = `${id}-blueprint`; 9 | blueprints.EksBlueprint.builder() 10 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 11 | .region(process.env.CDK_DEFAULT_REGION) 12 | .addOns( 13 | new blueprints.AwsLoadBalancerControllerAddOn(), 14 | new blueprints.VpcCniAddOn(), 15 | new blueprints.KubeProxyAddOn(), 16 | new blueprints.EbsCsiDriverAddOn(), 17 | new blueprints.CertManagerAddOn(), 18 | new ParalusAddOn({ 19 | namespace: 'paralus-system', 20 | // this signifies the paralus version to be deployed 21 | version: '0.2.3', 22 | // this flag deploys kratos in dev mode, install postgres, by default it is true 23 | development: true, 24 | /** 25 | * Values to pass to the chart as per https://github.com/paralus/helm-charts/blob/main/charts/ztka/values.yaml. 26 | */ 27 | // update this to your domain, as paralus works based on domain based routing 28 | values: { 29 | "fqdn": { 30 | "domain": "your-own-domain-name", 31 | "hostname": "console-eks", 32 | "coreConnectorSubdomain": "*.core-connector.eks", 33 | "userSubdomain": "*.user.eks" 34 | } 35 | } 36 | }) 37 | ) 38 | .teams()// add teams here) 39 | .version('auto') 40 | .build(scope, stackId); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/rafay-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 2 | import * as rafayAddOn from '@rafaysystems/rafay-eks-blueprints-addon'; 3 | import { prevalidateSecrets } from '../common/construct-utils'; 4 | import * as cdk from 'aws-cdk-lib'; 5 | 6 | export default class RafayConstruct { 7 | async buildAsync(scope: cdk.App, id: string) { 8 | let rafayConfig = { 9 | organizationName: "rafay-eks-org-1", // replace with your organization Name 10 | email: "abc@example.com", // replace with your email 11 | firstName: "John", // replace with your first Name 12 | lastName: "Doe", // replace with your last Name 13 | passwordSecret: "rafay-password-json", // replace with a secret name in secrets manager that you have created, must contain a single field "password" 14 | clusterName: "eks-cluster-1", // replace with the name that you want the cluster to be created in Rafay Console 15 | blueprintName: "minimal" 16 | } as rafayAddOn.RafayConfig; 17 | 18 | await prevalidateSecrets(RafayConstruct.name, undefined, rafayConfig.passwordSecret!); 19 | const stackId = `${id}-blueprint`; 20 | 21 | const addOns: Array = [ 22 | new rafayAddOn.RafayClusterAddOn(rafayConfig) 23 | ]; 24 | blueprints.EksBlueprint.builder() 25 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 26 | .region(process.env.CDK_DEFAULT_REGION) 27 | .addOns(...addOns) 28 | .version('auto') 29 | .build(scope, stackId); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/secure-ingress-auth-cognito/lambda/lambda_function.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import boto3 4 | 5 | def lambda_handler(event, context): 6 | print("Received event: " + json.dumps(event, indent=2)) 7 | 8 | ssmclient = boto3.client('ssm') 9 | 10 | try: 11 | paramName = '/secure-ingress-auth-cognito/ALLOWED_DOMAINS' 12 | resp = ssmclient.get_parameter(Name=paramName) 13 | allowed_domains_list = resp['Parameter']['Value'] 14 | 15 | except Exception as e: 16 | print("Error in reading the SSM Parameter Store : {}".format(str(e))) 17 | 18 | triggerSource = event['triggerSource'] 19 | 20 | # Split the email address so we can compare domains 21 | emailId = event['request']['userAttributes']['email'] 22 | address = emailId.split('@') 23 | #print("address={} allowed_domains_list={} auto_approved_domains_list={} email_allow_list={}".format(address, allowed_domains_list, auto_approved_domains_list, email_white_list)) 24 | 25 | emailDomain = address[1] 26 | 27 | print("Running the Validation for {} flow".format(triggerSource)) 28 | 29 | if triggerSource == 'PreSignUp_SignUp': 30 | # It sets the user pool autoConfirmUser flag after validating the email domain 31 | event['response']['autoConfirmUser'] = False 32 | 33 | # This example uses a custom attribute 'custom:domain' 34 | if emailDomain not in allowed_domains_list: 35 | raise Exception("Cannot register users with email domains other than allowed domains list={}".format(allowed_domains_list)) 36 | else: 37 | print("triggerSource={} is incorrect".format(triggerSource)) 38 | 39 | #print("Received event: " + json.dumps(event, indent=2)) 40 | 41 | return event 42 | -------------------------------------------------------------------------------- /lib/security/eks-config-rules/index.ts: -------------------------------------------------------------------------------- 1 | import * as defaultKubeVersion from "@aws-quickstart/eks-blueprints/dist/stacks"; 2 | import * as config from "aws-cdk-lib/aws-config"; 3 | import { Construct } from "constructs"; 4 | import { Stack, StackProps } from "aws-cdk-lib"; 5 | 6 | 7 | // Enable the AWS Config Managed Rules for EKS Security Best Pratices 8 | export class EksConfigRulesSetup extends Stack { 9 | constructor(scope: Construct, id: string, props?: StackProps) { 10 | super(scope, id, props); 11 | 12 | // Get the default kubernetes version used by the CDK EKS Blueprints framework. 13 | const defaultKubeVerison = defaultKubeVersion.DEFAULT_VERSION; 14 | 15 | // Checks if an Amazon Elastic Kubernetes Service (EKS) cluster is running a supported Kubernetes version. 16 | new config.ManagedRule(this, "EksOldestSupportedVersion", { 17 | identifier: 18 | config.ManagedRuleIdentifiers.EKS_CLUSTER_OLDEST_SUPPORTED_VERSION, 19 | inputParameters: { 20 | oldestVersionSupported: defaultKubeVerison, // Set to the default cluster version used by CDK EKS Blueprints. 21 | }, 22 | }); 23 | 24 | // Checks whether Amazon Elastic Kubernetes Service (Amazon EKS) endpoint is not publicly accessible. 25 | new config.ManagedRule(this, "EksSupportedVersion", { 26 | identifier: config.ManagedRuleIdentifiers.EKS_CLUSTER_SUPPORTED_VERSION, 27 | inputParameters: { 28 | oldestVersionSupported: defaultKubeVerison, // Set to the default cluster version used by CDK EKS Blueprints. 29 | }, 30 | }); 31 | 32 | // Checks whether Amazon Elastic Kubernetes Service (Amazon EKS) endpoint is not publicly accessible. 33 | new config.ManagedRule(this, "EksEndpointNoPublicAccess", { 34 | identifier: config.ManagedRuleIdentifiers.EKS_ENDPOINT_NO_PUBLIC_ACCESS, 35 | }); 36 | 37 | // Checks whether Amazon Elastic Kubernetes Service clusters are configured to have Kubernetes secrets encrypted using AWS Key Management Service (KMS) keys. 38 | new config.ManagedRule(this, "EksSecretsEncrypted", { 39 | identifier: config.ManagedRuleIdentifiers.EKS_SECRETS_ENCRYPTED, 40 | }); 41 | } 42 | } -------------------------------------------------------------------------------- /lib/security/guardduty-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from "constructs"; 2 | import * as blueprints from "@aws-quickstart/eks-blueprints"; 3 | import { SECRET_ARGO_ADMIN_PWD } from "../../multi-region-construct"; 4 | import { prevalidateSecrets } from "../../common/construct-utils"; 5 | 6 | const gitUrl = "https://github.com/aws-samples/eks-blueprints-workloads.git"; 7 | const targetRevision = "main"; 8 | 9 | export default class GuardDutyWorkloadConstruct { 10 | async buildAsync(scope: Construct, id: string) { 11 | await prevalidateSecrets( 12 | GuardDutyWorkloadConstruct.name, 13 | process.env.CDK_DEFAULT_REGION!, 14 | SECRET_ARGO_ADMIN_PWD 15 | ); 16 | 17 | const stackID = `${id}-blueprint`; 18 | 19 | await blueprints.EksBlueprint.builder() 20 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 21 | .region(process.env.CDK_DEFAULT_REGION!) 22 | .addOns( 23 | new blueprints.ArgoCDAddOn({ 24 | bootstrapRepo: { 25 | repoUrl: gitUrl, 26 | targetRevision: targetRevision, 27 | path: "teams/team-danger/dev", 28 | }, 29 | adminPasswordSecretName: SECRET_ARGO_ADMIN_PWD, 30 | }) 31 | ) 32 | .teams() 33 | .version('auto') 34 | .buildAsync(scope, stackID); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/security/image-vulnerability-scanning/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from "constructs"; 2 | import * as blueprints from "@aws-quickstart/eks-blueprints"; 3 | import { SECRET_ARGO_ADMIN_PWD } from "../../multi-region-construct"; 4 | import { prevalidateSecrets } from "../../common/construct-utils"; 5 | import * as team from "../../teams/team-scan"; 6 | import * as ecr from "aws-cdk-lib/aws-ecr"; 7 | 8 | const gitUrl = "https://github.com/aws-samples/eks-blueprints-workloads.git"; 9 | const targetRevision = "main"; 10 | 11 | export default class ImageScanningWorkloadConstruct { 12 | async buildAsync(scope: Construct, id: string) { 13 | 14 | await prevalidateSecrets(ImageScanningWorkloadConstruct.name, process.env.CDK_DEFAULT_REGION!, SECRET_ARGO_ADMIN_PWD); 15 | 16 | const ecrRepositoryName = "ImageScanningRepository"; 17 | const ecrRepository = blueprints.getNamedResource( 18 | ecrRepositoryName 19 | ) as ecr.Repository; 20 | 21 | const stackID = `${id}-blueprint`; 22 | await blueprints.EksBlueprint.builder() 23 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 24 | .region(process.env.CDK_DEFAULT_REGION!) 25 | .resourceProvider( 26 | ecrRepositoryName, 27 | new EcrResourceProvider(ecrRepositoryName) 28 | ) 29 | .addOns( 30 | new blueprints.ArgoCDAddOn({ 31 | bootstrapRepo: { 32 | repoUrl: gitUrl, 33 | targetRevision: targetRevision, 34 | path: "teams/team-scan/dev", 35 | }, 36 | bootstrapValues: { 37 | spec: { 38 | repositoryUri: ecrRepository.repositoryUri, 39 | region: process.env.CDK_DEFAULT_REGION!, 40 | }, 41 | }, 42 | adminPasswordSecretName: SECRET_ARGO_ADMIN_PWD, 43 | }) 44 | ) 45 | .teams(new team.TeamScan()) 46 | .version('auto') 47 | .buildAsync(scope, stackID); 48 | } 49 | } 50 | 51 | class EcrResourceProvider implements blueprints.ResourceProvider { 52 | 53 | public constructor(private readonly ecrRepositoryName: string) { 54 | this.ecrRepositoryName = ecrRepositoryName; 55 | } 56 | 57 | provide(context: blueprints.ResourceContext): ecr.IRepository { 58 | const repository = new ecr.Repository( 59 | context.scope, 60 | this.ecrRepositoryName, 61 | { 62 | encryption: ecr.RepositoryEncryption.AES_256, 63 | } 64 | ); 65 | return repository; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/security/securityhub-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as securityhub from 'aws-cdk-lib/aws-securityhub'; 2 | import { Construct } from "constructs"; 3 | import { Stack, StackProps } from "aws-cdk-lib"; 4 | 5 | export class SecurityHubStackSetup extends Stack { 6 | constructor(scope: Construct, id: string, props?: StackProps) { 7 | super(scope, id, props); 8 | 9 | // Enable Security Hub 10 | new securityhub.CfnHub(this, 'MyCfnHub'); 11 | } 12 | } -------------------------------------------------------------------------------- /lib/snyk-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 2 | import { SnykMonitorAddOn } from '@snyk-partners/snyk-monitor-eks-blueprints-addon'; 3 | import { Construct } from "constructs"; 4 | 5 | export default class SnykConstruct extends Construct { 6 | constructor(scope: Construct, id: string) { 7 | super(scope, id); 8 | 9 | const stackId = `${id}-blueprint`; 10 | 11 | const addOns: Array = [ 12 | new SnykMonitorAddOn({ 13 | version: "1.87.2", // replace with the version you wish to deploy 14 | integrationId: "", // replace with your integration ID 15 | values: {} // add any custom Helm values 16 | }) 17 | ]; 18 | 19 | blueprints.EksBlueprint.builder() 20 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 21 | .region(process.env.CDK_DEFAULT_REGION) 22 | .addOns(...addOns) 23 | .version('auto') 24 | .build(scope, stackId); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/starter-construct/index.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 3 | 4 | 5 | 6 | /** 7 | * Example starter with placeholders to add addOns and teams. 8 | */ 9 | export default class StarterConstruct { 10 | build(scope: Construct, id: string) { 11 | 12 | const stackID = `${id}-blueprint`; 13 | blueprints.EksBlueprint.builder() 14 | .addOns( 15 | new blueprints.AwsLoadBalancerControllerAddOn, 16 | new blueprints.VpcCniAddOn(), 17 | new blueprints.MetricsServerAddOn, 18 | new blueprints.ClusterAutoScalerAddOn, 19 | ) 20 | .teams() 21 | .version('auto') 22 | .build(scope, stackID); 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/teams/index.ts: -------------------------------------------------------------------------------- 1 | export { TeamBurnhamSetup } from "./team-burnham"; 2 | export { TeamPlatform } from "./team-platform"; 3 | export { TeamRikerSetup } from "./team-riker"; 4 | export { TeamTroiSetup } from "./team-troi"; 5 | export { dataTeam } from "./team-emr-on-eks"; 6 | export { TeamScan } from "./team-scan"; 7 | export { batchTeam } from './team-batch'; 8 | -------------------------------------------------------------------------------- /lib/teams/multi-account-monitoring/index.ts: -------------------------------------------------------------------------------- 1 | export { TeamGeordi } from './team-geordi'; 2 | export { CorePlatformTeam } from './team-platform'; 3 | -------------------------------------------------------------------------------- /lib/teams/multi-account-monitoring/team-geordi.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationTeam } from '@aws-quickstart/eks-blueprints'; 2 | 3 | export class TeamGeordi extends ApplicationTeam { 4 | constructor() { 5 | super({ 6 | name: `team-geordi`, 7 | namespace: 'geordie', 8 | }); 9 | } 10 | } -------------------------------------------------------------------------------- /lib/teams/multi-account-monitoring/team-platform.ts: -------------------------------------------------------------------------------- 1 | import { ClusterInfo, PlatformTeam } from '@aws-quickstart/eks-blueprints'; 2 | import { ArnPrincipal, IRole } from 'aws-cdk-lib/aws-iam'; 3 | 4 | export class CorePlatformTeam extends PlatformTeam { 5 | constructor() { 6 | super({ 7 | name: `team-platform` 8 | }); 9 | } 10 | 11 | protected getOrCreateRole(clusterInfo: ClusterInfo, users: ArnPrincipal[], roleArn?: string | undefined): IRole | undefined { 12 | return super.getOrCreateRole(clusterInfo, users, roleArn ?? `arn:aws:iam::${clusterInfo.cluster.stack.account}:role/Admin`); 13 | } 14 | } -------------------------------------------------------------------------------- /lib/teams/pipeline-multi-env-gitops/index.ts: -------------------------------------------------------------------------------- 1 | export { BackendCrystalTeam } from './team-backend-crystal'; 2 | export { FrontendTeam } from './team-backend-frontend'; 3 | export { BackendNodejsTeam } from './team-backend-nodejs'; 4 | export { CorePlatformTeam } from './team-platform'; 5 | 6 | -------------------------------------------------------------------------------- /lib/teams/pipeline-multi-env-gitops/team-backend-crystal.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationTeam } from '@aws-quickstart/eks-blueprints'; 2 | import { ArnPrincipal } from 'aws-cdk-lib/aws-iam'; 3 | 4 | export class BackendCrystalTeam extends ApplicationTeam { 5 | constructor(accountID: string, environment: string) { 6 | super({ 7 | name: `backend-crystal-${environment}`, 8 | users: [ 9 | new ArnPrincipal(`arn:aws:iam::${accountID}:user/crystal-user`), 10 | ], 11 | namespace: 'ecsdemo-crystal', 12 | }); 13 | } 14 | } -------------------------------------------------------------------------------- /lib/teams/pipeline-multi-env-gitops/team-backend-frontend.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationTeam } from '@aws-quickstart/eks-blueprints'; 2 | import { ArnPrincipal } from 'aws-cdk-lib/aws-iam'; 3 | 4 | export class FrontendTeam extends ApplicationTeam { 5 | constructor(accountID: string, environment: string) { 6 | super({ 7 | name: `frontend-${environment}`, 8 | users: [ 9 | new ArnPrincipal(`arn:aws:iam::${accountID}:user/frontend-user`), 10 | ], 11 | namespace: 'ecsdemo-frontend', 12 | }); 13 | } 14 | } -------------------------------------------------------------------------------- /lib/teams/pipeline-multi-env-gitops/team-backend-nodejs.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationTeam } from '@aws-quickstart/eks-blueprints'; 2 | import { ArnPrincipal } from 'aws-cdk-lib/aws-iam'; 3 | 4 | export class BackendNodejsTeam extends ApplicationTeam { 5 | constructor(accountID: string, environment: string) { 6 | super({ 7 | name: `backend-nodejs-${environment}`, 8 | users: [ 9 | new ArnPrincipal(`arn:aws:iam::${accountID}:user/nodejs-user`), 10 | ], 11 | namespace: 'ecsdemo-nodejs', 12 | 13 | }); 14 | } 15 | } -------------------------------------------------------------------------------- /lib/teams/pipeline-multi-env-gitops/team-platform.ts: -------------------------------------------------------------------------------- 1 | import { PlatformTeam } from '@aws-quickstart/eks-blueprints'; 2 | import { ArnPrincipal } from 'aws-cdk-lib/aws-iam'; 3 | 4 | export class CorePlatformTeam extends PlatformTeam { 5 | constructor(accountID: string, environment: string) { 6 | super({ 7 | name: `platform-${environment}`, 8 | users: [ 9 | new ArnPrincipal(`arn:aws:iam::${accountID}:user/platform-user`), 10 | ], 11 | }); 12 | } 13 | } -------------------------------------------------------------------------------- /lib/teams/team-batch/index.ts: -------------------------------------------------------------------------------- 1 | import { BatchEksTeam, BatchEnvType, BatchAllocationStrategy } from "@aws-quickstart/eks-blueprints"; 2 | 3 | export const batchTeam = new BatchEksTeam({ 4 | name: "batch-team-a", 5 | namespace: "aws-batch", 6 | envName: "batch-team-a-comp-env", 7 | computeResources:{ 8 | envType: BatchEnvType.EC2, 9 | allocationStrategy: BatchAllocationStrategy.BEST, 10 | priority: 10, 11 | minvCpus: 1, 12 | maxvCpus: 128, 13 | instanceTypes: ["m5", "c4.2xlarge"] 14 | }, 15 | jobQueueName: "batch-team-a-job-queue" 16 | }); -------------------------------------------------------------------------------- /lib/teams/team-burnham/index.ts: -------------------------------------------------------------------------------- 1 | import { ArnPrincipal } from 'aws-cdk-lib/aws-iam'; 2 | import { Construct } from 'constructs'; 3 | import { ApplicationTeam, GenerateSecretManagerProvider } from '@aws-quickstart/eks-blueprints'; 4 | 5 | function getUserArns(scope: Construct, key: string): ArnPrincipal[] { 6 | const context: string = scope.node.tryGetContext(key); 7 | if (context) { 8 | return context.split(",").map(e => new ArnPrincipal(e)); 9 | } 10 | return []; 11 | } 12 | 13 | export class TeamBurnhamSetup extends ApplicationTeam { 14 | constructor(scope: Construct, teamManifestDir: string) { 15 | super({ 16 | name: "burnham", 17 | users: getUserArns(scope, "team-burnham.users"), 18 | namespaceAnnotations: { 19 | "appmesh.k8s.aws/sidecarInjectorWebhook": "enabled" 20 | }, 21 | teamSecrets: [ 22 | { 23 | secretProvider: new GenerateSecretManagerProvider('auth-password-id','AuthPassword' + (+new Date())), 24 | kubernetesSecret: { 25 | secretName: 'auth-password', 26 | data: [ 27 | { 28 | key: 'password' 29 | } 30 | ] 31 | } 32 | } 33 | ], 34 | teamManifestDir: teamManifestDir 35 | }); 36 | } 37 | } -------------------------------------------------------------------------------- /lib/teams/team-burnham/restrict-ingress-egress-burnham.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: restrict-ingress-egress-burnham 5 | namespace: team-burnham 6 | spec: 7 | podSelector: {} 8 | policyTypes: 9 | - Ingress 10 | - Egress 11 | ingress: 12 | - from: 13 | - namespaceSelector: 14 | matchLabels: 15 | name: team-riker 16 | ports: 17 | - protocol: TCP 18 | port: 80 19 | egress: 20 | - to: 21 | - namespaceSelector: 22 | matchLabels: 23 | name: team-troi 24 | ports: 25 | - protocol: TCP 26 | port: 53 27 | - protocol: UDP 28 | port: 53 29 | -------------------------------------------------------------------------------- /lib/teams/team-emr-on-eks/index.ts: -------------------------------------------------------------------------------- 1 | import { EmrEksTeam } from '@aws-quickstart/eks-blueprints'; 2 | import { PolicyStatement } from 'aws-cdk-lib/aws-iam'; 3 | 4 | 5 | const executionRolePolicyStatement: PolicyStatement[] = [ 6 | new PolicyStatement({ 7 | actions: ['logs:PutLogEvents', 'logs:CreateLogStream', 'logs:DescribeLogGroups', 'logs:DescribeLogStreams'], 8 | resources: ['arn:aws:logs:*:*:*'], 9 | }), 10 | ]; 11 | 12 | export const dataTeam = new EmrEksTeam({ 13 | name: 'emr-data-team-a', 14 | virtualClusterName: 'emr-data-team-a', 15 | virtualClusterNamespace: 'batchjob', 16 | createNamespace: true, 17 | executionRoles: [ 18 | { 19 | executionRoleIamPolicyStatement: executionRolePolicyStatement, 20 | executionRoleName: 'myBlueprintExecRole' 21 | } 22 | ] 23 | }); 24 | -------------------------------------------------------------------------------- /lib/teams/team-platform/index.ts: -------------------------------------------------------------------------------- 1 | import { ArnPrincipal } from "aws-cdk-lib/aws-iam"; 2 | 3 | import { PlatformTeam } from '@aws-quickstart/eks-blueprints'; 4 | 5 | export class TeamPlatform extends PlatformTeam { 6 | constructor(accountID: string) { 7 | super({ 8 | name: "platform", 9 | users: [new ArnPrincipal(`arn:aws:iam::${accountID}:user/superadmin`)], 10 | }); 11 | } 12 | } -------------------------------------------------------------------------------- /lib/teams/team-riker/index.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationTeam } from '@aws-quickstart/eks-blueprints'; 2 | import { Construct } from 'constructs'; 3 | import { ArnPrincipal } from 'aws-cdk-lib/aws-iam'; 4 | 5 | function getUserArns(scope: Construct, key: string): ArnPrincipal[] { 6 | const context: string = scope.node.tryGetContext(key); 7 | if (context) { 8 | return context.split(",").map(e => new ArnPrincipal(e)); 9 | } 10 | return []; 11 | } 12 | 13 | export class TeamRikerSetup extends ApplicationTeam { 14 | constructor(scope: Construct, teamManifestDir: string) { 15 | super({ 16 | name: "riker", 17 | users: getUserArns(scope, "team-riker.users"), 18 | teamManifestDir: teamManifestDir, 19 | namespaceHardLimits: { 20 | 'requests.cpu': '0.5', 21 | 'requests.memory': '1Gi', 22 | 'limits.cpu': '1', 23 | 'limits.memory': '2Gi' 24 | } 25 | }); 26 | } 27 | } -------------------------------------------------------------------------------- /lib/teams/team-riker/restrict-ingress-egress-riker.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: restrict-ingress-egress-riker 5 | namespace: team-riker 6 | spec: 7 | podSelector: {} 8 | policyTypes: 9 | - Ingress 10 | - Egress 11 | ingress: 12 | - from: 13 | - namespaceSelector: 14 | matchLabels: 15 | name: team-troi 16 | ports: 17 | - protocol: TCP 18 | port: 80 19 | egress: 20 | - to: 21 | - namespaceSelector: 22 | matchLabels: 23 | name: team-burnham 24 | ports: 25 | - protocol: TCP 26 | port: 53 27 | - protocol: UDP 28 | port: 53 -------------------------------------------------------------------------------- /lib/teams/team-scan/index.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationTeam, ClusterInfo } from "@aws-quickstart/eks-blueprints"; 2 | import * as iam from "aws-cdk-lib/aws-iam"; 3 | 4 | export class TeamScan extends ApplicationTeam { 5 | constructor() { 6 | super({ 7 | name: `team-scan`, 8 | namespace: "scan", 9 | }); 10 | } 11 | 12 | protected setupServiceAccount(clusterInfo: ClusterInfo) { 13 | super.setupServiceAccount(clusterInfo); 14 | const ecrIamPolicy = new iam.PolicyStatement({ 15 | actions: ["ecr:*"], 16 | resources: ["*"], 17 | }); 18 | this.serviceAccount.addToPrincipalPolicy(ecrIamPolicy); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/teams/team-troi/index.ts: -------------------------------------------------------------------------------- 1 | import * as cdk from 'aws-cdk-lib'; 2 | import * as eks from "aws-cdk-lib/aws-eks"; 3 | import * as s3 from "aws-cdk-lib/aws-s3"; 4 | 5 | import { ClusterInfo, Team } from '@aws-quickstart/eks-blueprints'; 6 | 7 | export class TeamTroiSetup implements Team { 8 | readonly name: string = 'team-troi'; 9 | 10 | setup(clusterInfo: ClusterInfo) { 11 | const cluster = clusterInfo.cluster; 12 | const stack = cluster.stack; 13 | const namespace = cluster.addManifest(this.name, { 14 | apiVersion: 'v1', 15 | kind: 'Namespace', 16 | metadata: { 17 | name: this.name, 18 | annotations: { "argocd.argoproj.io/sync-wave": "-1" } 19 | } 20 | }); 21 | 22 | this.setupNamespacePolicies(cluster); 23 | 24 | const sa = cluster.addServiceAccount('inf-backend', { name: 'inf-backend', namespace: this.name }); 25 | sa.node.addDependency(namespace); 26 | const bucket = new s3.Bucket(stack, 'inf-backend-bucket'); 27 | bucket.grantReadWrite(sa); 28 | new cdk.CfnOutput(stack, this.name + '-sa-iam-role', { value: sa.role.roleArn }); 29 | } 30 | 31 | setupNamespacePolicies(cluster: eks.ICluster) { 32 | const quotaName = this.name + "-quota"; 33 | cluster.addManifest(quotaName, { 34 | apiVersion: 'v1', 35 | kind: 'ResourceQuota', 36 | metadata: { name: quotaName }, 37 | spec: { 38 | hard: { 39 | 'requests.cpu': '10', 40 | 'requests.memory': '10Gi', 41 | 'limits.cpu': '20', 42 | 'limits.memory': '20Gi' 43 | } 44 | } 45 | }); 46 | } 47 | } -------------------------------------------------------------------------------- /lib/windows-construct/vpc-cni/index.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 2 | import { KubernetesManifest } from 'aws-cdk-lib/aws-eks'; 3 | import { Construct } from 'constructs'; 4 | 5 | export class WindowsVpcCni implements blueprints.ClusterAddOn { 6 | id: "amazon-vpc-cni"; 7 | 8 | deploy(clusterInfo: blueprints.ClusterInfo): void | Promise { 9 | const cluster = clusterInfo.cluster; 10 | const configmap = new KubernetesManifest(cluster, 'amazon-vpc-cni', { cluster: cluster, 11 | manifest : [{ 12 | apiVersion: "v1", 13 | kind: "ConfigMap", 14 | metadata: { 15 | name: "amazon-vpc-cni", 16 | namespace: "kube-system", 17 | }, 18 | data:{ 19 | "enable-windows-ipam": "true" 20 | }, 21 | }], overwrite: true }); 22 | 23 | return Promise.resolve(configmap); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /lib/workloads-codecommit-construct/codecommit-credentials.ts: -------------------------------------------------------------------------------- 1 | import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId, PhysicalResourceIdReference } from 'aws-cdk-lib/custom-resources'; 2 | import { Construct } from 'constructs'; 3 | 4 | export class CodeCommitCredentials extends Construct { 5 | readonly serviceSpecificCredentialId: string; 6 | readonly serviceName: string; 7 | readonly serviceUserName: string; 8 | readonly servicePassword: string; 9 | readonly status: string; 10 | 11 | constructor(scope: Construct, id: string, userName: string) { 12 | super(scope, id); 13 | 14 | const codeCommitCredentialsResponse = new AwsCustomResource(this, "codecommit-credentials-custom-resource", { 15 | onCreate: { 16 | service: "IAM", 17 | action: "createServiceSpecificCredential", 18 | parameters: { 19 | ServiceName: "codecommit.amazonaws.com", 20 | UserName: userName 21 | }, 22 | physicalResourceId: PhysicalResourceId.fromResponse("ServiceSpecificCredential.ServiceSpecificCredentialId") 23 | }, 24 | onDelete: { 25 | service: "IAM", 26 | action: "deleteServiceSpecificCredential", 27 | parameters: { 28 | ServiceSpecificCredentialId: new PhysicalResourceIdReference(), 29 | UserName: userName, 30 | } 31 | }, 32 | policy: AwsCustomResourcePolicy.fromSdkCalls({ 33 | resources: AwsCustomResourcePolicy.ANY_RESOURCE, 34 | }), 35 | }); 36 | 37 | this.serviceSpecificCredentialId = codeCommitCredentialsResponse.getResponseField("ServiceSpecificCredential.ServiceSpecificCredentialId"); 38 | this.serviceName = codeCommitCredentialsResponse.getResponseField("ServiceSpecificCredential.ServiceName"); 39 | this.serviceUserName = codeCommitCredentialsResponse.getResponseField("ServiceSpecificCredential.ServiceUserName"); 40 | this.servicePassword = codeCommitCredentialsResponse.getResponseField("ServiceSpecificCredential.ServicePassword"); 41 | this.status = codeCommitCredentialsResponse.getResponseField("ServiceSpecificCredential.Status"); 42 | } 43 | } -------------------------------------------------------------------------------- /lib/workloads-codecommit-construct/index.ts: -------------------------------------------------------------------------------- 1 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 2 | import { Construct } from 'constructs'; 3 | import WorkloadsCodeCommitRepoStack from './workloads-codecommit-repo-stack'; 4 | 5 | /** 6 | * Demonstrates how to use AWS CodeCommmit as a repository for ArgoCD workloads. 7 | */ 8 | 9 | export default class WorkloadsCodeCommitConstruct extends Construct { 10 | constructor(scope: Construct, id: string) { 11 | super(scope, id); 12 | 13 | const region = process.env.CDK_DEFAULT_REGION!; 14 | 15 | const userName = 'argocd-cc'; 16 | const repoName = 'eks-blueprints-workloads-cc'; 17 | 18 | const repoUrl = 'https://git-codecommit.' + region + '.amazonaws.com/v1/repos/' + repoName; 19 | 20 | const stackId = `${id}-blueprint`; 21 | 22 | const bootstrapRepo : blueprints.ApplicationRepository = { 23 | repoUrl, 24 | targetRevision: 'main', 25 | credentialsSecretName: repoName + '-codecommit-secret', 26 | credentialsType: 'TOKEN' 27 | }; 28 | 29 | const addOns: Array = [ 30 | new blueprints.NestedStackAddOn({ 31 | builder: WorkloadsCodeCommitRepoStack.builder(userName, repoName), 32 | id: repoName + "-codecommit-repo-nested-stack" 33 | }), 34 | new blueprints.SecretsStoreAddOn, 35 | new blueprints.ArgoCDAddOn({ 36 | bootstrapRepo: { 37 | ...bootstrapRepo, 38 | path: 'envs/dev' 39 | }, 40 | values: { 41 | server: { 42 | service: { 43 | type: "LoadBalancer" 44 | } 45 | } 46 | } 47 | }) 48 | ]; 49 | 50 | blueprints.EksBlueprint.builder() 51 | .account(process.env.CDK_DEFAULT_ACCOUNT!) 52 | .region(process.env.CDK_DEFAULT_REGION) 53 | .addOns(...addOns) 54 | 55 | .version('auto') 56 | .build(scope, stackId); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/workloads-codecommit-construct/lambda/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | const https = require('https'); // eslint-disable-line 3 | 4 | /* webhook payload 5 | { 6 | "ref": "refs/heads/main", 7 | "repository": { 8 | "html_url": "https://git-codecommit.us-west-2.amazonaws.com/v1/repos/eks-blueprints-workloads-cc", 9 | "default_branch": "main" 10 | } 11 | } 12 | */ 13 | 14 | exports.handler = async function(event) { 15 | const eventSourceARNarray = event.Records[0].eventSourceARN.split(':'); 16 | const repoName = eventSourceARNarray[eventSourceARNarray.length - 1]; 17 | const ref = event.Records[0].codecommit.references[0].ref; 18 | const refArray = ref.split('/'); 19 | const branch = refArray[refArray.length - 1]; 20 | const data = JSON.stringify({ 21 | "ref": ref, 22 | "repository": { 23 | "html_url": "https://git-codecommit." + event.Records[0].awsRegion + ".amazonaws.com/v1/repos/" + repoName, 24 | "default_branch": branch 25 | } 26 | }); 27 | console.log(data); 28 | 29 | const options = { 30 | hostname: event.Records[0].customData, 31 | path: '/api/webhook', 32 | method: 'POST', 33 | port: 443, 34 | headers: { 35 | 'Content-Type': 'application/json', 36 | 'X-GitHub-Event': 'push', 37 | 'Content-Length': data.length, 38 | }, 39 | }; 40 | 41 | const promise = new Promise(function(resolve, reject) { 42 | process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; 43 | const req = https.request(options, (res) => { 44 | resolve(res.statusCode); 45 | }).on('error', (e) => { 46 | reject(Error(e)); 47 | }); 48 | req.write(data); 49 | req.end(); 50 | }); 51 | return promise; 52 | }; -------------------------------------------------------------------------------- /lib/workloads-codecommit-construct/workloads-codecommit-repo-stack.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import { NestedStack, NestedStackProps, SecretValue } from 'aws-cdk-lib'; 3 | import * as blueprints from '@aws-quickstart/eks-blueprints'; 4 | import * as codecommit from 'aws-cdk-lib/aws-codecommit'; 5 | import * as iam from 'aws-cdk-lib/aws-iam'; 6 | import * as lambda from 'aws-cdk-lib/aws-lambda'; 7 | import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager'; 8 | import { CodeCommitCredentials } from './codecommit-credentials'; 9 | 10 | export default class WorkloadsCodeCommitRepoStack extends NestedStack { 11 | public static builder(userName: string, repoName: string): blueprints.NestedStackBuilder { 12 | return { 13 | build(scope: Construct, id: string, props: NestedStackProps) { 14 | return new WorkloadsCodeCommitRepoStack(scope, id, props, userName, repoName); 15 | } 16 | }; 17 | } 18 | 19 | constructor(scope: Construct, id: string, props: NestedStackProps, userName: string, repoName: string) { 20 | super(scope, id); 21 | 22 | const repo = new codecommit.Repository(this, repoName + '-codecommit-repo', { 23 | repositoryName: repoName, 24 | }); 25 | 26 | const user = new iam.User(this, userName + '-user-name', { 27 | userName: userName, 28 | }); 29 | repo.grantPull(user); 30 | 31 | const credentials = new CodeCommitCredentials(this, "codecommit-credentials", user.userName); 32 | credentials.node.addDependency(user); 33 | 34 | new secretsmanager.Secret(this, 'codecommit-secret', { 35 | secretObjectValue: { 36 | username: SecretValue.unsafePlainText(credentials.serviceUserName), 37 | password: SecretValue.unsafePlainText(credentials.servicePassword), 38 | url: SecretValue.unsafePlainText(repo.repositoryCloneUrlHttp) 39 | }, 40 | secretName: repoName + '-codecommit-secret' 41 | }); 42 | 43 | const fn = new lambda.Function(this, repoName + '-webhook', { 44 | runtime: lambda.Runtime.NODEJS_20_X, 45 | functionName: repoName + '-webhook', 46 | description: 'Webhook for ArgoCD on commit to AWS CodeCommit', 47 | handler: 'index.handler', 48 | code: lambda.Code.fromAsset("lib/workloads-codecommit-construct/lambda"), 49 | }); 50 | 51 | const principal = new iam.ServicePrincipal('codecommit.amazonaws.com'); 52 | fn.grantInvoke(principal); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eks-blueprints-patterns", 3 | "version": "1.2.0", 4 | "main": "dist/lib/common/default-main.js", 5 | "types": "dist/lib/common/default-main.d.ts", 6 | "scripts": { 7 | "build": "rm -rf dist && tsc --skipLibCheck", 8 | "watch": "tsc -w", 9 | "test": "jest", 10 | "cdk": "cdk", 11 | "nginx": "cdk --app \"npx ts-node bin/nginx.ts\"", 12 | "lint": "npx eslint . --ext .js,.jsx,.ts,.tsx" 13 | }, 14 | "devDependencies": { 15 | "@types/jest": "^29.5.11", 16 | "@types/node": "^22.7.9", 17 | "@typescript-eslint/eslint-plugin": "^8.11.0", 18 | "@typescript-eslint/parser": "^8.11.0", 19 | "copyfiles": "^2.4.1", 20 | "eslint": "^8.56.0", 21 | "jest": "^29.7.0", 22 | "ts-jest": "^29.1.1", 23 | "ts-node": "^10.9.2", 24 | "typescript": "^5.3.3" 25 | }, 26 | "dependencies": { 27 | "@aws-quickstart/eks-blueprints": "1.16.3", 28 | "@aws-sdk/client-config-service": "^3.576.0", 29 | "@aws-sdk/client-eks": "^3.478.0", 30 | "@claranet-ch/konveyor-eks-blueprint-addon": "^1.0.2", 31 | "@datadog/datadog-eks-blueprints-addon": "^0.1.2", 32 | "@dynatrace/dynatrace-eks-blueprints-addon": "^1.4.0-1", 33 | "@granulate/gmaestro-eks-blueprints-addon": "^1.0.16", 34 | "@instana/aws-eks-blueprint-addon": "^1.0.4", 35 | "@kastenhq/kasten-eks-blueprints-addon": "^1.0.1", 36 | "@keptn/keptn-controlplane-eks-blueprints-addon": "^0.5.0", 37 | "@komodor/komodor-eks-blueprints-addon": "^1.2.0", 38 | "@kubecost/kubecost-eks-blueprints-addon": "^0.1.8", 39 | "@newrelic/newrelic-eks-blueprints-addon": "^1.0.9", 40 | "@paralus/paralus-eks-blueprints-addon": "^0.1.5", 41 | "@rafaysystems/rafay-eks-blueprints-addon": "^0.0.2", 42 | "@snyk-partners/snyk-monitor-eks-blueprints-addon": "^1.1.1", 43 | "aws-cdk": "2.173.4", 44 | "aws-cdk-lib": "2.173.4", 45 | "eks-blueprints-cdk-kubeflow-ext": "0.1.9", 46 | "kubeshark": "^0.0.9", 47 | "source-map-support": "^0.5.21" 48 | }, 49 | "overrides": { 50 | "@aws-quickstart/eks-blueprints": "1.16.3", 51 | "aws-cdk": "2.173.4", 52 | "aws-cdk-lib": "2.173.4", 53 | "xml2js": "0.5.0", 54 | "@aws-cdk/core": "../_EXCLUDED_", 55 | "axios": "^1.6.2" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "target": "ES2022", 5 | "module": "commonjs", 6 | "lib": [ 7 | "es2022", 8 | "dom" 9 | ], 10 | "declaration": true, 11 | "strict": true, 12 | "noImplicitAny": true, 13 | "strictNullChecks": true, 14 | "noImplicitThis": true, 15 | "alwaysStrict": true, 16 | "noUnusedLocals": false, 17 | "noUnusedParameters": false, 18 | "noImplicitReturns": true, 19 | "noFallthroughCasesInSwitch": false, 20 | "inlineSourceMap": true, 21 | "inlineSources": true, 22 | "experimentalDecorators": true, 23 | "strictPropertyInitialization": false, 24 | "typeRoots": [ 25 | "./node_modules/@types" 26 | ] 27 | }, 28 | "exclude": [ 29 | "cdk.out", 30 | "node_modules", 31 | "test", 32 | ".git", 33 | "dist" 34 | ], 35 | "include": [ 36 | "bin", 37 | "lib", 38 | "examples" 39 | ] 40 | } --------------------------------------------------------------------------------