├── README.md
├── amazon-api-gateway
├── api-lambda-dynamodb-hol.md
├── rest-api-lambda-proxy.py
└── url-commands-to-run.md
├── amazon-cloudfront
├── .DS_Store
├── cloudfront-cache-and-behavior.md
├── files
│ ├── coffee.jpg
│ ├── data-analysis.pdf
│ ├── documents.pdf
│ └── donut.jpg
└── index.html
├── amazon-cloudwatch
├── .DS_Store
└── custom-cloudwatch-metrics.md
├── amazon-dynamodb
├── DynamoDB CLI Commands.sh
├── addupdateorder.json
└── mystore.json
├── amazon-ebs
└── amazon-ebs-volumes.md
├── amazon-ec2
├── create-asg-alb-cli.md
├── ec2-user-data-web-app.md
├── generate-load-on-alb.md
├── user-data-metadata.md
└── user-data-web-server.sh
├── amazon-ecs
└── ec2-cluster-instances.md
├── amazon-efs
├── .DS_Store
└── working-with-efs.md
├── amazon-elasticache
└── add-retrieve-value.md
├── amazon-s3
├── .DS_Store
├── event-notification-sns.json
├── permissions-lesson
│ ├── bucket-policy.json
│ ├── identity-policy-deny.json
│ └── identity-policy.json
├── presigned_index.html
├── s3-enforce-kms-encryption.json
├── s3-replication-permissions.json
└── s3-trust-policy.json
├── amazon-sqs
├── aws-sqs-cli-commands.md
└── lambda-code-sns-sqs.py
├── amazon-vpc
├── .DS_Store
└── custom-vpc.md
├── aws-cloudformation
├── .DS_Store
├── 1-ec2-template.yml
├── 2-ec2-template.yml
├── 3-ec2-template.yml
├── Create Nested Stack using the AWS CLI.md
└── create-vpc-with-cloudformation.yaml
├── aws-copilot
└── copilot-commands.md
├── aws-developer-tools
├── AppSpec Examples
│ ├── appspec-example-ec2.yml
│ ├── appspec-example-ecs.yml
│ └── appspec-example-lambda.yml
├── appspec.yml
├── basic-git-commands.md
├── buildspec.yml
└── nodejs-blue.zip
├── aws-iam
├── .DS_Store
├── profile-ec2-full-access.config
└── sts-assume-role.json
├── aws-kms
└── kms-key-ebs-rds.json
├── aws-lambda
├── destinations-and-dlq.md
├── event-source-mapping.md
├── invoke-lambda-versions-aliases.md
├── invoking-functions.md
├── lambda-environ-test.md
└── sam-cli-commands.md
├── aws-secrets-manager
└── secrets-manager-cli-commands.md
├── aws-step-functions
└── Step Functions with Lambda.md
└── fargate-blue-green-ci-cd
├── appspec.yaml
├── create-service.json
├── ecr-allow-all.json
├── fargate-ci-cd-instructions.md
└── taskdef.json
/README.md:
--------------------------------------------------------------------------------
1 | # AWS Certified Developer Associate (DVA-C02) Course Code
2 | *By [Digital Cloud Training](https://digitalcloud.training/) - Course Author Neal Davis*
3 |
4 | ## How to Use the Course Code
5 |
6 | The code used throughout the course has been zipped up and is available for download from this repo. Please download the code to your computer and unzip the contents. When course updates are made the file may be updated and you will need to ensure you download the latest version.
7 |
8 | ## Course Overview
9 |
10 | In this course, you’ll learn everything you need to know to ace your AWS Certified Developer Associate exam.
11 |
12 | Use the practical exercises to learn how to architect and build applications on Amazon Web Services (AWS).
13 |
14 | The course includes many visual slides to help you understand the concepts.
15 |
16 | At the end of each section use the exam cram lesson for quick revision of the important facts and take the quizzes to test your knowledge.
17 |
18 | ***What you will learn: ***
19 |
20 | This course covers all of the following topics that are included in the AWS Certified Developer Associate (DVA-C02) exam guide and are featuring on the exam today:
21 |
22 | - AWS Serverless including AWS Lambda, Amazon API Gateway, Amazon DynamoDB, AWS Cognito and the AWS serverless application model (SAM)
23 | - Docker containers on AWS with Amazon Elastic Container Service (ECS) and AWS Fargate
24 | - AWS Developer Tools including AWS CodeCommit, CodeBuild, CodeDeploy, CodePipeline and CodeStar
25 | - Amazon EC2 including Auto Scaling and Elastic Load Balancing (ELB)
26 | - Amazon Virtual Private Cloud (VPC) including Security Groups, Network ACLs and Flow Logs
27 | - Amazon Route 53 and Amazon CloudFront
28 | - AWS Storage including Amazon S3 and Amazon EBS
29 | - The AWS CLI, SDK and APIs
30 | - AWS CloudFormation and Elastic Beanstalk
31 | - Amazon RDS, ElastiCache, and DynamoDB DAX
32 | - AWS Application integration services including Amazon SQS, SNS, AWS Step Functions and Amazon Kinesis
33 | - Monitoring, logging and tracing with Amazon CloudWatch, CloudTrail and AWS X-Ray
34 | - Security and access management with AWS IAM, Cognito, KMS, ACM, Systems Manager, and Secrets Manager
35 |
36 | Learn more and [enroll in this course](https://digitalcloud.training/aws-certified-developer-associate/) now to get started with your AWS Certified Developer Associate certification
37 |
--------------------------------------------------------------------------------
/amazon-api-gateway/api-lambda-dynamodb-hol.md:
--------------------------------------------------------------------------------
1 | ## 1 - Create IAM policy for Lambda execution role
2 |
3 | Create a policy named lambda-apigateway-policy
4 |
5 | Use the following JSON:
6 |
7 | ```json
8 | {
9 | "Version": "2012-10-17",
10 | "Statement": [
11 | {
12 | "Sid": "Stmt1428341300017",
13 | "Action": [
14 | "dynamodb:DeleteItem",
15 | "dynamodb:GetItem",
16 | "dynamodb:PutItem",
17 | "dynamodb:Query",
18 | "dynamodb:Scan",
19 | "dynamodb:UpdateItem"
20 | ],
21 | "Effect": "Allow",
22 | "Resource": "*"
23 | },
24 | {
25 | "Sid": "",
26 | "Resource": "*",
27 | "Action": [
28 | "logs:CreateLogGroup",
29 | "logs:CreateLogStream",
30 | "logs:PutLogEvents"
31 | ],
32 | "Effect": "Allow"
33 | }
34 | ]
35 | }
36 | ```
37 |
38 | ## 2 - Create the execution role
39 |
40 |
41 | Create a role named lambda-apigateway-role
42 |
43 | Use case should be Lambda
44 |
45 | Attach the lambda-apigateway-policy
46 |
47 |
48 | ## 3 - Create the Lambda function
49 |
50 | Create a function named "LambdaFunctionOverHttps"
51 |
52 | Use the latest Python runtime
53 |
54 | Use the lambda-apigateway-role as the execution role
55 |
56 | Add the following code:
57 |
58 | ```python
59 | import json
60 | import boto3
61 |
62 | dynamo = boto3.client('dynamodb')
63 |
64 | def lambda_handler(event, context):
65 |
66 | operation = event.get('operation')
67 |
68 | # Ensure TableName is included in payload
69 | if 'tableName' in event:
70 | event['payload']['TableName'] = event['tableName']
71 |
72 | try:
73 | if operation == 'create':
74 | event['payload']['Item'] = format_item(event['payload']['Item'])
75 | dynamo.put_item(**event['payload'])
76 | key = {k: v for k, v in event['payload']['Item'].items() if 'id' in k.lower()}
77 | response = dynamo.get_item(TableName=event['payload']['TableName'], Key=key)
78 | elif operation == 'read':
79 | event['payload']['Key'] = format_item(event['payload']['Key'])
80 | response = dynamo.get_item(**event['payload'])
81 | elif operation == 'update':
82 | event['payload']['Key'] = format_item(event['payload']['Key'])
83 | event['payload']['AttributeUpdates'] = format_updates(event['payload']['AttributeUpdates'])
84 | response = dynamo.update_item(**event['payload'])
85 | elif operation == 'delete':
86 | event['payload']['Key'] = format_item(event['payload']['Key'])
87 | response = dynamo.delete_item(**event['payload'])
88 | elif operation == 'list':
89 | response = dynamo.scan(**event['payload'])
90 | elif operation == 'echo':
91 | response = "Success"
92 | elif operation == 'ping':
93 | response = "pong"
94 | else:
95 | raise ValueError(f"Unknown operation: {operation}")
96 |
97 | return {
98 | 'statusCode': 200,
99 | 'body': json.dumps(response)
100 | }
101 | except Exception as e:
102 | return {
103 | 'statusCode': 400,
104 | 'body': json.dumps({'error': str(e)})
105 | }
106 |
107 | def format_item(raw_item):
108 |
109 | formatted_item = {}
110 | for key, value in raw_item.items():
111 | if isinstance(value, str):
112 | formatted_item[key] = {"S": value}
113 | elif isinstance(value, int) or isinstance(value, float):
114 | formatted_item[key] = {"N": str(value)}
115 | elif isinstance(value, list):
116 | formatted_item[key] = {"L": [format_item(item) if isinstance(item, dict) else item for item in value]}
117 | elif isinstance(value, dict):
118 | formatted_item[key] = {"M": format_item(value)}
119 | else:
120 | raise ValueError(f"Unsupported type for key {key}: {type(value)}")
121 | return formatted_item
122 |
123 | def format_updates(raw_updates):
124 |
125 | formatted_updates = {}
126 | for key, value in raw_updates.items():
127 | action = value.get("Action", "PUT") # Default action is PUT
128 | formatted_value = format_item({key: value["Value"]})[key]
129 | formatted_updates[key] = {
130 | "Value": formatted_value,
131 | "Action": action
132 | }
133 | return formatted_updates
134 | ```
135 |
136 |
137 | ## 4 - Test the function
138 |
139 | Use the following code to test the function:
140 |
141 | ```json
142 | {
143 | "operation": "echo",
144 | "payload": {
145 | "somekey1": "somevalue1",
146 | "somekey2": "somevalue2"
147 | }
148 | }
149 | ```
150 |
151 | Optionally, save in a text file named input.txt and execute the following CLI command:
152 |
153 | aws lambda invoke --function-name LambdaFunctionOverHttps --payload file://input.txt outputfile.txt
154 |
155 | ## 5 - Create REST API
156 |
157 | Create a REST API named "DynamoDBOperations"
158 |
159 | New API with a regional endpoint
160 |
161 | ## 6 - Create resource and method
162 |
163 | Create a resource named dynamodbmanager
164 |
165 | Create a POST method for the /dynamodbmanager resource
166 |
167 | Use a Lambda integration (non proxy) and enter the function name as LambdaFunctionOverHttps
168 |
169 | ## 7 - Create a DynamoDB table
170 |
171 | Create a table named lambda-apigateway
172 |
173 | For the partition key use "id" (string)
174 |
175 | ## 8 - Test the configuration
176 |
177 | In the REST API go to the /dynamodbmanager resource and choose the POST method
178 |
179 | In the Method Execution pane, in the Client box, choose Test
180 |
181 | In the Method Test pane, keep Query String and Headers empty, and for the request body enter the following JSON and choose "Test":
182 |
183 | ```json
184 | {
185 | "operation": "create",
186 | "tableName": "lambda-apigateway",
187 | "payload": {
188 | "Item": {
189 | "id": "1234ABCDE",
190 | "number": 5
191 | }
192 | }
193 | }
194 | ```
195 |
196 | A 200 indicates a successful operation. Go to DynamoDB to check
197 |
198 | You can also update an item:
199 |
200 | ```json
201 | {
202 | "operation": "update",
203 | "tableName": "lambda-apigateway",
204 | "payload": {
205 | "Key": {
206 | "id": "1234ABCD"
207 | },
208 | "AttributeUpdates": {
209 | "number": {
210 | "Value": 999
211 | }
212 | }
213 | }
214 | }
215 | ```
216 |
--------------------------------------------------------------------------------
/amazon-api-gateway/rest-api-lambda-proxy.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | def lambda_handler(event, context):
4 | name = "you"
5 | city = "World"
6 | time = "day"
7 | day = ""
8 | response_code = 200
9 |
10 | print("request:", json.dumps(event))
11 |
12 | query_params = event.get("queryStringParameters") or {}
13 | headers = event.get("headers") or {}
14 | body = json.loads(event.get("body", "{}")) if event.get("body") else {}
15 |
16 | if "name" in query_params:
17 | print("Received name:", query_params["name"])
18 | name = query_params["name"]
19 |
20 | if "city" in query_params:
21 | print("Received city:", query_params["city"])
22 | city = query_params["city"]
23 |
24 | if "day" in headers:
25 | print("Received day:", headers["day"])
26 | day = headers["day"]
27 |
28 | if "time" in body:
29 | time = body["time"]
30 |
31 | greeting = f"Good {time}, {name} of {city}."
32 | if day:
33 | greeting += f" Happy {day}!"
34 |
35 | response_body = {
36 | "message": greeting,
37 | "input": event
38 | }
39 |
40 | response = {
41 | "statusCode": response_code,
42 | "headers": {
43 | "x-custom-header": "my custom header value"
44 | },
45 | "body": json.dumps(response_body)
46 | }
47 |
48 | print("response:", json.dumps(response))
49 | return response
--------------------------------------------------------------------------------
/amazon-api-gateway/url-commands-to-run.md:
--------------------------------------------------------------------------------
1 | ## Run the API using this URL format:
2 |
3 | https://API/STAGE/helloworld?name=NAME&city=CITY
4 |
5 | ## Or use curl:
6 |
7 | curl -v POST "API/STAGE/helloworld?name=NAME&city=CITY" -H "content-type: application/json" -H "day: DAY" -d "{ \"time\": \"TIMEOFDAY\" }"
--------------------------------------------------------------------------------
/amazon-cloudfront/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nealdct/aws-dva-code/0b558a18c3fed95028fad930aa383d95e5a641e3/amazon-cloudfront/.DS_Store
--------------------------------------------------------------------------------
/amazon-cloudfront/cloudfront-cache-and-behavior.md:
--------------------------------------------------------------------------------
1 | # Amazon CloudFront Cache and Behavior Settings
2 |
3 | 1. Set up Amazon S3 buckets:
4 | - Create two S3 buckets for the files (e.g., 'pdf-bucket' and 'jpg-bucket')
5 | - Upload sample PDF files to the 'pdf-bucket' and JPG images to the 'jpg-bucket'
6 | - Create a bucket for the static website
7 |
8 | 2. For the static website:
9 | - Enable public access
10 | - Configure as a static website
11 | - Add the index.html (when ready)
12 |
13 | 3. Configure Amazon CloudFront:
14 | - Create a new CloudFront distribution
15 | - Add the static website as an origin (use website endpoint)
16 | - Disable caching
17 | - Add 2 more origins for the buckets containing the files and create/configure OAC
18 | - Configure cache behavior settings for each origin based on file type (PDF or JPG) and default going to the static website
--------------------------------------------------------------------------------
/amazon-cloudfront/files/coffee.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nealdct/aws-dva-code/0b558a18c3fed95028fad930aa383d95e5a641e3/amazon-cloudfront/files/coffee.jpg
--------------------------------------------------------------------------------
/amazon-cloudfront/files/data-analysis.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nealdct/aws-dva-code/0b558a18c3fed95028fad930aa383d95e5a641e3/amazon-cloudfront/files/data-analysis.pdf
--------------------------------------------------------------------------------
/amazon-cloudfront/files/documents.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nealdct/aws-dva-code/0b558a18c3fed95028fad930aa383d95e5a641e3/amazon-cloudfront/files/documents.pdf
--------------------------------------------------------------------------------
/amazon-cloudfront/files/donut.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nealdct/aws-dva-code/0b558a18c3fed95028fad930aa383d95e5a641e3/amazon-cloudfront/files/donut.jpg
--------------------------------------------------------------------------------
/amazon-cloudfront/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Sample Deployment
6 |
26 |
27 |
28 |
29 |
S3 Static Website
30 |
Welcome to the Static Website
31 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/amazon-cloudwatch/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nealdct/aws-dva-code/0b558a18c3fed95028fad930aa383d95e5a641e3/amazon-cloudwatch/.DS_Store
--------------------------------------------------------------------------------
/amazon-cloudwatch/custom-cloudwatch-metrics.md:
--------------------------------------------------------------------------------
1 | **These commands can be executed using AWS CloudShell**
2 |
3 | ## Create an IAM role and instance profile
4 |
5 | 1. Create an IAM policy
6 |
7 | aws iam create-policy --policy-name "CloudWatch-Put-Metric-Data" --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["cloudwatch:PutMetricData"],"Resource":"*"}]}'
8 |
9 | 2. Create an IAM role that uses the policy document
10 |
11 | aws iam create-role --role-name "CloudWatch-Role" --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
12 |
13 | 3. Attach the policy to the role (update policy ARN)
14 |
15 | aws iam attach-role-policy --role-name "CloudWatch-Role" --policy-arn ""
16 |
17 | 4. Create an instance profile
18 |
19 | aws iam create-instance-profile --instance-profile-name "CloudWatch-Instance-Profile"
20 |
21 | 5. Add the role to the instance profile
22 |
23 | aws iam add-role-to-instance-profile --instance-profile-name "CloudWatch-Instance-Profile" --role-name "CloudWatch-Role"
24 |
25 | ## Launch an EC2 instance
26 |
27 | 1. Create a security group
28 |
29 | aws ec2 create-security-group --group-name CustomMetricLab --description "Temporary SG for the Custom Metric Lab"
30 |
31 | 2. Add a rule for SSH inbound to the security group
32 |
33 | aws ec2 authorize-security-group-ingress --group-name CustomMetricLab --protocol tcp --port 22 --cidr 0.0.0.0/0
34 |
35 | 3. Launch instance in US-EAST-1A
36 |
37 | aws ec2 run-instances --image-id --instance-type t2.micro --placement AvailabilityZone=us-east-1a --security-group-ids --iam-instance-profile Name="CloudWatch-Instance-Profile"
38 |
39 | # Run the remaining commands from the EC2 instance
40 |
41 | ## Install stress
42 |
43 | sudo dnf install stress-ng -y
44 |
45 | ## Configure a shell script that uses the put-metric-data API
46 |
47 | 1. Create a shell script named mem-usage.sh
48 |
49 | sudo nano mem-usage.sh
50 |
51 | 2. Add the following code and save:
52 |
53 | ```bash
54 | #!/bin/bash
55 |
56 | # Create a token for IMDSv2 that expires after 60 seconds
57 | TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 60" -s`
58 |
59 | # Use the token to fetch the EC2 instance ID
60 | INSTANCE_ID=`curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/instance-id`
61 |
62 | # Get memory usage and put metric data to CloudWatch
63 | MEMORY_USAGE=$(free | awk '/Mem/{printf("%d", ($2-$7)/$2*100)}')
64 | aws cloudwatch put-metric-data --region us-east-1 --namespace "Custom/Memory" --metric-name "MemUsage" --value "$MEMORY_USAGE" --unit "Percent" --dimensions "Name=InstanceId,Value=$INSTANCE_ID"
65 | ```
66 |
67 | 3. Make the script executable
68 |
69 | sudo chmod +x mem-usage.sh
70 |
71 | 4. Run the following commands to install and run crontab
72 |
73 | ```bash
74 | sudo dnf install cronie
75 | sudo systemctl enable crond
76 | sudo systemctl start crond
77 | crontab -e
78 | ```
79 |
80 | 5. Then, add the following line to execute the script every minute
81 |
82 | * * * * * /home/ec2-user/mem-usage.sh
83 |
84 | 6. Save by typing the following and pressing enter
85 |
86 | :wq
87 |
88 | ## Run the stres utility to generate load
89 |
90 | stress-ng --vm 15 --vm-bytes 80% --vm-method all --verify -t 60m -v
91 |
92 | ## Create an alarm in CloudWatch
93 |
94 | 1. Create an alarm that is based on the custom metric
95 |
96 |
97 |
--------------------------------------------------------------------------------
/amazon-dynamodb/DynamoDB CLI Commands.sh:
--------------------------------------------------------------------------------
1 | # Import data
2 | aws dynamodb batch-write-item --request-items file://mystore.json
3 |
4 | #### SCANS ####
5 |
6 | # Perform scan of ProductOrders table:
7 | aws dynamodb scan --table-name mystore
8 |
9 | # Use Page-Size Parameter:
10 | aws dynamodb scan --table-name mystore --page-size 1
11 | aws dynamodb scan --table-name mystore --page-size 2
12 |
13 | # Use Max-Items Parameter:
14 | aws dynamodb scan --table-name mystore --max-items 1
15 |
16 | # Use Projection-Expression Parameter:
17 | aws dynamodb scan --table-name mystore --projection-expression "created"
18 | aws dynamodb scan --table-name mystore --projection-expression "category"
19 | aws dynamodb scan --table-name mystore --projection-expression "colour"
20 |
21 | # Use Filter-Expression Parameter:
22 | aws dynamodb scan --table-name mystore --filter-expression "clientid = :username" --expression-attribute-values '{ ":username": { "S": "chris@example.com" }}'
23 | aws dynamodb scan --table-name mystore --filter-expression "size = :n" --expression-attribute-values '{ ":n": { "N": "12" }}'
24 | aws dynamodb scan --table-name mystore --filter-expression "size > :n" --expression-attribute-values '{ ":n": { "N": "12" }}'
25 |
26 | #### QUERIES ####
27 |
28 | # Use Key-Conditions Parameter:
29 | aws dynamodb query --table-name mystore --key-conditions '{ "clientid":{ "ComparisonOperator":"EQ", "AttributeValueList": [ {"S": "chris@example.com"} ] } }'
30 |
31 | # Use Key-Condition-Expression Parameter:
32 | aws dynamodb query --table-name mystore --key-condition-expression "clientid = :name" --expression-attribute-values '{":name":{"S":"chris@example.com"}}'
--------------------------------------------------------------------------------
/amazon-dynamodb/addupdateorder.json:
--------------------------------------------------------------------------------
1 | {
2 | "mystore": [
3 | {
4 | "PutRequest": {
5 | "Item": {
6 | "clientid": {
7 | "S": "john@example.com"
8 | },
9 | "created": {
10 | "S": "2020-03-9T08:12Z"
11 | },
12 | "sku": {
13 | "S": "SKU-S523"
14 | },
15 | "category": {
16 | "S": "T-Shirt"
17 | },
18 | "size": {
19 | "S": "Small"
20 | },
21 | "colour": {
22 | "S": "Blue"
23 | },
24 | "qty": {
25 | "N": "1"
26 | },
27 | "price": {
28 | "N": "30"
29 | },
30 | "weight": {
31 | "S": "Light"
32 | }
33 |
34 | }
35 | }
36 | },
37 | {
38 | "PutRequest": {
39 | "Item": {
40 | "clientid": {
41 | "S": "joseph@example.com"
42 | },
43 | "created": {
44 | "S": "2020-04-04T10:12Z"
45 | },
46 | "sku": {
47 | "S": "SKU-R203"
48 | },
49 | "category": {
50 | "S": "Socks"
51 | },
52 | "size": {
53 | "S": "Small"
54 | },
55 | "qty": {
56 | "N": "1"
57 | },
58 | "price": {
59 | "N": "20"
60 | },
61 | "weight": {
62 | "S": "Light"
63 | }
64 |
65 | }
66 | }
67 | }
68 | ]
69 |
70 | }
71 |
72 |
--------------------------------------------------------------------------------
/amazon-dynamodb/mystore.json:
--------------------------------------------------------------------------------
1 | {
2 | "mystore": [
3 | {
4 | "PutRequest": {
5 | "Item": {
6 | "clientid": {
7 | "S": "john@example.com"
8 | },
9 | "created": {
10 | "S": "2020-03-9T08:12Z"
11 | },
12 | "sku": {
13 | "S": "SKU-S523"
14 | },
15 | "category": {
16 | "S": "T-Shirt"
17 | },
18 | "size": {
19 | "S": "Small"
20 | },
21 | "colour": {
22 | "S": "Red"
23 | },
24 | "qty": {
25 | "N": "1"
26 | },
27 | "price": {
28 | "N": "30"
29 | },
30 | "weight": {
31 | "S": "Light"
32 | }
33 |
34 | }
35 | }
36 | },
37 | {
38 | "PutRequest": {
39 | "Item": {
40 | "clientid": {
41 | "S": "chris@example.com"
42 | },
43 | "created": {
44 | "S": "2020-03-10T14:30Z"
45 | },
46 | "sku": {
47 | "S": "SKU-J091"
48 | },
49 | "category": {
50 | "S": "Pen"
51 | },
52 | "qty": {
53 | "N": "1"
54 | },
55 | "price": {
56 | "N": "14.99"
57 | },
58 | "colour": {
59 | "S": "Blue"
60 | }
61 |
62 | }
63 | }
64 | },
65 | {
66 | "PutRequest": {
67 | "Item": {
68 | "clientid": {
69 | "S": "chris@example.com"
70 | },
71 | "created": {
72 | "S": "2020-03-10T15:30Z"
73 | },
74 | "sku": {
75 | "S": "SKU-A234"
76 | },
77 | "category": {
78 | "S": "Mug"
79 | },
80 | "qty": {
81 | "N": "2"
82 | },
83 | "price": {
84 | "N": "8.99"
85 | },
86 | "size": {
87 | "N": "12"
88 | }
89 |
90 | }
91 | }
92 | },
93 | {
94 | "PutRequest": {
95 | "Item": {
96 | "clientid": {
97 | "S": "sarah@example.com"
98 | },
99 | "created": {
100 | "S": "2020-03-12T7:42Z"
101 | },
102 | "sku": {
103 | "S": "SKU-R873"
104 | },
105 | "category": {
106 | "S": "Chair"
107 | },
108 | "size": {
109 | "N": "94"
110 | },
111 | "qty": {
112 | "N": "6"
113 | },
114 | "price": {
115 | "N": "82.99"
116 | },
117 | "weight": {
118 | "N": "4011"
119 | }
120 |
121 | }
122 | }
123 | },
124 | {
125 | "PutRequest": {
126 | "Item": {
127 | "clientid": {
128 | "S": "jenny@example.com"
129 | },
130 | "created": {
131 | "S": "2020-03-13T18:29Z"
132 | },
133 | "sku": {
134 | "S": "SKU-I019"
135 | },
136 | "category": {
137 | "S": "Plate"
138 | },
139 | "qty": {
140 | "N": "12"
141 | },
142 | "price": {
143 | "N": "119.99"
144 | },
145 | "size": {
146 | "N": "30"
147 | }
148 |
149 | }
150 | }
151 | },
152 | {
153 | "PutRequest": {
154 | "Item": {
155 | "clientid": {
156 | "S": "jose@example.com"
157 | },
158 | "created": {
159 | "S": "2020-04-01T20:01Z"
160 | },
161 | "sku": {
162 | "S": "SKU-U812"
163 | },
164 | "category": {
165 | "S": "Phone Case"
166 | },
167 | "qty": {
168 | "N": "1"
169 | },
170 | "price": {
171 | "N": "19.99"
172 | },
173 | "size": {
174 | "S": "iPhone 8"
175 | }
176 |
177 | }
178 | }
179 | },
180 | {
181 | "PutRequest": {
182 | "Item": {
183 | "clientid": {
184 | "S": "jess@example.com"
185 | },
186 | "created": {
187 | "S": "2020-04-02T06:04Z"
188 | },
189 | "sku": {
190 | "S": "SKU-P122"
191 | },
192 | "category": {
193 | "S": "book"
194 | },
195 | "qty": {
196 | "N": "1"
197 | },
198 | "price": {
199 | "N": "24.95"
200 | },
201 | "weight": {
202 | "N": "200"
203 | }
204 |
205 | }
206 | }
207 | },
208 | {
209 | "PutRequest": {
210 | "Item": {
211 | "clientid": {
212 | "S": "cindy@example.com"
213 | },
214 | "created": {
215 | "S": "2020-03-28T20:29Z"
216 | },
217 | "sku": {
218 | "S": "SKU-L398"
219 | },
220 | "qty": {
221 | "N": "1"
222 | },
223 | "price": {
224 | "N": "12.99"
225 | },
226 | "category": {
227 | "S": "Charger"
228 | }
229 |
230 | }
231 | }
232 | },{
233 | "PutRequest": {
234 | "Item": {
235 | "clientid": {
236 | "S": "adam@example.com"
237 | },
238 | "created": {
239 | "S": "2020-03-18T04:54Z"
240 | },
241 | "sku": {
242 | "S": "SKU-K101"
243 | },
244 | "category": {
245 | "S": "Bowl"
246 | },
247 | "size": {
248 | "N": "20"
249 | },
250 | "price": {
251 | "N": "32"
252 | },
253 | "qty": {
254 | "N": "4"
255 | }
256 |
257 | }
258 | }
259 | },{
260 | "PutRequest": {
261 | "Item": {
262 | "clientid": {
263 | "S": "safin@example.com"
264 | },
265 | "created": {
266 | "S": "2020-03-21T22:27Z"
267 | },
268 | "sku": {
269 | "S": "SKU-M011"
270 | },
271 | "category": {
272 | "S": "Glasses"
273 | },
274 | "model": {
275 | "S": "Champagne"
276 | },
277 | "qty": {
278 | "N": "10"
279 | },
280 | "price": {
281 | "N": "249.99"
282 | },
283 | "finish": {
284 | "S": "Crystal"
285 | }
286 |
287 | }
288 | }
289 | },{
290 | "PutRequest": {
291 | "Item": {
292 | "clientid": {
293 | "S": "carol@example.com"
294 | },
295 | "created": {
296 | "S": "2020-03-27T19:19Z"
297 | },
298 | "category": {
299 | "S": "Watch"
300 | },
301 | "model": {
302 | "S": "NXC021Z"
303 | },
304 | "qty": {
305 | "N": "2"
306 | },
307 | "price": {
308 | "N": "349.99"
309 | },
310 | "brand": {
311 | "S": "Garmin"
312 | }
313 |
314 | }
315 | }
316 | },
317 | {
318 | "PutRequest": {
319 | "Item": {
320 | "clientid": {
321 | "S": "jake@example.com"
322 | },
323 | "created": {
324 | "S": "2020-03-18T19:29Z"
325 | },
326 | "sku": {
327 | "S": "SKU-Q012"
328 | },
329 | "category": {
330 | "S": "Camera"
331 | },
332 | "brand": {
333 | "S": "Cannon"
334 | },
335 | "qty": {
336 | "N": "1"
337 | },
338 | "price": {
339 | "N": "429.99"
340 | },
341 | "model": {
342 | "S": "EOS 5D MIV"
343 | }
344 |
345 | }
346 | }
347 | },
348 | {
349 | "PutRequest": {
350 | "Item": {
351 | "clientid": {
352 | "S": "chris@example.com"
353 | },
354 | "created": {
355 | "S": "2020-04-01T12:30Z"
356 | },
357 | "sku": {
358 | "S": "SKU-B123"
359 | },
360 | "category": {
361 | "S": "Batteries"
362 | },
363 | "qty": {
364 | "N": "12"
365 | },
366 | "price": {
367 | "N": "22.99"
368 | },
369 | "size": {
370 | "S": "A3"
371 | }
372 |
373 | }
374 | }
375 | },
376 | {
377 | "PutRequest": {
378 | "Item": {
379 | "clientid": {
380 | "S": "chris@example.com"
381 | },
382 | "created": {
383 | "S": "2020-03-28T18:01Z"
384 | },
385 | "sku": {
386 | "S": "SKU-C765"
387 | },
388 | "category": {
389 | "S": "Ear Plugs"
390 | },
391 | "qty": {
392 | "N": "1"
393 | },
394 | "price": {
395 | "N": "6.99"
396 | }
397 |
398 | }
399 | }
400 | },
401 | {
402 | "PutRequest": {
403 | "Item": {
404 | "clientid": {
405 | "S": "pj@example.com"
406 | },
407 | "created": {
408 | "S": "2020-04-03T07:04Z"
409 | },
410 | "sku": {
411 | "S": "SKU-P122"
412 | },
413 | "category": {
414 | "S": "book"
415 | },
416 | "qty": {
417 | "N": "1"
418 | },
419 | "price": {
420 | "N": "24.95"
421 | },
422 | "weight": {
423 | "N": "200"
424 | }
425 |
426 | }
427 | }
428 | },
429 | {
430 | "PutRequest": {
431 | "Item": {
432 | "clientid": {
433 | "S": "werner@example.com"
434 | },
435 | "created": {
436 | "S": "2020-04-02T06:04Z"
437 | },
438 | "sku": {
439 | "S": "SKU-P122"
440 | },
441 | "category": {
442 | "S": "book"
443 | },
444 | "qty": {
445 | "N": "1"
446 | },
447 | "price": {
448 | "N": "24.95"
449 | },
450 | "weight": {
451 | "N": "200"
452 | }
453 |
454 | }
455 | }
456 | },
457 | {
458 | "PutRequest": {
459 | "Item": {
460 | "clientid": {
461 | "S": "charles@example.com"
462 | },
463 | "created": {
464 | "S": "2020-04-02T06:04Z"
465 | },
466 | "sku": {
467 | "S": "SKU-P122"
468 | },
469 | "category": {
470 | "S": "book"
471 | },
472 | "qty": {
473 | "N": "4"
474 | },
475 | "price": {
476 | "N": "24.95"
477 | },
478 | "weight": {
479 | "N": "200"
480 | }
481 |
482 | }
483 | }
484 | },
485 | {
486 | "PutRequest": {
487 | "Item": {
488 | "clientid": {
489 | "S": "kathy@example.com"
490 | },
491 | "created": {
492 | "S": "2020-04-02T06:04Z"
493 | },
494 | "sku": {
495 | "S": "SKU-P122"
496 | },
497 | "category": {
498 | "S": "book"
499 | },
500 | "qty": {
501 | "N": "2"
502 | },
503 | "price": {
504 | "N": "24.95"
505 | },
506 | "weight": {
507 | "N": "200"
508 | }
509 |
510 | }
511 | }
512 | },
513 | {
514 | "PutRequest": {
515 | "Item": {
516 | "clientid": {
517 | "S": "leonard@example.com"
518 | },
519 | "created": {
520 | "S": "2020-04-03T06:04Z"
521 | },
522 | "sku": {
523 | "S": "SKU-T122"
524 | },
525 | "category": {
526 | "S": "Phone Case"
527 | },
528 | "qty": {
529 | "N": "2"
530 | },
531 | "price": {
532 | "N": "19.95"
533 | },
534 | "weight": {
535 | "S": "iPhone 8"
536 | }
537 |
538 | }
539 | }
540 | },
541 | {
542 | "PutRequest": {
543 | "Item": {
544 | "clientid": {
545 | "S": "pat@example.com"
546 | },
547 | "created": {
548 | "S": "2020-04-03T06:04Z"
549 | },
550 | "sku": {
551 | "S": "SKU-T122"
552 | },
553 | "category": {
554 | "S": "Phone Case"
555 | },
556 | "qty": {
557 | "N": "2"
558 | },
559 | "price": {
560 | "N": "19.95"
561 | },
562 | "weight": {
563 | "S": "iPhone 8"
564 | }
565 |
566 | }
567 | }
568 | },
569 | {
570 | "PutRequest": {
571 | "Item": {
572 | "clientid": {
573 | "S": "colin@example.com"
574 | },
575 | "created": {
576 | "S": "2020-04-03T06:04Z"
577 | },
578 | "sku": {
579 | "S": "SKU-T122"
580 | },
581 | "category": {
582 | "S": "Phone Case"
583 | },
584 | "qty": {
585 | "N": "4"
586 | },
587 | "price": {
588 | "N": "19.95"
589 | },
590 | "weight": {
591 | "S": "iPhone 8"
592 | }
593 |
594 | }
595 | }
596 | }
597 |
598 |
599 |
600 | ]
601 | }
--------------------------------------------------------------------------------
/amazon-ebs/amazon-ebs-volumes.md:
--------------------------------------------------------------------------------
1 | # Amazon EBS Volume Lab
2 |
3 | ## Launch Instances in two AZs
4 |
5 | 1. Launch an instance using the Amazon Linux AMI in us-east-1a
6 | 2. Launch another instnace using the Amazon Linux AMI in us-east-1b
7 |
8 | ## Create and Attach an EBS Volume
9 | 1. Create a 10GB gp2 volume in us-east-1a with a name tag of 'data-volume'
10 | 2. List non-loopback block devices on instance
11 | sudo lsblk -e7
12 | 3. Attach the volume to the instance in us-east-1a
13 | 4. Rerun the command to view block devices
14 |
15 | ## Create a filesystem and mount the volume
16 | 1. Create a filesystem on the EBS volume
17 | sudo mkfs -t ext4 /dev/xvdf
18 | 2. Create a mount point for the EBS volume
19 | sudo mkdir /data
20 | 3. Mount the EBS volume to the mount point
21 | sudo mount /dev/xvdf /data
22 | 4. Make the volume mount persistent
23 | Run: 'sudo nano /etc/fstab' then add '/dev/xvdf /data ext4 defaults,nofail 0 2' and save the file
24 |
25 | ## Add some data to the volume
26 |
27 | 1. Change to the /data mount point directory
28 | 2. Create some files and folders
29 |
30 | ## Take a snapshot and move the volume to us-east-1b
31 |
32 | 1. Take a snapshot of the data volume
33 | 2. Create a new EBS volume from the snapshot in us-east-1b
34 | 3. Mount the new EBS volume to the instance in us-east-1b
35 | 4. Change to the /data mount point and view the data
36 |
37 |
--------------------------------------------------------------------------------
/amazon-ec2/create-asg-alb-cli.md:
--------------------------------------------------------------------------------
1 |
2 | ## create auto scaling group
3 |
4 | aws autoscaling create-auto-scaling-group --auto-scaling-group-name ASG2 --launch-template "LaunchTemplateName=MyEC2WebApp" --min-size 1 --max-size 3 --desired-capacity 2 --availability-zones "us-east-1a" "us-east-1b" --vpc-zone-identifier "subnet-02a94e365a7db9848, subnet-00fcec5c9dcd1077d"
5 |
6 | ## create load balancer, create listener, and attach to TG1 to ASG2
7 |
8 | aws elbv2 create-load-balancer --name ALB2 --subnets subnet-02a94e365a7db9848 subnet-00fcec5c9dcd1077d --security-groups sg-018ef94c41893157d
9 |
10 | aws elbv2 create-listener --load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:821711655051:loadbalancer/app/ALB2/c3276fdb62a22113 --protocol HTTP --port 80 --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:821711655051:targetgroup/TG1/e47504d36c5b8a7f
11 |
12 | aws autoscaling attach-load-balancer-target-groups --auto-scaling-group-name ASG2 --target-group-arns arn:aws:elasticloadbalancing:us-east-1:821711655051:targetgroup/TG1/e47504d36c5b8a7f
13 |
14 | ## delete ASG2 and ALB2
15 |
16 | aws elbv2 delete-load-balancer --load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:821711655051:loadbalancer/app/ALB2/c3276fdb62a22113
17 |
18 | aws autoscaling delete-auto-scaling-group --auto-scaling-group-name ASG2 --force-delete
--------------------------------------------------------------------------------
/amazon-ec2/ec2-user-data-web-app.md:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | yum update -y
3 | yum install -y httpd
4 | systemctl start httpd
5 | systemctl enable httpd
6 | EC2AZ=$(TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/placement/availability-zone)
7 | echo 'This Amazon EC2 instance is located in Availability Zone: AZID
' > /var/www/html/index.txt
8 | sed "s/AZID/$EC2AZ/" /var/www/html/index.txt > /var/www/html/index.html
--------------------------------------------------------------------------------
/amazon-ec2/generate-load-on-alb.md:
--------------------------------------------------------------------------------
1 | # Command to generate load on the ALB
2 |
3 | ***replace with your alb dns name***
4 | ```for i in {1..200}; do curl http://your-alb-address.com & done; wait```
5 |
--------------------------------------------------------------------------------
/amazon-ec2/user-data-metadata.md:
--------------------------------------------------------------------------------
1 | # IMDS v1
2 |
3 | ## Example commmands to run:
4 |
5 | 1. Get the instance ID:
6 | curl http://169.254.169.254/latest/meta-data/instance-id
7 |
8 | 2. Get the AMI ID:
9 | curl http://169.254.169.254/latest/meta-data/ami-id
10 |
11 | 3. Get the instance type:
12 | curl http://169.254.169.254/latest/meta-data/instance-type
13 |
14 | 4. Get the local IPv4 address:
15 | curl http://169.254.169.254/latest/meta-data/local-ipv4
16 |
17 | 5. Get the public IPv4 address:
18 | curl http://169.254.169.254/latest/meta-data/public-ipv4
19 |
20 |
21 | # IMDS v2
22 |
23 | ## Step 1 - Create a session and get a token
24 |
25 | TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
26 |
27 | ## Step 2 - Use the token to request metadata
28 |
29 | 1. Get the instance ID:
30 | curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id
31 |
32 | 2. Get the AMI ID:
33 | curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/ami-id
34 |
35 | # Use metadata with user data to configure the instance
36 |
37 | This script installs a web server and uses instance metadata to retrieve information about the instance and then output the information on a webpage.
38 |
39 | ```bash
40 | #!/bin/bash
41 |
42 | # Update system and install httpd (Apache)
43 | yum update -y
44 | yum install -y httpd
45 |
46 | # Start httpd service and enable it to start on boot
47 | systemctl start httpd
48 | systemctl enable httpd
49 |
50 | # Fetch metadata using IMDSv2
51 | TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
52 | INSTANCE_ID=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id)
53 | AMI_ID=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/ami-id)
54 | INSTANCE_TYPE=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-type)
55 |
56 | # Create a web page to display the metadata
57 | cat < /var/www/html/index.html
58 |
59 |
60 | EC2 Instance Metadata
61 |
62 |
63 | EC2 Instance Metadata
64 | Instance ID: $INSTANCE_ID
65 | AMI ID: $AMI_ID
66 | Instance Type: $INSTANCE_TYPE
67 |
68 |
69 | EOF
70 | ```
--------------------------------------------------------------------------------
/amazon-ec2/user-data-web-server.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Update the system and install necessary packages
4 | yum update -y
5 | yum install -y httpd
6 |
7 | # Start the Apache server
8 | systemctl start httpd
9 | systemctl enable httpd
10 |
11 | # Fetch the Availability Zone information using IMDSv2
12 | TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
13 | AZ=`curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone`
14 |
15 | # Create the index.html file
16 | cat > /var/www/html/index.html <
18 |
19 | Instance Availability Zone
20 |
33 |
34 |
35 | This instance is located in Availability Zone: $AZ
36 |
37 |