├── 601-Build-An-ECR-Repo
├── .gitignore
└── README.md
├── .gitignore
├── 604-Deploy-Container-With-Copilot-CLI
├── .gitignore
├── index.html
├── Dockerfile
└── README.md
├── 607-Fargate-Task-With-Event
├── cdk-AWS-Cookbook-607
│ ├── cdk_aws_cookbook_607
│ │ ├── __init__.py
│ │ └── cdk_aws_cookbook_607_stack.py
│ ├── requirements.txt
│ ├── .gitignore
│ ├── cdk.json
│ ├── app.py
│ ├── source.bat
│ ├── setup.py
│ ├── helper.py
│ └── README.md
├── .gitignore
├── maze.jpg
├── LaunchingFargateTaskOnEvent.png
├── task-execution-assume-role.json
├── policy1.json
├── Docker
│ ├── Dockerfile
│ └── cmd.sh
├── policy2.json
├── targets-template.json
└── README.md
├── 606-Autoscaling-Container-Workloads
├── cdk-AWS-Cookbook-606
│ ├── requirements.txt
│ ├── cdk_aws_cookbook_606
│ │ ├── __init__.py
│ │ └── cdk_aws_cookbook_606_stack.py
│ ├── Docker
│ │ ├── build.sh
│ │ ├── Dockerfile
│ │ ├── README.md
│ │ └── app
│ │ │ ├── WebContent
│ │ │ └── WEB-INF
│ │ │ │ └── web.xml
│ │ │ ├── pom.xml
│ │ │ └── src
│ │ │ └── main
│ │ │ └── java
│ │ │ └── net
│ │ │ └── zengineering
│ │ │ └── LoadtestServlet.java
│ ├── .gitignore
│ ├── cdk.json
│ ├── app.py
│ ├── source.bat
│ ├── setup.py
│ ├── helper.py
│ └── README.md
├── scaling-policy.json
├── task-execution-assume-role.json
└── README.md
├── 605-Updating-Containers-With-BlueGreen
├── cdk-AWS-Cookbook-605
│ ├── cdk_aws_cookbook_605
│ │ ├── __init__.py
│ │ └── cdk_aws_cookbook_605_stack.py
│ ├── requirements.txt
│ ├── DockerBlue
│ │ ├── Dockerfile
│ │ └── index.html
│ ├── DockerGreen
│ │ ├── Dockerfile
│ │ └── index.html
│ ├── .gitignore
│ ├── cdk.json
│ ├── app.py
│ ├── source.bat
│ ├── setup.py
│ ├── helper.py
│ └── README.md
├── .gitignore
├── assume-role-policy.json
├── appspec-template.yaml
├── deployment-template.json
├── codedeploy-template.json
└── README.md
├── 608-Capturing-Logs-From-Containers-Running-On-ECS
├── cdk-AWS-Cookbook-608
│ ├── cdk_aws_cookbook_608
│ │ ├── __init__.py
│ │ └── cdk_aws_cookbook_608_stack.py
│ ├── requirements.txt
│ ├── .gitignore
│ ├── cdk.json
│ ├── app.py
│ ├── source.bat
│ ├── setup.py
│ ├── helper.py
│ └── README.md
├── task-execution-assume-role.json
├── taskdef.json
└── README.md
├── 602-Image-Scanning-In-ECR
├── ContainerImageScanningSolutionWorkflow.png
└── README.md
├── README.md
├── 603-Deploy-Container-With-Lightsail
├── README.md
└── lightsail.json
├── .github
└── ISSUE_TEMPLATE
│ ├── recipe-request.md
│ └── bug_report.md
└── LICENSE
/601-Build-An-ECR-Repo/.gitignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | output.jpg
3 | targets.json
--------------------------------------------------------------------------------
/604-Deploy-Container-With-Copilot-CLI/.gitignore:
--------------------------------------------------------------------------------
1 | copilot/
2 |
--------------------------------------------------------------------------------
/604-Deploy-Container-With-Copilot-CLI/index.html:
--------------------------------------------------------------------------------
1 | Hello AWS Cookbook Reader!
2 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/cdk_aws_cookbook_607/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/requirements.txt:
--------------------------------------------------------------------------------
1 | -e .
2 | boto3
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/requirements.txt:
--------------------------------------------------------------------------------
1 | -e .
2 | boto3
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/.gitignore:
--------------------------------------------------------------------------------
1 | bucketpolicy.json
2 | targets.json
3 | output.jpg
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/cdk_aws_cookbook_605/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/requirements.txt:
--------------------------------------------------------------------------------
1 | -e .
2 | boto3
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/cdk_aws_cookbook_606/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/cdk_aws_cookbook_608/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/requirements.txt:
--------------------------------------------------------------------------------
1 | -e .
2 | boto3
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/.gitignore:
--------------------------------------------------------------------------------
1 | codedeploy.json
2 | deployment.json
3 | appspec.yaml
4 |
--------------------------------------------------------------------------------
/604-Deploy-Container-With-Copilot-CLI/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nginx:latest
2 | COPY index.html /usr/share/nginx/html
3 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/maze.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AWSCookbook/Containers/HEAD/607-Fargate-Task-With-Event/maze.jpg
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/Docker/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | docker build -t mzazon/loadtest:latest .
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/DockerBlue/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM httpd:latest
2 | COPY index.html /usr/local/apache2/htdocs/index.html
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/DockerGreen/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM httpd:latest
2 | COPY index.html /usr/local/apache2/htdocs/index.html
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/LaunchingFargateTaskOnEvent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AWSCookbook/Containers/HEAD/607-Fargate-Task-With-Event/LaunchingFargateTaskOnEvent.png
--------------------------------------------------------------------------------
/602-Image-Scanning-In-ECR/ContainerImageScanningSolutionWorkflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AWSCookbook/Containers/HEAD/602-Image-Scanning-In-ECR/ContainerImageScanningSolutionWorkflow.png
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | package-lock.json
3 | __pycache__
4 | .pytest_cache
5 | .env
6 | .venv
7 | *.egg-info
8 |
9 | # CDK asset staging directory
10 | .cdk.staging
11 | cdk.out
12 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | package-lock.json
3 | __pycache__
4 | .pytest_cache
5 | .env
6 | .venv
7 | *.egg-info
8 |
9 | # CDK asset staging directory
10 | .cdk.staging
11 | cdk.out
12 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | package-lock.json
3 | __pycache__
4 | .pytest_cache
5 | .env
6 | .venv
7 | *.egg-info
8 |
9 | # CDK asset staging directory
10 | .cdk.staging
11 | cdk.out
12 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | package-lock.json
3 | __pycache__
4 | .pytest_cache
5 | .env
6 | .venv
7 | *.egg-info
8 |
9 | # CDK asset staging directory
10 | .cdk.staging
11 | cdk.out
12 |
--------------------------------------------------------------------------------
/604-Deploy-Container-With-Copilot-CLI/README.md:
--------------------------------------------------------------------------------
1 | # Deploying containers using AWS Copilot CLI
2 | ## Preparation
3 | ### Install Copilot cli tool
4 | brew install aws/tap/copilot-cli
5 |
6 |
7 | ## Clean up
8 | ### Delete the App
9 | copilot app delete
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/scaling-policy.json:
--------------------------------------------------------------------------------
1 | {
2 | "TargetValue": 50.0,
3 | "PredefinedMetricSpecification": {
4 | "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
5 | },
6 | "ScaleOutCooldown": 10,
7 | "ScaleInCooldown": 10
8 | }
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "python3 app.py",
3 | "context": {
4 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
5 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
6 | "@aws-cdk/core:stackRelativeExports": false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "python3 app.py",
3 | "context": {
4 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
5 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
6 | "@aws-cdk/core:stackRelativeExports": false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "python3 app.py",
3 | "context": {
4 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
5 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
6 | "@aws-cdk/core:stackRelativeExports": false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/app.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import aws_cdk as cdk
4 |
5 | from cdk_aws_cookbook_607.cdk_aws_cookbook_607_stack import CdkAwsCookbook607Stack
6 |
7 |
8 | app = cdk.App()
9 | CdkAwsCookbook607Stack(app, "cdk-aws-cookbook-607")
10 |
11 | app.synth()
12 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/app.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import aws_cdk as cdk
4 |
5 | from cdk_aws_cookbook_606.cdk_aws_cookbook_606_stack import CdkAwsCookbook606Stack
6 |
7 |
8 | app = cdk.App()
9 | CdkAwsCookbook606Stack(app, "cdk-aws-cookbook-606")
10 |
11 | app.synth()
12 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "python3 app.py",
3 | "context": {
4 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
5 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
6 | "@aws-cdk/core:stackRelativeExports": false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 6
2 | ## Set and export your default region:
3 |
4 | `export AWS_REGION=us-east-1`
5 |
6 | ## Set your AWS ACCOUNT ID::
7 |
8 | `AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)`
9 |
10 | ## Validate AWS Cli Setup and access:
11 |
12 | `aws ec2 describe-instances`
13 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/app.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import aws_cdk as cdk
4 |
5 | from cdk_aws_cookbook_605.cdk_aws_cookbook_605_stack import CdkAwsCookbook605Stack
6 |
7 |
8 | app = cdk.App()
9 | CdkAwsCookbook605Stack(app, "cdk-aws-cookbook-605")
10 |
11 | app.synth()
12 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/Docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM maven:3.6.3-jdk-8 AS build
2 | COPY app/ /opt/app
3 | RUN cd /opt/app && mvn clean install
4 |
5 | FROM tomcat:8.5-jdk8-slim
6 | RUN rm -rf /usr/local/tomcat/webapps/ROOT
7 | COPY --from=build /opt/app/target/loadtest.war /usr/local/tomcat/webapps/ROOT.war
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/task-execution-assume-role.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Sid": "",
6 | "Effect": "Allow",
7 | "Principal": {
8 | "Service": "ecs-tasks.amazonaws.com"
9 | },
10 | "Action": "sts:AssumeRole"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/task-execution-assume-role.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Sid": "",
6 | "Effect": "Allow",
7 | "Principal": {
8 | "Service": "ecs-tasks.amazonaws.com"
9 | },
10 | "Action": "sts:AssumeRole"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/policy1.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Effect": "Allow",
6 | "Principal": {
7 | "Service": "events.amazonaws.com"
8 | },
9 | "Action": "sts:AssumeRole"
10 | }
11 | ]
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/app.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import aws_cdk as cdk
4 |
5 | from cdk_aws_cookbook_608.cdk_aws_cookbook_608_stack import CdkAwsCookbook608Stack
6 |
7 |
8 | app = cdk.App()
9 | CdkAwsCookbook608Stack(app, "cdk-aws-cookbook-608")
10 |
11 | app.synth()
12 |
--------------------------------------------------------------------------------
/603-Deploy-Container-With-Lightsail/README.md:
--------------------------------------------------------------------------------
1 | # Deploying a container using Amazon Lightsail
2 |
3 | ## Clean up
4 | ### Delete the local image from your workstation:
5 |
6 | `docker image rm nginx`
7 |
8 | ### Delete the container service:
9 |
10 | `aws lightsail delete-container-service --service-name awscookbook`
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/task-execution-assume-role.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Sid": "",
6 | "Effect": "Allow",
7 | "Principal": {
8 | "Service": "ecs-tasks.amazonaws.com"
9 | },
10 | "Action": "sts:AssumeRole"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/DockerBlue/index.html:
--------------------------------------------------------------------------------
1 |
AWSCookbook AWS Cookbook BLUE
This HTML is running in an apache container on Fargate!
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/DockerGreen/index.html:
--------------------------------------------------------------------------------
1 | AWSCookbook AWS Cookbook GREEN
This HTML is running in an apache container on Fargate!
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/assume-role-policy.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Effect": "Allow",
6 | "Principal": {
7 | "Service": "codedeploy.amazonaws.com"
8 | },
9 | "Action": "sts:AssumeRole"
10 | }
11 | ]
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/appspec-template.yaml:
--------------------------------------------------------------------------------
1 | version: 0.0
2 | Resources:
3 | - TargetService:
4 | Type: AWS::ECS::Service
5 | Properties:
6 | TaskDefinition: "FargateTaskGreenArn"
7 | LoadBalancerInfo:
8 | ContainerName: "ContainerDefGreen"
9 | ContainerPort: 80
10 | PlatformVersion: "LATEST"
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/deployment-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "applicationName": "awscookbook-605",
3 | "deploymentGroupName": "awscookbook-605-dg",
4 | "revision": {
5 | "revisionType": "S3",
6 | "s3Location": {
7 | "bucket": "S3BucketName",
8 | "key": "appspec.yaml",
9 | "bundleType": "YAML"
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/603-Deploy-Container-With-Lightsail/lightsail.json:
--------------------------------------------------------------------------------
1 | {
2 | "serviceName": "awscookbook",
3 | "containers": {
4 | "awscookbook": {
5 | "image": ":awscookbook.awscookbook.1",
6 | "ports": {
7 | "80": "HTTP"
8 | }
9 | }
10 | },
11 | "publicEndpoint": {
12 | "containerName": "awscookbook",
13 | "containerPort": 80
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/Docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM amazon/aws-cli:latest
2 | #ENV BucketName $S3_BUCKET
3 | #ENV ObjectKey $S3_KEY
4 | RUN yum -y update && yum -y install python3
5 | RUN pip3 install mazesolver --user
6 | WORKDIR /root/
7 | COPY cmd.sh /root/
8 | RUN chmod +x cmd.sh
9 | CMD ["/bin/bash", "-c", "/root/cmd.sh $S3_BUCKET $S3_KEY"]
10 | #CMD ["cmd.sh"]
11 | ENTRYPOINT ["/bin/bash", "-c", "/root/cmd.sh $S3_BUCKET $S3_KEY"]
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/source.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem The sole purpose of this script is to make the command
4 | rem
5 | rem source .venv/bin/activate
6 | rem
7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows.
8 | rem On Windows, this command just runs this batch file (the argument is ignored).
9 | rem
10 | rem Now we don't need to document a Windows command for activating a virtualenv.
11 |
12 | echo Executing .venv\Scripts\activate.bat for you
13 | .venv\Scripts\activate.bat
14 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/source.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem The sole purpose of this script is to make the command
4 | rem
5 | rem source .venv/bin/activate
6 | rem
7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows.
8 | rem On Windows, this command just runs this batch file (the argument is ignored).
9 | rem
10 | rem Now we don't need to document a Windows command for activating a virtualenv.
11 |
12 | echo Executing .venv\Scripts\activate.bat for you
13 | .venv\Scripts\activate.bat
14 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/source.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem The sole purpose of this script is to make the command
4 | rem
5 | rem source .venv/bin/activate
6 | rem
7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows.
8 | rem On Windows, this command just runs this batch file (the argument is ignored).
9 | rem
10 | rem Now we don't need to document a Windows command for activating a virtualenv.
11 |
12 | echo Executing .venv\Scripts\activate.bat for you
13 | .venv\Scripts\activate.bat
14 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/source.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem The sole purpose of this script is to make the command
4 | rem
5 | rem source .venv/bin/activate
6 | rem
7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows.
8 | rem On Windows, this command just runs this batch file (the argument is ignored).
9 | rem
10 | rem Now we don't need to document a Windows command for activating a virtualenv.
11 |
12 | echo Executing .venv\Scripts\activate.bat for you
13 | .venv\Scripts\activate.bat
14 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/Docker/README.md:
--------------------------------------------------------------------------------
1 | # aws loadtest api
2 | java servlet and tomcat 8.5 implementation of a load test API for containers
3 | java sdk8 and maven 3.x for build
4 |
5 | Easily demonstrate ECS AutoScaling and simulate container CPU, Memory and request loads on container infrastructure
6 |
7 | ## Usage
8 | * Run locally using "docker run -rm --it -p 8080:8080 mzazon/loadtest"
9 | * HTTP GET "/loadtest/cpu"
10 | * Initiates an HTTP call which will load CPU to 100%
11 | * Returns JSON
12 | * Healthcheck path for load balancers HTTP GET "/loadtest/healthcheck"
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/recipe-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Recipe request
3 | about: Suggest a recipe for this Chapter
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your recipe request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe what you'd like to learn**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/Docker/cmd.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # script takes parameters
3 | # $1 aws s3 bucket name
4 | # $2 input file path on s3
5 | # TODO: get bucket name from SSM or CloudFormation or DynamoDB or SQS
6 | set -x
7 | #printenv
8 | echo "Downloading input file from S3..."
9 | echo $1
10 | echo $2
11 | aws s3 cp s3://$1/$2 /root/$2
12 | #aws s3 cp s3://cdk-aws-cookbook-407-awscookbokrecipe407f6cd7422-1kmigiv1e331u/input/maze.jpg /root/
13 | #mv /root/maze.jpg /root/input.jpg
14 | echo "Processing Input... This may take a while depending on size."
15 | python3 /root/.local/bin/mazesolver -i /root/$2 -o /root/
16 | ls -al
17 | aws s3 cp /root/maze_out.jpg s3://$1/output/output.jpg
18 | echo "Completed."
19 | exit 0
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/policy2.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Effect": "Allow",
6 | "Action": [
7 | "ecs:RunTask"
8 | ],
9 | "Resource": [
10 | "arn:aws:ecs:*:*:task-definition/*"
11 | ]
12 | },
13 | {
14 | "Effect": "Allow",
15 | "Action": "iam:PassRole",
16 | "Resource": [
17 | "*"
18 | ],
19 | "Condition": {
20 | "StringLike": {
21 | "iam:PassedToService": "ecs-tasks.amazonaws.com"
22 | }
23 | }
24 | }
25 | ]
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/601-Build-An-ECR-Repo/README.md:
--------------------------------------------------------------------------------
1 | # Building and Pushing a Container Image to ECR
2 |
3 |
4 | ## Cleanup
5 | ### Remove the image from ECR:
6 | ```
7 | aws ecr batch-delete-image --repository-name aws-cookbook-repo \
8 | --image-ids imageTag=latest
9 |
10 | aws ecr batch-delete-image --repository-name aws-cookbook-repo \
11 | --image-ids imageTag=1.0
12 | ```
13 |
14 |
15 | ### Delete the image from your local machine:
16 | ```
17 | docker image rm \
18 | $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:1.0
19 | docker image rm \
20 | $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:latest
21 | ```
22 |
23 | ### Delete the repository:
24 |
25 | `aws ecr delete-repository --repository-name aws-cookbook-repo`
26 |
27 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/Docker/app/WebContent/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | loadtest
4 |
5 |
6 | LoadtestServlet
7 | LoadtestServlet
8 | net.zengineering.java.loadtest.LoadtestServlet
9 |
10 |
11 | LoadtestServlet
12 | /*
13 |
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/targets-template.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Id": "AWSCookbookRuleID",
4 | "Arn": "ECSClusterARN",
5 | "RoleArn": "arn:aws:iam::AWS_ACCOUNT_ID:role/AWSCookbook607RuleRole",
6 | "EcsParameters": {
7 | "TaskDefinitionArn": "TaskDefinitionARN",
8 | "TaskCount": 1,
9 | "LaunchType": "FARGATE",
10 | "NetworkConfiguration": {
11 | "awsvpcConfiguration": {
12 | "Subnets": [VPCPrivateSubnets],
13 | "SecurityGroups": ["VPCDefaultSecurityGroup"],
14 | "AssignPublicIp": "ENABLED"
15 | }
16 | }
17 | },
18 | "InputTransformer": {
19 | "InputPathsMap": {"s3_bucket": "$.detail.requestParameters.bucketName","s3_key": "$.detail.requestParameters.key"},
20 | "InputTemplate": "{ \"containerOverrides\": [{\"name\": \"AWS-Cookbook-ContainerDefinition\",\"environment\": [{ \"name\": \"S3_BUCKET\", \"value\": },{ \"name\": \"S3_KEY\", \"value\": }]}]}"
21 | }
22 | }
23 | ]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 AWS Cookbook
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/taskdef.json:
--------------------------------------------------------------------------------
1 | {
2 | "networkMode": "awsvpc",
3 | "containerDefinitions": [
4 | {
5 | "portMappings": [
6 | {
7 | "hostPort": 80,
8 | "containerPort": 80,
9 | "protocol": "tcp"
10 | }
11 | ],
12 | "essential": true,
13 | "entryPoint": [
14 | "sh",
15 | "-c"
16 | ],
17 | "logConfiguration": {
18 | "logDriver": "awslogs",
19 | "options": {
20 | "awslogs-group": "AWSCookbook608ECS",
21 | "awslogs-region": "us-east-1",
22 | "awslogs-stream-prefix": "LogStream"
23 | }
24 | },
25 | "name": "awscookbook608",
26 | "image": "httpd:2.4",
27 | "command": [
28 | "/bin/sh -c \"echo 'Hello AWS Cookbook Reader, this container is running on ECS!' > /usr/local/apache2/htdocs/index.html && httpd-foreground\""
29 | ]
30 | }
31 | ],
32 | "family": "awscookbook608",
33 | "requiresCompatibilities": [
34 | "FARGATE"
35 | ],
36 | "cpu": "256",
37 | "memory": "512"
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 |
4 | with open("README.md") as fp:
5 | long_description = fp.read()
6 |
7 |
8 | setuptools.setup(
9 | name="cdk_aws_cookbook_607",
10 | version="0.0.1",
11 |
12 | description="An empty CDK Python app",
13 | long_description=long_description,
14 | long_description_content_type="text/markdown",
15 |
16 | author="author",
17 |
18 | package_dir={"": "cdk_aws_cookbook_607"},
19 | packages=setuptools.find_packages(where="cdk_aws_cookbook_607"),
20 |
21 | install_requires=[
22 | "aws-cdk-lib>=2.0.0rc1",
23 | "constructs>=10.0.0",
24 | ],
25 |
26 | python_requires=">=3.6",
27 |
28 | classifiers=[
29 | "Development Status :: 4 - Beta",
30 |
31 | "Intended Audience :: Developers",
32 |
33 | "License :: OSI Approved :: Apache Software License",
34 |
35 | "Programming Language :: JavaScript",
36 | "Programming Language :: Python :: 3 :: Only",
37 | "Programming Language :: Python :: 3.6",
38 | "Programming Language :: Python :: 3.7",
39 | "Programming Language :: Python :: 3.8",
40 |
41 | "Topic :: Software Development :: Code Generators",
42 | "Topic :: Utilities",
43 |
44 | "Typing :: Typed",
45 | ],
46 | )
47 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 |
4 | with open("README.md") as fp:
5 | long_description = fp.read()
6 |
7 |
8 | setuptools.setup(
9 | name="cdk_aws_cookbook_605",
10 | version="0.0.1",
11 |
12 | description="An empty CDK Python app",
13 | long_description=long_description,
14 | long_description_content_type="text/markdown",
15 |
16 | author="author",
17 |
18 | package_dir={"": "cdk_aws_cookbook_605"},
19 | packages=setuptools.find_packages(where="cdk_aws_cookbook_605"),
20 |
21 | install_requires=[
22 | "aws-cdk-lib>=2.0.0rc1",
23 | "constructs>=10.0.0",
24 | ],
25 |
26 | python_requires=">=3.6",
27 |
28 | classifiers=[
29 | "Development Status :: 4 - Beta",
30 |
31 | "Intended Audience :: Developers",
32 |
33 | "License :: OSI Approved :: Apache Software License",
34 |
35 | "Programming Language :: JavaScript",
36 | "Programming Language :: Python :: 3 :: Only",
37 | "Programming Language :: Python :: 3.6",
38 | "Programming Language :: Python :: 3.7",
39 | "Programming Language :: Python :: 3.8",
40 |
41 | "Topic :: Software Development :: Code Generators",
42 | "Topic :: Utilities",
43 |
44 | "Typing :: Typed",
45 | ],
46 | )
47 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 |
4 | with open("README.md") as fp:
5 | long_description = fp.read()
6 |
7 |
8 | setuptools.setup(
9 | name="cdk_aws_cookbook_606",
10 | version="0.0.1",
11 |
12 | description="An empty CDK Python app",
13 | long_description=long_description,
14 | long_description_content_type="text/markdown",
15 |
16 | author="author",
17 |
18 | package_dir={"": "cdk_aws_cookbook_606"},
19 | packages=setuptools.find_packages(where="cdk_aws_cookbook_606"),
20 |
21 | install_requires=[
22 | "aws-cdk-lib>=2.0.0rc1",
23 | "constructs>=10.0.0",
24 | ],
25 |
26 | python_requires=">=3.6",
27 |
28 | classifiers=[
29 | "Development Status :: 4 - Beta",
30 |
31 | "Intended Audience :: Developers",
32 |
33 | "License :: OSI Approved :: Apache Software License",
34 |
35 | "Programming Language :: JavaScript",
36 | "Programming Language :: Python :: 3 :: Only",
37 | "Programming Language :: Python :: 3.6",
38 | "Programming Language :: Python :: 3.7",
39 | "Programming Language :: Python :: 3.8",
40 |
41 | "Topic :: Software Development :: Code Generators",
42 | "Topic :: Utilities",
43 |
44 | "Typing :: Typed",
45 | ],
46 | )
47 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 |
4 | with open("README.md") as fp:
5 | long_description = fp.read()
6 |
7 |
8 | setuptools.setup(
9 | name="cdk_aws_cookbook_608",
10 | version="0.0.1",
11 |
12 | description="An empty CDK Python app",
13 | long_description=long_description,
14 | long_description_content_type="text/markdown",
15 |
16 | author="author",
17 |
18 | package_dir={"": "cdk_aws_cookbook_608"},
19 | packages=setuptools.find_packages(where="cdk_aws_cookbook_608"),
20 |
21 | install_requires=[
22 | "aws-cdk-lib>=2.0.0rc1",
23 | "constructs>=10.0.0",
24 | ],
25 |
26 | python_requires=">=3.6",
27 |
28 | classifiers=[
29 | "Development Status :: 4 - Beta",
30 |
31 | "Intended Audience :: Developers",
32 |
33 | "License :: OSI Approved :: Apache Software License",
34 |
35 | "Programming Language :: JavaScript",
36 | "Programming Language :: Python :: 3 :: Only",
37 | "Programming Language :: Python :: 3.6",
38 | "Programming Language :: Python :: 3.7",
39 | "Programming Language :: Python :: 3.8",
40 |
41 | "Topic :: Software Development :: Code Generators",
42 | "Topic :: Utilities",
43 |
44 | "Typing :: Typed",
45 | ],
46 | )
47 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/codedeploy-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "applicationName": "awscookbook-605",
3 | "autoRollbackConfiguration": {
4 | "enabled": true,
5 | "events": [ "DEPLOYMENT_FAILURE" ]
6 | },
7 | "blueGreenDeploymentConfiguration": {
8 | "deploymentReadyOption": {
9 | "actionOnTimeout": "CONTINUE_DEPLOYMENT",
10 | "waitTimeInMinutes": 0
11 | },
12 | "terminateBlueInstancesOnDeploymentSuccess": {
13 | "action": "TERMINATE",
14 | "terminationWaitTimeInMinutes": 5
15 | }
16 | },
17 | "deploymentGroupName": "awscookbook-605-dg",
18 | "deploymentStyle": {
19 | "deploymentOption": "WITH_TRAFFIC_CONTROL",
20 | "deploymentType": "BLUE_GREEN"
21 | },
22 | "loadBalancerInfo": {
23 | "targetGroupPairInfoList": [
24 | {
25 | "targetGroups": [
26 | {
27 | "name": "BlueTG"
28 | },
29 | {
30 | "name": "GreenTG"
31 | }
32 | ],
33 | "prodTrafficRoute": {
34 | "listenerArns": [
35 | "PROD_LISTENER_ARN"
36 | ]
37 | },
38 | "testTrafficRoute": {
39 | "listenerArns": [
40 | "TEST_LISTENER_ARN"
41 | ]
42 | }
43 | }
44 | ]
45 | },
46 | "serviceRoleArn": "arn:aws:iam::AWS_ACCOUNT_ID:role/ecsCodeDeployRole",
47 | "ecsServices": [
48 | {
49 | "serviceName": "AWSCookbook605",
50 | "clusterName": "awscookbook605"
51 | }
52 | ]
53 | }
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/helper.py:
--------------------------------------------------------------------------------
1 | import os
2 | import boto3
3 | import argparse
4 |
5 |
6 | def change_case(str):
7 | res = [str[0]]
8 | for c in str[1:]:
9 | if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
10 | res.append('_')
11 | res.append(c)
12 | elif c in ('123456789'):
13 | res.append('_')
14 | res.append(c)
15 | else:
16 | res.append(c.upper())
17 |
18 | return ''.join(res)
19 |
20 |
21 | parser = argparse.ArgumentParser(description="Generate commands to set and unset environment variables")
22 | parser.add_argument('--unset', action='store_true', help="Generate commands to unset environment variables by setting this flag")
23 |
24 | args = parser.parse_args()
25 |
26 | os.environ['AWS_DEFAULT_REGION'] = os.environ.get('AWS_REGION')
27 |
28 | cfn = boto3.client('cloudformation')
29 | stackname = os.path.basename(os.getcwd()).lower()
30 | response = cfn.describe_stacks(StackName=stackname)
31 | unsets = []
32 | sets = []
33 |
34 | outputs = response["Stacks"][0]["Outputs"]
35 | print("Copy and paste the commands below into your terminal")
36 | print("")
37 | for output in outputs:
38 | if ', ' in output["OutputValue"]:
39 | sets.append(change_case(output["OutputKey"]) + "='" + ', '.join('"{}"'.format(word) for word in output["OutputValue"].split(", ")) + "'")
40 | else:
41 | sets.append(change_case(output["OutputKey"]) + "='" + output["OutputValue"] + "'")
42 | unsets.append("unset " + change_case(output["OutputKey"]))
43 |
44 | if (args.unset):
45 | print('\n'.join(map(str, unsets)))
46 | else:
47 | print('\n'.join(map(str, sets)))
48 |
49 | print("")
50 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/helper.py:
--------------------------------------------------------------------------------
1 | import os
2 | import boto3
3 | import argparse
4 |
5 |
6 | def change_case(str):
7 | res = [str[0]]
8 | for c in str[1:]:
9 | if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
10 | res.append('_')
11 | res.append(c)
12 | elif c in ('123456789'):
13 | res.append('_')
14 | res.append(c)
15 | else:
16 | res.append(c.upper())
17 |
18 | return ''.join(res)
19 |
20 |
21 | parser = argparse.ArgumentParser(description="Generate commands to set and unset environment variables")
22 | parser.add_argument('--unset', action='store_true', help="Generate commands to unset environment variables by setting this flag")
23 |
24 | args = parser.parse_args()
25 |
26 | os.environ['AWS_DEFAULT_REGION'] = os.environ.get('AWS_REGION')
27 |
28 | cfn = boto3.client('cloudformation')
29 | stackname = os.path.basename(os.getcwd()).lower()
30 | response = cfn.describe_stacks(StackName=stackname)
31 | unsets = []
32 | sets = []
33 |
34 | outputs = response["Stacks"][0]["Outputs"]
35 | print("Copy and paste the commands below into your terminal")
36 | print("")
37 | for output in outputs:
38 | if ', ' in output["OutputValue"]:
39 | sets.append(change_case(output["OutputKey"]) + "='" + ', '.join('"{}"'.format(word) for word in output["OutputValue"].split(", ")) + "'")
40 | else:
41 | sets.append(change_case(output["OutputKey"]) + "='" + output["OutputValue"] + "'")
42 | unsets.append("unset " + change_case(output["OutputKey"]))
43 |
44 | if (args.unset):
45 | print('\n'.join(map(str, unsets)))
46 | else:
47 | print('\n'.join(map(str, sets)))
48 |
49 | print("")
50 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/helper.py:
--------------------------------------------------------------------------------
1 | import os
2 | import boto3
3 | import argparse
4 |
5 |
6 | def change_case(str):
7 | res = [str[0]]
8 | for c in str[1:]:
9 | if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
10 | res.append('_')
11 | res.append(c)
12 | elif c in ('123456789'):
13 | res.append('_')
14 | res.append(c)
15 | else:
16 | res.append(c.upper())
17 |
18 | return ''.join(res)
19 |
20 |
21 | parser = argparse.ArgumentParser(description="Generate commands to set and unset environment variables")
22 | parser.add_argument('--unset', action='store_true', help="Generate commands to unset environment variables by setting this flag")
23 |
24 | args = parser.parse_args()
25 |
26 | os.environ['AWS_DEFAULT_REGION'] = os.environ.get('AWS_REGION')
27 |
28 | cfn = boto3.client('cloudformation')
29 | stackname = os.path.basename(os.getcwd()).lower()
30 | response = cfn.describe_stacks(StackName=stackname)
31 | unsets = []
32 | sets = []
33 |
34 | outputs = response["Stacks"][0]["Outputs"]
35 | print("Copy and paste the commands below into your terminal")
36 | print("")
37 | for output in outputs:
38 | if ', ' in output["OutputValue"]:
39 | sets.append(change_case(output["OutputKey"]) + "='" + ', '.join('"{}"'.format(word) for word in output["OutputValue"].split(", ")) + "'")
40 | else:
41 | sets.append(change_case(output["OutputKey"]) + "='" + output["OutputValue"] + "'")
42 | unsets.append("unset " + change_case(output["OutputKey"]))
43 |
44 | if (args.unset):
45 | print('\n'.join(map(str, unsets)))
46 | else:
47 | print('\n'.join(map(str, sets)))
48 |
49 | print("")
50 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/helper.py:
--------------------------------------------------------------------------------
1 | import os
2 | import boto3
3 | import argparse
4 |
5 |
6 | def change_case(str):
7 | res = [str[0]]
8 | for c in str[1:]:
9 | if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
10 | res.append('_')
11 | res.append(c)
12 | elif c in ('123456789'):
13 | res.append('_')
14 | res.append(c)
15 | else:
16 | res.append(c.upper())
17 |
18 | return ''.join(res)
19 |
20 |
21 | parser = argparse.ArgumentParser(description="Generate commands to set and unset environment variables")
22 | parser.add_argument('--unset', action='store_true', help="Generate commands to unset environment variables by setting this flag")
23 |
24 | args = parser.parse_args()
25 |
26 | os.environ['AWS_DEFAULT_REGION'] = os.environ.get('AWS_REGION')
27 |
28 | cfn = boto3.client('cloudformation')
29 | stackname = os.path.basename(os.getcwd()).lower()
30 | response = cfn.describe_stacks(StackName=stackname)
31 | unsets = []
32 | sets = []
33 |
34 | outputs = response["Stacks"][0]["Outputs"]
35 | print("Copy and paste the commands below into your terminal")
36 | print("")
37 | for output in outputs:
38 | if ', ' in output["OutputValue"]:
39 | sets.append(change_case(output["OutputKey"]) + "='" + ', '.join('"{}"'.format(word) for word in output["OutputValue"].split(", ")) + "'")
40 | else:
41 | sets.append(change_case(output["OutputKey"]) + "='" + output["OutputValue"] + "'")
42 | unsets.append("unset " + change_case(output["OutputKey"]))
43 |
44 | if (args.unset):
45 | print('\n'.join(map(str, unsets)))
46 | else:
47 | print('\n'.join(map(str, sets)))
48 |
49 | print("")
50 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/Docker/app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | net.zengineering.java.loadtest
4 | loadtest
5 | 2.1
6 | war
7 |
8 | loadtest
9 |
10 |
11 | maven-war-plugin
12 | 2.3
13 |
14 | WebContent
15 | false
16 |
17 |
18 |
19 |
20 |
21 |
22 | javax.servlet
23 | servlet-api
24 | 2.5
25 | provided
26 |
27 |
37 |
38 |
51 |
52 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Welcome to your CDK Python project!
3 |
4 | This is a blank project for Python development with CDK.
5 |
6 | The `cdk.json` file tells the CDK Toolkit how to execute your app.
7 |
8 | This project is set up like a standard Python project. The initialization
9 | process also creates a virtualenv within this project, stored under the `.venv`
10 | directory. To create the virtualenv it assumes that there is a `python3`
11 | (or `python` for Windows) executable in your path with access to the `venv`
12 | package. If for any reason the automatic creation of the virtualenv fails,
13 | you can create the virtualenv manually.
14 |
15 | To manually create a virtualenv on MacOS and Linux:
16 |
17 | ```
18 | $ python3 -m venv .venv
19 | ```
20 |
21 | After the init process completes and the virtualenv is created, you can use the following
22 | step to activate your virtualenv.
23 |
24 | ```
25 | $ source .venv/bin/activate
26 | ```
27 |
28 | If you are a Windows platform, you would activate the virtualenv like this:
29 |
30 | ```
31 | % .venv\Scripts\activate.bat
32 | ```
33 |
34 | Once the virtualenv is activated, you can install the required dependencies.
35 |
36 | ```
37 | $ pip install -r requirements.txt
38 | ```
39 |
40 | At this point you can now synthesize the CloudFormation template for this code.
41 |
42 | ```
43 | $ cdk synth
44 | ```
45 |
46 | To add additional dependencies, for example other CDK libraries, just add
47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt`
48 | command.
49 |
50 | ## Useful commands
51 |
52 | * `cdk ls` list all stacks in the app
53 | * `cdk synth` emits the synthesized CloudFormation template
54 | * `cdk deploy` deploy this stack to your default AWS account/region
55 | * `cdk diff` compare deployed stack with current state
56 | * `cdk docs` open CDK documentation
57 |
58 | Enjoy!
59 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Welcome to your CDK Python project!
3 |
4 | This is a blank project for Python development with CDK.
5 |
6 | The `cdk.json` file tells the CDK Toolkit how to execute your app.
7 |
8 | This project is set up like a standard Python project. The initialization
9 | process also creates a virtualenv within this project, stored under the `.venv`
10 | directory. To create the virtualenv it assumes that there is a `python3`
11 | (or `python` for Windows) executable in your path with access to the `venv`
12 | package. If for any reason the automatic creation of the virtualenv fails,
13 | you can create the virtualenv manually.
14 |
15 | To manually create a virtualenv on MacOS and Linux:
16 |
17 | ```
18 | $ python3 -m venv .venv
19 | ```
20 |
21 | After the init process completes and the virtualenv is created, you can use the following
22 | step to activate your virtualenv.
23 |
24 | ```
25 | $ source .venv/bin/activate
26 | ```
27 |
28 | If you are a Windows platform, you would activate the virtualenv like this:
29 |
30 | ```
31 | % .venv\Scripts\activate.bat
32 | ```
33 |
34 | Once the virtualenv is activated, you can install the required dependencies.
35 |
36 | ```
37 | $ pip install -r requirements.txt
38 | ```
39 |
40 | At this point you can now synthesize the CloudFormation template for this code.
41 |
42 | ```
43 | $ cdk synth
44 | ```
45 |
46 | To add additional dependencies, for example other CDK libraries, just add
47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt`
48 | command.
49 |
50 | ## Useful commands
51 |
52 | * `cdk ls` list all stacks in the app
53 | * `cdk synth` emits the synthesized CloudFormation template
54 | * `cdk deploy` deploy this stack to your default AWS account/region
55 | * `cdk diff` compare deployed stack with current state
56 | * `cdk docs` open CDK documentation
57 |
58 | Enjoy!
59 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Welcome to your CDK Python project!
3 |
4 | This is a blank project for Python development with CDK.
5 |
6 | The `cdk.json` file tells the CDK Toolkit how to execute your app.
7 |
8 | This project is set up like a standard Python project. The initialization
9 | process also creates a virtualenv within this project, stored under the `.venv`
10 | directory. To create the virtualenv it assumes that there is a `python3`
11 | (or `python` for Windows) executable in your path with access to the `venv`
12 | package. If for any reason the automatic creation of the virtualenv fails,
13 | you can create the virtualenv manually.
14 |
15 | To manually create a virtualenv on MacOS and Linux:
16 |
17 | ```
18 | $ python3 -m venv .venv
19 | ```
20 |
21 | After the init process completes and the virtualenv is created, you can use the following
22 | step to activate your virtualenv.
23 |
24 | ```
25 | $ source .venv/bin/activate
26 | ```
27 |
28 | If you are a Windows platform, you would activate the virtualenv like this:
29 |
30 | ```
31 | % .venv\Scripts\activate.bat
32 | ```
33 |
34 | Once the virtualenv is activated, you can install the required dependencies.
35 |
36 | ```
37 | $ pip install -r requirements.txt
38 | ```
39 |
40 | At this point you can now synthesize the CloudFormation template for this code.
41 |
42 | ```
43 | $ cdk synth
44 | ```
45 |
46 | To add additional dependencies, for example other CDK libraries, just add
47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt`
48 | command.
49 |
50 | ## Useful commands
51 |
52 | * `cdk ls` list all stacks in the app
53 | * `cdk synth` emits the synthesized CloudFormation template
54 | * `cdk deploy` deploy this stack to your default AWS account/region
55 | * `cdk diff` compare deployed stack with current state
56 | * `cdk docs` open CDK documentation
57 |
58 | Enjoy!
59 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Welcome to your CDK Python project!
3 |
4 | This is a blank project for Python development with CDK.
5 |
6 | The `cdk.json` file tells the CDK Toolkit how to execute your app.
7 |
8 | This project is set up like a standard Python project. The initialization
9 | process also creates a virtualenv within this project, stored under the `.venv`
10 | directory. To create the virtualenv it assumes that there is a `python3`
11 | (or `python` for Windows) executable in your path with access to the `venv`
12 | package. If for any reason the automatic creation of the virtualenv fails,
13 | you can create the virtualenv manually.
14 |
15 | To manually create a virtualenv on MacOS and Linux:
16 |
17 | ```
18 | $ python3 -m venv .venv
19 | ```
20 |
21 | After the init process completes and the virtualenv is created, you can use the following
22 | step to activate your virtualenv.
23 |
24 | ```
25 | $ source .venv/bin/activate
26 | ```
27 |
28 | If you are a Windows platform, you would activate the virtualenv like this:
29 |
30 | ```
31 | % .venv\Scripts\activate.bat
32 | ```
33 |
34 | Once the virtualenv is activated, you can install the required dependencies.
35 |
36 | ```
37 | $ pip install -r requirements.txt
38 | ```
39 |
40 | At this point you can now synthesize the CloudFormation template for this code.
41 |
42 | ```
43 | $ cdk synth
44 | ```
45 |
46 | To add additional dependencies, for example other CDK libraries, just add
47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt`
48 | command.
49 |
50 | ## Useful commands
51 |
52 | * `cdk ls` list all stacks in the app
53 | * `cdk synth` emits the synthesized CloudFormation template
54 | * `cdk deploy` deploy this stack to your default AWS account/region
55 | * `cdk diff` compare deployed stack with current state
56 | * `cdk docs` open CDK documentation
57 |
58 | Enjoy!
59 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/README.md:
--------------------------------------------------------------------------------
1 | # Auto Scaling container workloads on Amazon ECS
2 | ## Preparation
3 |
4 | This recipe requires some “prep work” which deploys resources that you’ll build the solution on. You will use the AWS CDK to deploy these resources
5 |
6 | ### In the root of this Chapter’s repo cd to the “606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606” directory and follow the subsequent steps:
7 | ```
8 | cd 606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/
9 | test -d .venv || python3 -m venv .venv
10 | source .venv/bin/activate
11 | pip install --upgrade pip
12 | pip install -r requirements.txt
13 | cdk deploy
14 | ```
15 |
16 | ### Wait for the cdk deploy command to complete.
17 |
18 | ### We created a helper.py script to let you easily create and export environment variables to make subsequent commands easier. Run the script, and copy the output to your terminal to export variables:
19 |
20 | `python helper.py`
21 |
22 | ### Navigate up to the main directory for this recipe (out of the “cdk-AWS-Cookbook-606” directory)
23 |
24 | `cd ..`
25 |
26 |
27 | ## Clean up
28 | ### Delete the container images:
29 | ```
30 | aws ecr batch-delete-image --repository-name aws-cdk/assets \
31 | --image-ids imageTag=$(echo $ECR_IMAGE | cut -d : -f 2)
32 | ```
33 |
34 | ### Go to the cdk-AWS-Cookbook-606 directory:
35 |
36 | `cd cdk-AWS-Cookbook-606/`
37 |
38 | ### To clean up the environment variables, run the helper.py script in this recipe’s cdk- directory with the --unset flag, and copy the output to your terminal to export variables:
39 |
40 | `python helper.py --unset`
41 |
42 | ### Use the AWS CDK to destroy the resources, deactivate your Python virtual environment, and go to the root of the chapter:
43 |
44 | `cdk destroy && deactivate && rm -r .venv/ && cd ../..`
45 |
46 | ### Detach the managed Auto Scaling policy from the IAM role:
47 | ```
48 | aws iam detach-role-policy --role-name AWSCookbook606ECS --policy-arn \
49 | arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole
50 | ```
51 |
52 | ### Delete the Auto Scaling IAM role:
53 |
54 | `aws iam delete-role --role-name AWSCookbook606ECS`
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608/cdk_aws_cookbook_608/cdk_aws_cookbook_608_stack.py:
--------------------------------------------------------------------------------
1 | from constructs import Construct
2 | from aws_cdk import (
3 | aws_ec2 as ec2,
4 | aws_ecs as ecs,
5 | Stack,
6 | CfnOutput,
7 | )
8 |
9 |
10 | class CdkAwsCookbook608Stack(Stack):
11 |
12 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
13 | super().__init__(scope, construct_id, **kwargs)
14 |
15 | # create VPC
16 | vpc = ec2.Vpc(
17 | self,
18 | 'AWS-Cookbook-VPC'
19 | )
20 |
21 | InterfaceEndpointSecurityGroup = ec2.SecurityGroup(
22 | self,
23 | 'InterfaceEndpointSecurityGroup',
24 | description='Security Group for the VPC Endpoints',
25 | allow_all_outbound=True,
26 | vpc=vpc
27 | )
28 |
29 | InterfaceEndpointSecurityGroup.connections.allow_from(
30 | ec2.Peer.ipv4(vpc.vpc_cidr_block), ec2.Port.tcp(443), "Ingress")
31 |
32 | vpc.add_interface_endpoint(
33 | 'CloudWatchLogsEndpoint',
34 | service=ec2.InterfaceVpcEndpointAwsService('logs'),
35 | private_dns_enabled=True,
36 | security_groups=[InterfaceEndpointSecurityGroup],
37 | subnets=ec2.SubnetSelection(
38 | one_per_az=True,
39 | subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT
40 | ),
41 | )
42 |
43 | # create ECS Cluster
44 | ecs_cluster = ecs.Cluster(
45 | self,
46 | 'AWS-Cookbook-EcsCluster',
47 | vpc=vpc
48 | )
49 |
50 | CfnOutput(
51 | self,
52 | 'EcsClusterName',
53 | value=ecs_cluster.cluster_name
54 | )
55 |
56 | public_subnets = vpc.select_subnets(subnet_type=ec2.SubnetType.PUBLIC)
57 |
58 | CfnOutput(
59 | self,
60 | 'VpcPublicSubnets',
61 | value=', '.join(map(str, public_subnets.subnet_ids))
62 | )
63 |
64 | CfnOutput(
65 | self,
66 | 'VpcDefaultSecurityGroup',
67 | value=vpc.vpc_default_security_group
68 | )
69 |
--------------------------------------------------------------------------------
/608-Capturing-Logs-From-Containers-Running-On-ECS/README.md:
--------------------------------------------------------------------------------
1 | # Capturing logs from containers running on Amazon ECS
2 | ## Preparation
3 |
4 | This recipe requires some “prep work” which deploys resources that you’ll build the solution on. You will use the AWS CDK to deploy these resources.
5 |
6 | ### In the root of this Chapter’s repo cd to the “608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608” directory and follow the subsequent steps:
7 | ```
8 | cd 608-Capturing-Logs-From-Containers-Running-On-ECS/cdk-AWS-Cookbook-608
9 | test -d .venv || python3 -m venv .venv
10 | source .venv/bin/activate
11 | pip install --upgrade pip
12 | pip install -r requirements.txt
13 | cdk deploy
14 | ```
15 |
16 | ### Wait for the cdk deploy command to complete.
17 |
18 | ### We created a helper.py script to let you easily create and export environment variables to make subsequent commands easier. Run the script, and copy the output to your terminal to export variables:
19 |
20 | `python helper.py`
21 |
22 | ### Navigate up to the main directory for this recipe (out of the “cdk-AWS-Cookbook-608” directory):
23 |
24 | `cd ..`
25 |
26 | ### This solution, like the others using Amazon ECS, requires an ECS service-linked role to allow ECS to perform actions on your behalf. This may already exist in your AWS account. To see if you have this role already, issue the following command:
27 |
28 | `aws iam list-roles --path-prefix /aws-service-role/ecs.amazonaws.com/`
29 |
30 | ### If the role is displayed, you can skip the creation step.
31 |
32 | ### Create the ECS service-linked role if it does not exist (it is OK if the command fails indicating that the role already exists in your account):
33 |
34 | `aws iam create-service-linked-role --aws-service-name ecs.amazonaws.com`
35 |
36 |
37 | ## Clean up
38 |
39 | ### Stop the ECS task:
40 |
41 | `aws ecs stop-task --cluster $ECS_CLUSTER_NAME --task <>`
42 |
43 | ### Delete the IAM Policy Attachment and Role:
44 | ```
45 | aws iam detach-role-policy --role-name AWSCookbook608ECS --policy-arn \
46 | arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
47 | aws iam delete-role --role-name AWSCookbook608ECS
48 | ```
49 |
50 | ### Delete Log Group:
51 | `aws logs delete-log-group --log-group-name AWSCookbook608ECS`
52 |
53 | ### Deregister the Task Definition
54 |
55 | `aws ecs deregister-task-definition --task-definition awscookbook608:1`
56 |
57 | ### Go to the cdk-AWS-Cookbook-608 directory
58 |
59 | `cd cdk-AWS-Cookbook-608/`
60 |
61 | ### To clean up the environment variables, run the helper.py script in this recipe’s cdk- directory with the --unset flag, and copy the output to your terminal to export variables:
62 |
63 | `python helper.py --unset`
64 |
65 | ### Use the AWS CDK to destroy the resources, deactivate your Python virtual environment, and go to the root of the chapter:
66 |
67 | `cdk destroy && deactivate && rm -r .venv/ && cd ../..`
68 |
69 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/README.md:
--------------------------------------------------------------------------------
1 | # Updating containers with blue/green deployments
2 | ## Preparation
3 |
4 | This recipe requires some “prep work” which deploys resources that you’ll build the solution on. You will use the AWS CDK to deploy these resources
5 |
6 | ### In the root of this Chapter’s repo cd to the “605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605” directory:
7 | ```
8 | cd 605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/
9 | test -d .venv || python3 -m venv .venv
10 | source .venv/bin/activate
11 | pip install --upgrade pip
12 | pip install -r requirements.txt
13 | cdk deploy
14 | ```
15 |
16 | ### Wait for the cdk deploy command to complete.
17 |
18 | ### We created a helper.py script to let you easily create and export environment variables to make subsequent commands easier. Run the script, and copy the output to your terminal to export variables:
19 |
20 | `python helper.py`
21 |
22 | ### Navigate up to the main directory for this recipe (out of the “cdk-AWS-Cookbook-605” directory)
23 |
24 | `cd ..`
25 |
26 |
27 | ## Clean up
28 |
29 | ### Delete the CodeDeploy deployment group and application:
30 | ```
31 | aws deploy delete-deployment-group \
32 | --deployment-group-name awscookbook-605-dg \
33 | --application-name awscookbook-605
34 |
35 | aws deploy delete-application --application-name awscookbook-605
36 | ```
37 |
38 | ### Detach the IAM policy from and delete the role used by CodeDeploy to update your application on Amazon ECS:
39 | ```
40 | aws iam detach-role-policy --role-name ecsCodeDeployRole \
41 | --policy-arn arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS
42 |
43 | aws iam delete-role --role-name ecsCodeDeployRole
44 | ```
45 |
46 | ### Now remove the load balancer rules created by CodeDeploy during the deployment and the target group you created previously:
47 | ```
48 | aws elbv2 delete-rule --rule-arn \
49 | $(aws elbv2 describe-rules \
50 | --listener-arn $PROD_LISTENER_ARN \
51 | --query 'Rules[?Priority==`"1"`].RuleArn' \
52 | --output text)
53 |
54 | aws elbv2 modify-listener --listener-arn $TEST_LISTENER_ARN \
55 | --default-actions Type=forward,TargetGroupArn=$DEFAULT_TARGET_GROUP_ARN
56 |
57 | aws elbv2 delete-target-group --target-group-arn \
58 | $(aws elbv2 describe-target-groups \
59 | --names "GreenTG" \
60 | --query 'TargetGroups[0].TargetGroupArn' \
61 | --output text)
62 | ```
63 |
64 | ### Delete the Blue and Green images:
65 | ```
66 | aws ecr batch-delete-image --repository-name aws-cdk/assets \
67 | --image-ids imageTag=$(echo $BLUE_IMAGE | cut -d : -f 2) \
68 | imageTag=$(echo $GREEN_IMAGE | cut -d : -f 2)
69 | `
70 |
71 | ### Go to the cdk-AWS-Cookbook-605 directory
72 | `cd cdk-AWS-Cookbook-605/`
73 |
74 | ### To clean up the environment variables, run the helper.py script in this recipe’s cdk- directory with the --unset flag, and copy the output to your terminal to export variables:
75 |
76 | `python helper.py --unset`
77 |
78 | ### Use the AWS CDK to destroy the resources, deactivate your Python virtual environment, and go to the root of the chapter:
79 |
80 | `cdk destroy && deactivate && rm -r .venv/ && cd ../..`
81 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/Docker/app/src/main/java/net/zengineering/LoadtestServlet.java:
--------------------------------------------------------------------------------
1 | package net.zengineering.java.loadtest;
2 |
3 | import java.io.IOException;
4 | import java.text.DateFormat;
5 | import java.text.SimpleDateFormat;
6 | import java.util.Calendar;
7 | import java.util.GregorianCalendar;
8 | import java.util.Locale;
9 | import java.util.TimeZone;
10 |
11 | import javax.servlet.ServletException;
12 | import javax.servlet.ServletInputStream;
13 | import javax.servlet.ServletOutputStream;
14 | import javax.servlet.http.HttpServlet;
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 |
18 | import java.net.InetAddress;
19 | import java.net.UnknownHostException;
20 |
21 | public class LoadtestServlet extends HttpServlet {
22 | private static final long serialVersionUID = 1L;
23 | private DateFormat httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
24 |
25 | public LoadtestServlet() {
26 | httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
27 | }
28 |
29 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
30 | long now = System.currentTimeMillis();
31 | String timeStr = request.getParameter("time");
32 | String httpStatusStr = request.getParameter("http-status");
33 | int httpStatus = (httpStatusStr!=null?Integer.parseInt(httpStatusStr):200);
34 | long maxTime = (timeStr != null ? Long.parseLong(timeStr) : 0L);
35 |
36 | long time = maxTime;
37 |
38 | if (request.getRequestURI().endsWith("/cpu")) {
39 |
40 | double value = 9.9;
41 | while (System.currentTimeMillis() <= (now + 99999999)) {
42 | value = value / 1.0000001;
43 | value = value * 1.00000015;
44 | if (value > Double.MAX_VALUE / 2) {
45 | value = 1.0;
46 | }
47 | }
48 | finishTest(request, response, (System.currentTimeMillis() - now), httpStatus, "success", "value=" + value);
49 |
50 | } else if (request.getRequestURI().endsWith("/healthcheck")) {
51 | // aws load balancer health check
52 |
53 | double value = 9.9;
54 | while (System.currentTimeMillis() <= (now + 3000)) {
55 | value = value / 1.0000001;
56 | value = value * 1.00000015;
57 | if (value > Double.MAX_VALUE / 2) {
58 | value = 1.0;
59 | }
60 | }
61 | finishTest(request, response, (System.currentTimeMillis() - now), httpStatus, "success", "value=" + value);
62 |
63 | } else {
64 | finishTest(request, response, (System.currentTimeMillis() - now), 400, "error",
65 | "");
66 | }
67 |
68 | }
69 |
70 | private void finishTest(HttpServletRequest request, HttpServletResponse response, long timeElapsed, int statusCode, String result, String info) {
71 | try {
72 | response.setContentType("application/json");
73 | response.setStatus(statusCode);
74 | ServletOutputStream responseOS = response.getOutputStream();
75 | InetAddress ip;
76 | ip = InetAddress.getLocalHost();
77 | String hostname = ip.getHostName();
78 | String body = "{\n \"URL\":\"" + request.getRequestURL() + "\",\n \"ContainerLocalAddress\":\"" + request.getLocalAddr() + ":" + request.getLocalPort() + "\",\n \"ProcessingTimeTotalMilliseconds\":\"" + timeElapsed + "\",\n \"LoadBalancerPrivateIP\":\"" + request.getRemoteHost() + "\",\n \"ContainerHostname\":\"" + hostname + "\",\n \"CurrentTime\":\"" + System.currentTimeMillis() + "\"\n}";
79 | responseOS.print(body);
80 | } catch (IOException e) {
81 | throw new RuntimeException(e);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/cdk_aws_cookbook_607/cdk_aws_cookbook_607_stack.py:
--------------------------------------------------------------------------------
1 | from constructs import Construct
2 | from aws_cdk import (
3 | aws_ec2 as ec2,
4 | aws_ecs as ecs,
5 | aws_s3 as s3,
6 | aws_iam as iam,
7 | aws_cloudtrail as cloudtrail,
8 | Stack,
9 | CfnOutput,
10 | RemovalPolicy
11 | )
12 |
13 |
14 | class CdkAwsCookbook607Stack(Stack):
15 |
16 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
17 | super().__init__(scope, construct_id, **kwargs)
18 |
19 | cloud_trail_bucket = s3.Bucket(
20 | self,
21 | "AWS-Cookbok-Recipe607-Cloud-trail",
22 | removal_policy=RemovalPolicy.DESTROY,
23 | auto_delete_objects=True
24 | )
25 |
26 | trail = cloudtrail.Trail(
27 | self,
28 | 'Cloudtrail',
29 | bucket=cloud_trail_bucket
30 | )
31 |
32 | s3_Bucket = s3.Bucket(
33 | self,
34 | "AWS-Cookbok-Recipe607",
35 | removal_policy=RemovalPolicy.DESTROY,
36 | auto_delete_objects=True
37 | )
38 |
39 | # create VPC
40 | vpc = ec2.Vpc(
41 | self,
42 | 'AWS-Cookbook-VPC'
43 | )
44 |
45 | # create ECS Cluster
46 | ecs_cluster = ecs.Cluster(
47 | self,
48 | 'AWS-Cookbook-EcsCluster',
49 | vpc=vpc
50 | )
51 |
52 | # create Fargate Task Definition
53 | FargateTask = ecs.FargateTaskDefinition(
54 | self,
55 | 'AWS-Cookbook-FargateTask',
56 | cpu=1024,
57 | memory_limit_mib=2048,
58 | )
59 |
60 | # create Container Definition
61 | ContainerDefinition = ecs.ContainerDefinition(
62 | self,
63 | 'AWS-Cookbook-ContainerDefinition',
64 | image=ecs.ContainerImage.from_registry("public.ecr.aws/x4e8a6b6/mazesolver:1.0.7"),
65 | task_definition=FargateTask,
66 | )
67 |
68 | ContainerDefinition.add_port_mappings(
69 | ecs.PortMapping(
70 | container_port=80
71 | )
72 | )
73 |
74 | # Grant the container access to the s3 bucket by adding an IAM policy to the execution role
75 | FargateTask.add_to_task_role_policy(iam.PolicyStatement(
76 | effect=iam.Effect.ALLOW,
77 | resources=[s3_Bucket.bucket_arn + '/*'],
78 | actions=["s3:*"])
79 | )
80 |
81 | CfnOutput(
82 | self,
83 | 'CloudTrailArn',
84 | value=trail.trail_arn
85 | )
86 |
87 | CfnOutput(
88 | self,
89 | 'BucketArn',
90 | value=s3_Bucket.bucket_arn
91 | )
92 |
93 | CfnOutput(
94 | self,
95 | 'CloudTrailBucketName',
96 | value=cloud_trail_bucket.bucket_name
97 | )
98 |
99 | CfnOutput(
100 | self,
101 | 'BucketName',
102 | value=s3_Bucket.bucket_name
103 | )
104 |
105 | CfnOutput(
106 | self,
107 | 'EcsClusterArn',
108 | value=ecs_cluster.cluster_arn
109 | )
110 |
111 | CfnOutput(
112 | self,
113 | 'TaskDefinitionArn',
114 | value=FargateTask.task_definition_arn
115 | )
116 |
117 | private_subnets = vpc.select_subnets(subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT)
118 |
119 | CfnOutput(
120 | self,
121 | 'VpcPrivateSubnets',
122 | value=', '.join(map(str, private_subnets.subnet_ids))
123 | )
124 |
125 | CfnOutput(
126 | self,
127 | 'VpcDefaultSecurityGroup',
128 | value=vpc.vpc_default_security_group
129 | )
130 |
--------------------------------------------------------------------------------
/602-Image-Scanning-In-ECR/README.md:
--------------------------------------------------------------------------------
1 | # Automatically Scanning Images in ECR for Security
2 |
3 | ## Problem
4 | You want to automatically scan your container images for security vulnerabilities each time you push to a repository.
5 |
6 | ## Solution
7 | Enable automatic image scanning on a repository in Amazon ECR, push an image, and observe the scan results, as shown in Figure 6-5.
8 |
9 | 
10 |
11 | ## Prerequisite
12 | * ECR repository
13 |
14 | ## Preparation
15 | ### Create an ECR repository:
16 | ```
17 | aws ecr create-repository --repository-name aws-cookbook-repo
18 | ```
19 |
20 | ## Steps
21 | 1. Rather than building a new container image from a Dockerfile (as you did in Recipe 6.1), this time you are going to pull an old NGINX container image:
22 | ```
23 | docker pull nginx:1.14.1
24 | ```
25 | 2. On the command line, apply the scanning configuration to the repository you created:
26 | ```
27 | REPO=aws-cookbook-repo && \
28 | aws ecr put-image-scanning-configuration \
29 | --repository-name $REPO \
30 | --image-scanning-configuration scanOnPush=true
31 | ```
32 | 3. Get Docker login information:
33 | ```
34 | aws ecr get-login-password | docker login --username AWS \
35 | --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
36 | ```
37 | 4. Apply a tag to the image so that you can push it to the ECR repository:
38 | ```
39 | docker tag nginx:1.14.1 \
40 | $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:old
41 | ```
42 | 5. Push the image:
43 | ```
44 | docker push \
45 | $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:old
46 | ```
47 |
48 | ## Validation checks
49 | Shortly after the push is complete, you can examine the results of the security scan of the image in JSON format:
50 | ```
51 | aws ecr describe-image-scan-findings \
52 | --repository-name aws-cookbook-repo --image-id imageTag=old
53 | ```
54 | You should see output similar to the following:
55 | ```
56 | {
57 | "imageScanFindings": {
58 | "findings": [
59 | {
60 | "name": "CVE-2019-3462",
61 | "description": "Incorrect sanitation of the 302 redirect field in HTTP
62 | transport method of apt versions 1.4.8 and earlier can lead to content injection by
63 | a MITM attacker, potentially leading to remote code execution on the target
64 | machine.",
65 | "uri": "https://security-tracker.debian.org/tracker/CVE-2019-3462",
66 | "severity": "CRITICAL",
67 | "attributes": [
68 | {
69 | "key": "package_version",
70 | "value": "1.4.8"
71 | },
72 | ```
73 |
74 | ## Clean up
75 | ### Delete the image from your local machine
76 | ```
77 | docker image rm \
78 | $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:old
79 | docker image rm nginx:1.14.1
80 | ```
81 |
82 | ### Delete the image from ECR:
83 | ```
84 | aws ecr batch-delete-image --repository-name aws-cookbook-repo \
85 | --image-ids imageTag=old
86 | ```
87 |
88 | ### Delete the repository:
89 | ```
90 | aws ecr delete-repository --repository-name aws-cookbook-repo
91 | ```
92 |
93 | ## Discussion
94 | The [Common Vulnerabilities and Exposures (CVEs)](https://cve.mitre.org/) database from the open source [Clair project](https://github.com/quay/clair) is used by Amazon ECR for [vulnerability scanning](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html). You are provided a Common Vulnerability Scoring System (CVSS) score to indicate the severity of any detected vulnerabilities. This helps you detect and remediate vulnerabilities in your container image. You can configure alerts for newly discovered vulnerabilities in images by using Amazon EventBridge and Amazon Simple Notification Service (Amazon SNS).
95 |
96 | > WARNING: The scanning feature does not continuously scan your images, so it is important to push your image versions routinely (or trigger a manual scan).
97 |
98 | You can retrieve the results of the last scan for an image at any time with the com‐ mand used in the last step of this recipe. Furthermore, you can use these commands as part of an automated CI/CD process that may validate whether or not an image has a certain CVSS score before deploying.
99 |
100 | ### Challenge 1
101 | Remediate the vulnerability by updating the image with the latest NGINX container image.
102 |
103 | ### Challenge 2
104 | Configure an SNS topic to send you an email when vulnerabilities are detected in your repository.
105 |
--------------------------------------------------------------------------------
/606-Autoscaling-Container-Workloads/cdk-AWS-Cookbook-606/cdk_aws_cookbook_606/cdk_aws_cookbook_606_stack.py:
--------------------------------------------------------------------------------
1 | from constructs import Construct
2 | from aws_cdk import (
3 | aws_ec2 as ec2,
4 | aws_ecs as ecs,
5 | aws_elasticloadbalancingv2 as alb,
6 | aws_ecr_assets as ecr_assets,
7 | Stack,
8 | CfnOutput,
9 | Duration
10 | )
11 |
12 |
13 | class CdkAwsCookbook606Stack(Stack):
14 |
15 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
16 | super().__init__(scope, construct_id, **kwargs)
17 |
18 | ecr_asset = ecr_assets.DockerImageAsset(
19 | self,
20 | 'ecr_asset',
21 | directory='Docker',
22 | )
23 |
24 | # create VPC
25 | vpc = ec2.Vpc(
26 | self,
27 | 'AWS-Cookbook-VPC'
28 | )
29 |
30 | InterfaceEndpointSecurityGroup = ec2.SecurityGroup(
31 | self,
32 | 'InterfaceEndpointSecurityGroup',
33 | description='Security Group for the VPC Endpoints',
34 | allow_all_outbound=True,
35 | vpc=vpc
36 | )
37 |
38 | InterfaceEndpointSecurityGroup.connections.allow_from(
39 | ec2.Peer.ipv4(vpc.vpc_cidr_block), ec2.Port.tcp(443), "Ingress")
40 |
41 | vpc.add_interface_endpoint(
42 | 'CloudWatchLogsEndpoint',
43 | service=ec2.InterfaceVpcEndpointAwsService('logs'),
44 | private_dns_enabled=True,
45 | security_groups=[InterfaceEndpointSecurityGroup],
46 | subnets=ec2.SubnetSelection(
47 | one_per_az=True,
48 | subnet_type=ec2.SubnetType('PRIVATE_WITH_NAT')
49 | ),
50 | )
51 |
52 | albSecurityGroup = ec2.SecurityGroup(
53 | self,
54 | 'albSecurityGroup',
55 | description='Security Group for the ALB',
56 | allow_all_outbound=True,
57 | vpc=vpc
58 | )
59 |
60 | albSecurityGroup.add_ingress_rule(
61 | peer=ec2.Peer.ipv4("0.0.0.0/0"),
62 | connection=ec2.Port.tcp(80),
63 | description='Allow HTTP from the world',
64 | remote_rule=False
65 | )
66 |
67 | fargate_service_security_group = ec2.SecurityGroup(
68 | self,
69 | 'fargate_service_security_group',
70 | description='Security Group for the Fargate Service',
71 | allow_all_outbound=True,
72 | vpc=vpc
73 | )
74 |
75 | fargate_service_security_group.connections.allow_from(
76 | albSecurityGroup, ec2.Port.tcp(8080), "Ingress")
77 |
78 | # create ECS Cluster
79 | ecs_cluster = ecs.Cluster(
80 | self,
81 | 'AWS-Cookbook-EcsCluster',
82 | vpc=vpc
83 | )
84 |
85 | FargateTask = ecs.FargateTaskDefinition(
86 | self,
87 | 'FargateTask',
88 | cpu=256,
89 | memory_limit_mib=512,
90 | )
91 |
92 | ContainerDef = ecs.ContainerDefinition(
93 | self,
94 | 'ContainerDef',
95 | image=ecs.ContainerImage.from_docker_image_asset(ecr_asset),
96 | task_definition=FargateTask,
97 | )
98 |
99 | ContainerDef.add_port_mappings(
100 | ecs.PortMapping(
101 | container_port=8080
102 | )
103 | )
104 |
105 | FargateService = ecs.FargateService(
106 | self,
107 | 'awscookbook606',
108 | cluster=ecs_cluster,
109 | task_definition=FargateTask,
110 | assign_public_ip=False,
111 | desired_count=2,
112 | enable_ecs_managed_tags=False,
113 | max_healthy_percent=100,
114 | min_healthy_percent=0,
115 | platform_version=ecs.FargatePlatformVersion('LATEST'),
116 | security_groups=[fargate_service_security_group],
117 | service_name='AWSCookbook606',
118 | vpc_subnets=ec2.SubnetSelection(
119 | one_per_az=False,
120 | subnet_type=ec2.SubnetType('PRIVATE_WITH_NAT')
121 | )
122 | )
123 |
124 | lb = alb.ApplicationLoadBalancer(
125 | self,
126 | 'LB',
127 | vpc=vpc,
128 | deletion_protection=False,
129 | http2_enabled=True,
130 | idle_timeout=Duration.seconds(60),
131 | internet_facing=True,
132 | ip_address_type=alb.IpAddressType('IPV4'),
133 | load_balancer_name='FargateServiceALB',
134 | security_group=albSecurityGroup,
135 | vpc_subnets=ec2.SubnetSelection(
136 | one_per_az=False,
137 | subnet_type=ec2.SubnetType('PUBLIC')
138 | )
139 | )
140 |
141 | DefaultTargetGroup = alb.ApplicationTargetGroup(
142 | self,
143 | "DefaultTargetGroup",
144 | deregistration_delay=Duration.seconds(60),
145 | health_check=alb.HealthCheck(
146 | healthy_http_codes='200',
147 | healthy_threshold_count=2,
148 | interval=Duration.seconds(10),
149 | path='/loadtest/healthcheck',
150 | port='traffic-port',
151 | protocol=alb.Protocol('HTTP'),
152 | unhealthy_threshold_count=10
153 | ),
154 | port=80,
155 | vpc=vpc,
156 | target_group_name="DefaultTG",
157 | target_type=alb.TargetType('IP'),
158 | targets=[FargateService]
159 | )
160 |
161 | alb.ApplicationListener(
162 | self,
163 | 'listener80',
164 | load_balancer=lb,
165 | open=False,
166 | port=80,
167 | protocol=alb.ApplicationProtocol('HTTP'),
168 | default_target_groups=[DefaultTargetGroup]
169 | )
170 |
171 | CfnOutput(
172 | self, 'LoadBalancerDns',
173 | value=lb.load_balancer_dns_name
174 | )
175 |
176 | CfnOutput(
177 | self, 'EcsClusterName',
178 | value=ecs_cluster.cluster_name
179 | )
180 |
181 | CfnOutput(
182 | self,
183 | 'EcrImage',
184 | value=ecr_asset.image_uri
185 | )
186 |
--------------------------------------------------------------------------------
/607-Fargate-Task-With-Event/README.md:
--------------------------------------------------------------------------------
1 | # Launching a Fargate container task in response to an event
2 |
3 | ## Problem
4 | You need to launch a container task to process incoming files.
5 |
6 | 
7 |
8 | ### Prerequisites
9 | * Amazon Virtual Private Cloud (VPC) with isolated or private subnets and associated route tables
10 | * Two Simple Storage Service (S3) Buckets
11 | * CloudTrail Enabled
12 | * An Elastic Container Service (ECS) Cluster for Fargate, a Fargate Task Definition, and a Container Definition
13 | * AWS CLI v2
14 |
15 | > TIP: These prerequisites are all included in the CDK code associated with this recipe.
16 |
17 | ## Preparation
18 | ### This recipe requires some “prep work” which deploys resources that you’ll build the solution on. You will use the AWS CDK to deploy these resources
19 |
20 | ### In the root of this Chapter’s repo cd to the “607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607” directory and follow the subsequent steps:
21 | ```
22 | cd 607-Fargate-Task-With-Event/cdk-AWS-Cookbook-607/
23 | test -d .venv || python3 -m venv .venv
24 | source .venv/bin/activate
25 | pip install --upgrade pip
26 | pip install -r requirements.txt
27 | cdk deploy
28 | ```
29 |
30 | ### Wait for the cdk deploy command to complete.
31 |
32 | ### We created a helper.py script to let you easily create and export environment variables to make subsequent commands easier. Run the script, and copy the output to your terminal to export variables:
33 |
34 | `python helper.py`
35 |
36 | ### Navigate up to the main directory for this recipe (out of the “cdk-AWS-Cookbook-607” directory)
37 |
38 | `cd ..`
39 |
40 | ## Steps
41 | 1. Configure CloudTrail to log events on the S3 bucket:
42 | ```
43 | aws cloudtrail put-event-selectors --trail-name $CLOUD_TRAIL_ARN --event-selectors "[{ \"ReadWriteType\":
44 | \"WriteOnly\", \"IncludeManagementEvents\":false, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\",
45 | \"Values\": [\"arn:aws:s3:::$BUCKET_NAME/input/\"] }], \"ExcludeManagementEventSources\": [] }]"
46 | ```
47 |
48 | 2. Create an assume-role policy JSON statement called policy1.json to use in the next step (this file is provided in the repository) and create the role:
49 | ```
50 | {
51 | "Version": "2012-10-17",
52 | "Statement": [
53 | {
54 | "Effect": "Allow",
55 | "Principal": {
56 | "Service": "events.amazonaws.com"
57 | },
58 | "Action": "sts:AssumeRole"
59 | }
60 | ]
61 | }
62 | ```
63 |
64 | ```
65 | aws iam create-role --role-name AWSCookbook607RuleRole \
66 | --assume-role-policy-document file://policy1.json
67 | ```
68 |
69 | 3. You will also need a policy document with the following content called policy2.json (this file is provided in the repository):
70 | ```
71 | {
72 | "Version": "2012-10-17",
73 | "Statement": [
74 | {
75 | "Effect": "Allow",
76 | "Action": [
77 | "ecs:RunTask"
78 | ],
79 | "Resource": [
80 | "arn:aws:ecs:*:*:task-definition/*"
81 | ]
82 | },
83 | {
84 | "Effect": "Allow",
85 | "Action": "iam:PassRole",
86 | "Resource": [
87 | "*"
88 | ],
89 | "Condition": {
90 | "StringLike": {
91 | "iam:PassedToService": "ecs-tasks.amazonaws.com"
92 | }
93 | }
94 | }
95 | ]
96 | }
97 | ```
98 |
99 | 4. Now attach the IAM policy JSON you just created to the IAM role:
100 |
101 | ```
102 | aws iam put-role-policy --role-name AWSCookbook607RuleRole \
103 | --policy-name ECSRunTaskPermissionsForEvents \
104 | --policy-document file://policy2.json
105 | ```
106 |
107 | 5. Create an EventBridge rule that monitors the S3 bucket for file uploads:
108 |
109 | ```
110 | aws events put-rule --name "AWSCookbookRule" --role-arn "arn:aws:iam::$AWS_ACCOUNT_ID:role/AWSCookbook607RuleRole" --event-pattern "{\"source\":[\"aws.s3\"],\"detail-type\":[\"AWS API Call via CloudTrail\"],\"detail\":{\"eventSource\":[\"s3.amazonaws.com\"],\"eventName\":[\"CopyObject\",\"PutObject\",\"CompleteMultipartUpload\"],\"requestParameters\":{\"bucketName\":[\"$BUCKET_NAME\"]}}}"
111 | ```
112 |
113 | 6. Modify the value in targets-template.json and create a targets.json for use:
114 |
115 | ```
116 | sed -e "s|AWS_ACCOUNT_ID|${AWS_ACCOUNT_ID}|g" \
117 | -e "s|AWS_REGION|${AWS_REGION}|g" \
118 | -e "s|ECSClusterARN|${ECS_CLUSTER_ARN}|g" \
119 | -e "s|TaskDefinitionARN|${TASK_DEFINITION_ARN}|g" \
120 | -e "s|VPCPrivateSubnets|${VPC_PRIVATE_SUBNETS}|g" \
121 | -e "s|VPCDefaultSecurityGroup|${VPC_DEFAULT_SECURITY_GROUP}|g" \
122 | targets-template.json > targets.json
123 | ```
124 |
125 | 7. Create a rule target that specifies the ECS cluster, ECS task definition, IAM role, and networking parameters. This specifies what the rule will trigger; in this case, launch a container on Fargate:
126 |
127 | ```
128 | aws events put-targets --rule AWSCookbookRule \
129 | --targets file://targets.json
130 | ```
131 |
132 | 8. Check the S3 bucket to verify that it’s empty before we populate it:
133 |
134 | `aws s3 ls s3://$BUCKET_NAME/`
135 |
136 | 9. Copy the provided maze.jpg file to the S3 bucket. This will trigger the ECS task that launches a container with a Python library to process the file:
137 |
138 |
139 | `aws s3 cp maze.jpg s3://$BUCKET_NAME/input/maze.jpg`
140 |
141 | This will trigger an ECS task to process the image file. Quickly, check the task with the ecs list-tasks command. The task will run for about two to three minutes:
142 |
143 | `aws ecs list-tasks --cluster $ECS_CLUSTER_ARN`
144 |
145 | ## Validation checks
146 |
147 | After a few minutes, observe the output directory created in the S3 bucket:
148 |
149 | `aws s3 ls s3://$BUCKET_NAME/output/`
150 |
151 | Download and view the output file:
152 |
153 | `aws s3 cp s3://$BUCKET_NAME/output/output.jpg ./output.jpg`
154 |
155 | Open output.jpg with a file viewer of your choice to view the file that was processed.
156 |
157 |
158 | ## Clean up
159 | ### Remove the EventBridge targets from the EventBridge rule:
160 |
161 | `aws events remove-targets --rule AWSCookbookRule --ids AWSCookbookRuleID`
162 |
163 | ### Delete the EventBridge rule:
164 |
165 | `aws events delete-rule --name "AWSCookbookRule"`
166 |
167 | ### Detach the policies and delete the EventBridge Rule IAM role:
168 | ```
169 | aws iam delete-role-policy --role-name AWSCookbook607RuleRole \
170 | --policy-name ECSRunTaskPermissionsForEvents
171 |
172 | aws iam delete-role --role-name AWSCookbook607RuleRole
173 | ```
174 |
175 | ### Stop the Cloudtrail
176 |
177 | `aws cloudtrail stop-logging --name $CLOUD_TRAIL_ARN`
178 |
179 | ### Go to the cdk-AWS-Cookbook-607 directory
180 |
181 | `cd cdk-AWS-Cookbook-607/`
182 |
183 | ### To clean up the environment variables, run the helper.py script in this recipe’s cdk- directory with the --unset flag, and copy the output to your terminal to export variables:
184 |
185 | `python helper.py --unset`
186 |
187 | ### Use the AWS CDK to destroy the resources, deactivate your Python virtual environment, and go to the root of the chapter:
188 |
189 | `cdk destroy && deactivate && rm -r .venv/ && cd ../..`
190 |
191 | ## Discussion
192 |
193 | Event-driven architecture is an important approach to application and process design in the cloud. This type of design allows for removing long-running application workloads in favor of serverless architectures, which can be more resilient and easily scale to peaks of higher usage when needed. When there are no events to handle in your application, you generally do not pay much for compute resources (if at all), so potential cost savings is also a point to consider when choosing an application architecture.
194 |
195 | > NOTE: It is common to use Lambda functions with S3 for event-driven architectures, but for longer-running data-processing jobs and computational jobs like this one, Fargate is a better choice because the runtime is essentially infinite, while the maximum runtime for Lambda functions is limited.
196 |
197 | Amazon ECS can run tasks and services. Services are made up of tasks, and generally, are long-running in that a service keeps a specific set of tasks running. Tasks can be short-lived; a container may start, process some data, and then gracefully exit after the task is complete. This is what you have achieved in this solution: a task was launched in response to an S3 event signaling a new object, and the container read the object, processed the file, and exited.
198 |
199 | ### Challenge
200 |
201 | While EventBridge is a powerful solution that can be used to orchestrate many types of event-driven solutions, you can achieve similar functionality with S3’s triggers. Try to deploy and configure a Lambda function to be invoked directly from S3 events. [Here is a hint](https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html)
202 |
203 |
204 |
--------------------------------------------------------------------------------
/605-Updating-Containers-With-BlueGreen/cdk-AWS-Cookbook-605/cdk_aws_cookbook_605/cdk_aws_cookbook_605_stack.py:
--------------------------------------------------------------------------------
1 | from constructs import Construct
2 | from aws_cdk import (
3 | aws_ec2 as ec2,
4 | aws_ecs as ecs,
5 | aws_s3 as s3,
6 | aws_ecr_assets as ecr_assets,
7 | aws_elasticloadbalancingv2 as alb,
8 | Stack,
9 | CfnOutput,
10 | Duration,
11 | RemovalPolicy
12 | )
13 |
14 |
15 | class CdkAwsCookbook605Stack(Stack):
16 |
17 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
18 | super().__init__(scope, construct_id, **kwargs)
19 |
20 | ecr_asset_blue = ecr_assets.DockerImageAsset(
21 | self,
22 | 'ecr_asset_blue',
23 | directory='DockerBlue',
24 | )
25 |
26 | ecr_asset_green = ecr_assets.DockerImageAsset(
27 | self,
28 | 'ecr_asset_green',
29 | directory='DockerGreen',
30 | )
31 |
32 | # create VPC
33 | vpc = ec2.Vpc(
34 | self,
35 | 'AWS-Cookbook-VPC'
36 | )
37 |
38 | albSecurityGroup = ec2.SecurityGroup(
39 | self,
40 | 'albSecurityGroup',
41 | description='Security Group for the ALB',
42 | allow_all_outbound=True,
43 | vpc=vpc
44 | )
45 |
46 | albSecurityGroup.add_ingress_rule(
47 | peer=ec2.Peer.ipv4("0.0.0.0/0"),
48 | connection=ec2.Port.tcp(80),
49 | description='Allow HTTP from the world',
50 | remote_rule=False
51 | )
52 |
53 | albSecurityGroup.add_ingress_rule(
54 | peer=ec2.Peer.ipv4("0.0.0.0/0"),
55 | connection=ec2.Port.tcp(8080),
56 | description='Allow 8080 from the world',
57 | remote_rule=False
58 | )
59 |
60 | fargate_service_security_group = ec2.SecurityGroup(
61 | self,
62 | 'fargate_service_security_group',
63 | description='Security Group for the Fargate Service',
64 | allow_all_outbound=True,
65 | vpc=vpc
66 | )
67 |
68 | fargate_service_security_group.connections.allow_from(
69 | albSecurityGroup, ec2.Port.tcp(80), "Ingress")
70 |
71 | # create ECS Cluster
72 | ecs_cluster = ecs.Cluster(
73 | self,
74 | 'AWS-Cookbook-EcsCluster',
75 | cluster_name='awscookbook605',
76 | vpc=vpc
77 | )
78 |
79 | FargateTaskBlue = ecs.FargateTaskDefinition(
80 | self,
81 | 'FargateTaskBlue',
82 | cpu=256,
83 | memory_limit_mib=512,
84 | )
85 |
86 | ContainerDefBlue = ecs.ContainerDefinition(
87 | self,
88 | 'ContainerDefBlue',
89 | image=ecs.ContainerImage.from_docker_image_asset(ecr_asset_blue),
90 | task_definition=FargateTaskBlue,
91 | )
92 |
93 | ContainerDefBlue.add_port_mappings(
94 | ecs.PortMapping(
95 | container_port=80
96 | )
97 | )
98 |
99 | FargateTaskGreen = ecs.FargateTaskDefinition(
100 | self,
101 | 'FargateTaskGreen',
102 | cpu=256,
103 | memory_limit_mib=512,
104 | )
105 |
106 | ContainerDefGreen = ecs.ContainerDefinition(
107 | self,
108 | 'ContainerDefGreen',
109 | image=ecs.ContainerImage.from_docker_image_asset(ecr_asset_green),
110 | task_definition=FargateTaskGreen,
111 | )
112 |
113 | ContainerDefGreen.add_port_mappings(
114 | ecs.PortMapping(
115 | container_port=80
116 | )
117 | )
118 |
119 | FargateService = ecs.FargateService(
120 | self,
121 | 'awscookbook605',
122 | cluster=ecs_cluster,
123 | task_definition=FargateTaskBlue,
124 | assign_public_ip=False,
125 | desired_count=2,
126 | enable_ecs_managed_tags=False,
127 | # health_check_grace_period=Duration.seconds(60),
128 | max_healthy_percent=100,
129 | min_healthy_percent=0,
130 | platform_version=ecs.FargatePlatformVersion('LATEST'),
131 | security_groups=[fargate_service_security_group],
132 | service_name='AWSCookbook605',
133 | deployment_controller=ecs.DeploymentController(
134 | type=ecs.DeploymentControllerType('CODE_DEPLOY')
135 | ),
136 | vpc_subnets=ec2.SubnetSelection(
137 | one_per_az=False,
138 | subnet_type=ec2.SubnetType('PRIVATE_WITH_NAT')
139 | )
140 | )
141 |
142 | lb = alb.ApplicationLoadBalancer(
143 | self,
144 | 'LB',
145 | vpc=vpc,
146 | deletion_protection=False,
147 | http2_enabled=True,
148 | idle_timeout=Duration.seconds(60),
149 | internet_facing=True,
150 | ip_address_type=alb.IpAddressType('IPV4'),
151 | load_balancer_name='FargateServiceALB',
152 | security_group=albSecurityGroup,
153 | vpc_subnets=ec2.SubnetSelection(
154 | one_per_az=False,
155 | subnet_type=ec2.SubnetType('PUBLIC')
156 | )
157 | )
158 |
159 | DefaultTargetGroup = alb.ApplicationTargetGroup(
160 | self,
161 | "DefaultTargetGroup",
162 | port=80,
163 | vpc=vpc,
164 | target_group_name="DefaultTG",
165 | target_type=alb.TargetType('IP'),
166 | )
167 |
168 | listener80 = alb.ApplicationListener(
169 | self,
170 | 'listener80',
171 | load_balancer=lb,
172 | open=False,
173 | port=80,
174 | protocol=alb.ApplicationProtocol('HTTP'),
175 | default_target_groups=[DefaultTargetGroup]
176 | )
177 |
178 | BlueTargetGroup = listener80.add_targets(
179 | 'BlueTargetGroup',
180 | conditions=[alb.ListenerCondition.http_header(
181 | name="All",
182 | values=['*.*.*'],
183 | )],
184 | deregistration_delay=Duration.seconds(60),
185 | health_check=alb.HealthCheck(
186 | healthy_http_codes='200',
187 | healthy_threshold_count=2,
188 | interval=Duration.seconds(10),
189 | path='/',
190 | port='traffic-port',
191 | protocol=alb.Protocol('HTTP'),
192 | unhealthy_threshold_count=2
193 | ),
194 | port=80,
195 | priority=1,
196 | protocol=alb.ApplicationProtocol('HTTP'),
197 | target_group_name="BlueTG",
198 | targets=[FargateService]
199 | )
200 |
201 | listener8080 = alb.ApplicationListener(
202 | self,
203 | 'listener8080',
204 | load_balancer=lb,
205 | open=False,
206 | port=8080,
207 | protocol=alb.ApplicationProtocol('HTTP'),
208 | default_target_groups=[BlueTargetGroup]
209 | )
210 |
211 | # create s3 bucket
212 | s3_Bucket = s3.Bucket(
213 | self,
214 | "AWS-Cookbook-Recipe605",
215 | removal_policy=RemovalPolicy.DESTROY,
216 | auto_delete_objects=True
217 | )
218 |
219 | # outputs
220 |
221 | CfnOutput(
222 | self,
223 | 'BlueImage',
224 | value=ecr_asset_blue.image_uri
225 | )
226 |
227 | CfnOutput(
228 | self,
229 | 'GreenImage',
230 | value=ecr_asset_green.image_uri
231 | )
232 |
233 | CfnOutput(
234 | self,
235 | 'VpcId',
236 | value=vpc.vpc_id
237 | )
238 |
239 | CfnOutput(
240 | self,
241 | 'LoadBalancerDns',
242 | value=lb.load_balancer_dns_name
243 | )
244 |
245 | CfnOutput(
246 | self,
247 | 'EcsClusterName',
248 | value=ecs_cluster.cluster_name
249 | )
250 |
251 | public_subnets = vpc.select_subnets(subnet_type=ec2.SubnetType.PUBLIC)
252 |
253 | CfnOutput(
254 | self,
255 | 'VpcPublicSubnets',
256 | value=', '.join(map(str, public_subnets.subnet_ids))
257 | )
258 |
259 | CfnOutput(
260 | self,
261 | 'VpcDefaultSecurityGroup',
262 | value=vpc.vpc_default_security_group
263 | )
264 |
265 | CfnOutput(
266 | self,
267 | 'BucketName',
268 | value=s3_Bucket.bucket_name
269 | )
270 |
271 | CfnOutput(
272 | self,
273 | 'BlueTargetGroupName',
274 | value=BlueTargetGroup.target_group_arn
275 | )
276 |
277 | CfnOutput(
278 | self,
279 | 'ProdListenerArn',
280 | value=listener80.listener_arn
281 | )
282 |
283 | CfnOutput(
284 | self,
285 | 'TestListenerArn',
286 | value=listener8080.listener_arn
287 | )
288 |
289 | CfnOutput(
290 | self,
291 | 'DefaultTargetGroupArn',
292 | value=DefaultTargetGroup.target_group_arn
293 | )
294 |
295 | CfnOutput(
296 | self,
297 | 'FargateTaskBlueArn',
298 | value=FargateTaskBlue.task_definition_arn
299 | )
300 |
301 | CfnOutput(
302 | self,
303 | 'FargateTaskGreenArn',
304 | value=FargateTaskGreen.task_definition_arn
305 | )
306 |
--------------------------------------------------------------------------------