├── amazon-cloudfront └── Static-Website-ACM │ ├── images │ └── cloud.png │ ├── index.html │ └── style.css ├── aws-organizations ├── Switch Roles.txt ├── Amazon VPC │ ├── aws-cli-run-instances.md │ ├── vpc-flow-logs.json │ ├── user-data-subnet-id.txt │ ├── Bucket-Policy-VPCE.json │ ├── custom-vpc.md │ └── custom-vpc-prod.md └── DenyAccessToASpecificRole.json ├── aws-cloudtrail └── LogEC2StopInstance.js ├── amazon-eventbridge └── log-ec2-stop-instance.py ├── amazon-s3 ├── error.html └── index.html ├── amazon-vpc ├── aws-cli-run-instances.md ├── vpc-flow-logs.json ├── Bucket-Policy-VPCE.json ├── custom-vpc.md ├── custom-vpc-prod.md └── user-data-subnet-id.md ├── aws-kms ├── enforce-s3-encryption.json └── kms-key-ebs-rds.md ├── ec2-instance-profile ├── jack-ec2.json └── commands.sh ├── amazon-cloudwatch ├── ec2-custom-metrics.md └── custom-cloudwatch-metrics.md ├── iam-access-control ├── abac-policy.json └── PermissionsBoundary.json ├── operating-system-commands ├── basic-windows-commands.md └── basic-linux-mac-commands.md ├── README.md ├── cross-account-access └── cross-account-access-s3.md ├── aws-iam └── access-keys-and-iam-roles.md └── aws-cloudformation ├── create-vpc-cf-1-NGW.yaml └── create-vpc-cf.yaml /amazon-cloudfront/Static-Website-ACM/images/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nealdct/aws-scs-code/HEAD/amazon-cloudfront/Static-Website-ACM/images/cloud.png -------------------------------------------------------------------------------- /aws-organizations/Switch Roles.txt: -------------------------------------------------------------------------------- 1 | 2 | Account number: 3 | 4 | Role: OrganizationAccountAccessRole 5 | 6 | Display name: DCT-PRODUCTION -------------------------------------------------------------------------------- /aws-cloudtrail/LogEC2StopInstance.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.handler = (event, context, callback) => { 4 | console.log('LogEC2StopInstance'); 5 | console.log('Received event:', JSON.stringify(event, null, 2)); 6 | callback(null, 'Finished'); 7 | }; -------------------------------------------------------------------------------- /amazon-eventbridge/log-ec2-stop-instance.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def lambda_handler(event, context): 4 | print('LogEC2StopInstance') 5 | print('Received event:', json.dumps(event, indent=2)) 6 | return { 7 | 'statusCode': 200, 8 | 'body': 'Finished' 9 | } 10 | -------------------------------------------------------------------------------- /amazon-s3/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 |

Error: this is an error page generated on Amazon S3

16 | 17 | -------------------------------------------------------------------------------- /amazon-s3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 |

Congratulations, you've launched a static website on Amazon S3

16 | 17 | 18 | -------------------------------------------------------------------------------- /amazon-vpc/aws-cli-run-instances.md: -------------------------------------------------------------------------------- 1 | # Launch instance in Public 1A 2 | aws ec2 run-instances --image-id --instance-type --security-group-ids --subnet-id --key-name --user-data 3 | 4 | 5 | # Launch instance in Public 1B 6 | 7 | 8 | # Launch instance in Private 1B 9 | 10 | 11 | # Terminate instances 12 | 13 | aws ec2 terminate-instances --instance-ids -------------------------------------------------------------------------------- /aws-organizations/Amazon VPC/aws-cli-run-instances.md: -------------------------------------------------------------------------------- 1 | # Launch instance in Public 1A 2 | aws ec2 run-instances --image-id --instance-type --security-group-ids --subnet-id --key-name --user-data 3 | 4 | 5 | # Launch instance in Public 1B 6 | 7 | 8 | # Launch instance in Private 1B 9 | 10 | 11 | # Terminate instances 12 | 13 | aws ec2 terminate-instances --instance-ids -------------------------------------------------------------------------------- /amazon-vpc/vpc-flow-logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Action": [ 6 | "logs:CreateLogGroup", 7 | "logs:CreateLogStream", 8 | "logs:PutLogEvents", 9 | "logs:DescribeLogGroups", 10 | "logs:DescribeLogStreams" 11 | ], 12 | "Effect": "Allow", 13 | "Resource": "*" 14 | } 15 | ] 16 | } 17 | 18 | 19 | # Trust policy 20 | 21 | vpc-flow-logs.amazonaws.com -------------------------------------------------------------------------------- /aws-organizations/Amazon VPC/vpc-flow-logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Action": [ 6 | "logs:CreateLogGroup", 7 | "logs:CreateLogStream", 8 | "logs:PutLogEvents", 9 | "logs:DescribeLogGroups", 10 | "logs:DescribeLogStreams" 11 | ], 12 | "Effect": "Allow", 13 | "Resource": "*" 14 | } 15 | ] 16 | } 17 | 18 | 19 | # Trust policy 20 | 21 | vpc-flow-logs.amazonaws.com -------------------------------------------------------------------------------- /aws-organizations/Amazon VPC/user-data-subnet-id.txt: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | yum update -y 3 | yum install -y httpd 4 | systemctl start httpd 5 | systemctl enable httpd 6 | INTERFACE=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/) 7 | SUBNETID=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${INTERFACE}/subnet-id) 8 | echo '

This instance is in the subnet wih ID: SUBNETID

' > /var/www/html/index.txt 9 | sed "s/SUBNETID/$SUBNETID/" /var/www/html/index.txt > /var/www/html/index.html -------------------------------------------------------------------------------- /amazon-vpc/Bucket-Policy-VPCE.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Id": "Policy1415115909152", 4 | "Statement": [ 5 | { 6 | "Sid": "Access-to-specific-VPCE-only", 7 | "Principal": "*", 8 | "Action": "s3:*", 9 | "Effect": "Deny", 10 | "Resource": ["arn:aws:s3:::YOUR-BUCKET-NAME", 11 | "arn:aws:s3:::YOUR-BUCKET-NAME/*"], 12 | "Condition": { 13 | "StringNotEquals": { 14 | "aws:sourceVpce": "YOUR-VPCE-ID" 15 | } 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /aws-organizations/Amazon VPC/Bucket-Policy-VPCE.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Id": "Policy1415115909152", 4 | "Statement": [ 5 | { 6 | "Sid": "Access-to-specific-VPCE-only", 7 | "Principal": "*", 8 | "Action": "s3:*", 9 | "Effect": "Deny", 10 | "Resource": ["arn:aws:s3:::YOUR-BUCKET-NAME", 11 | "arn:aws:s3:::YOUR-BUCKET-NAME/*"], 12 | "Condition": { 13 | "StringNotEquals": { 14 | "aws:sourceVpce": "YOUR-VPCE-ID" 15 | } 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /aws-kms/enforce-s3-encryption.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Id": "PutObjectPolicy", 4 | "Statement": [ 5 | { 6 | "Sid": "DenyUnEncryptedObjectUploads", 7 | "Effect": "Deny", 8 | "Principal": "*", 9 | "Action": "s3:PutObject", 10 | "Resource": "arn:aws:s3:::/*", 11 | "Condition": { 12 | "StringNotEquals": { 13 | "s3:x-amz-server-side-encryption": "AES256" 14 | } 15 | } 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /ec2-instance-profile/jack-ec2.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": [ 7 | "iam:CreateInstanceProfile", 8 | "iam:AddRoleToInstanceProfile", 9 | "ec2:AssociateIamInstanceProfile", 10 | "iam:RemoveRoleFromInstanceProfile", 11 | "iam:DeleteInstanceProfile", 12 | "iam:GetRole", 13 | "iam:PassRole" 14 | ], 15 | "Resource": "*" 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /amazon-vpc/custom-vpc.md: -------------------------------------------------------------------------------- 1 | # Create VPC 2 | Name: MyVPC 3 | IPv4 CIDR Block: 10.0.0.0/16 4 | 5 | # Create Subnets 6 | 7 | Name: Public-1A 8 | Availability Zone: us-east-1a 9 | IPv4 CIDR Block: 10.0.1.0/24 10 | 11 | Name: Public-1B 12 | Availability Zone: us-east-1b 13 | IPv4 CIDR Block: 10.0.2.0/24 14 | 15 | Name: Private-1A 16 | Availability Zone: us-east-1a 17 | IPv4 CIDR Block: 10.0.3.0/24 18 | 19 | Name: Private-1B 20 | Availability Zone: us-east-1b 21 | IPv4 CIDR Block: 10.0.4.0/24 22 | 23 | # Create private route table 24 | 25 | Name: Private-RT 26 | VPC: MyVPC 27 | Subnet associations: Private-1A, Private-1B 28 | 29 | # Create Internet Gateway 30 | 31 | Name: MyIGW 32 | VPC: MyVPC -------------------------------------------------------------------------------- /amazon-cloudfront/Static-Website-ACM/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Welcome to my S3 and CloudFront Static Website 6 | 7 | 8 | 9 |
10 |

Congratulations, you enabled secure access to this site!

11 |
12 |
13 | cloud 14 |

Thanks for visiting my mock website. I hope you enjoy your stay.

15 |
16 |
17 |

© 2023 My Mock Website

18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /amazon-cloudwatch/ec2-custom-metrics.md: -------------------------------------------------------------------------------- 1 | ## PutMetricData CLI Command 2 | 3 | aws cloudwatch put-metric-data --metric-name bytes --namespace MyCustomNameSpace --unit Bytes --value 242678092 --dimensions InstanceId=INSTANCE-ID,InstanceType=t2.micro --region us-east-1 4 | 5 | aws cloudwatch put-metric-data --metric-name latency --namespace MyCustomNameSpace --unit Milliseconds --value 24 --dimensions InstanceId=INSTANCE-ID,InstanceType=t2.micro --region us-east-1 6 | 7 | 8 | ## Trigger CloudWatch Alarm 9 | 10 | aws cloudwatch put-metric-data --metric-name latency --namespace MyCustomNameSpace --unit Milliseconds --value 35 --dimensions InstanceId=INSTANCE-ID,InstanceType=t2.micro --region us-east-1 11 | 12 | -------------------------------------------------------------------------------- /aws-organizations/Amazon VPC/custom-vpc.md: -------------------------------------------------------------------------------- 1 | # Create VPC 2 | Name: MyVPC 3 | IPv4 CIDR Block: 10.0.0.0/16 4 | 5 | # Create Subnets 6 | 7 | Name: Public-1A 8 | Availability Zone: us-east-1a 9 | IPv4 CIDR Block: 10.0.1.0/24 10 | 11 | Name: Public-1B 12 | Availability Zone: us-east-1b 13 | IPv4 CIDR Block: 10.0.2.0/24 14 | 15 | Name: Private-1A 16 | Availability Zone: us-east-1a 17 | IPv4 CIDR Block: 10.0.3.0/24 18 | 19 | Name: Private-1B 20 | Availability Zone: us-east-1b 21 | IPv4 CIDR Block: 10.0.4.0/24 22 | 23 | # Create private route table 24 | 25 | Name: Private-RT 26 | VPC: MyVPC 27 | Subnet associations: Private-1A, Private-1B 28 | 29 | # Create Internet Gateway 30 | 31 | Name: MyIGW 32 | VPC: MyVPC -------------------------------------------------------------------------------- /aws-organizations/DenyAccessToASpecificRole.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "DenyAccessToASpecificRole", 6 | "Effect": "Deny", 7 | "Action": [ 8 | "iam:AttachRolePolicy", 9 | "iam:DeleteRole", 10 | "iam:DeleteRolePermissionsBoundary", 11 | "iam:DeleteRolePolicy", 12 | "iam:DetachRolePolicy", 13 | "iam:PutRolePermissionsBoundary", 14 | "iam:PutRolePolicy", 15 | "iam:UpdateAssumeRolePolicy", 16 | "iam:UpdateRole", 17 | "iam:UpdateRoleDescription" 18 | ], 19 | "Resource": [ 20 | "arn:aws:iam::*:role/name-of-role-to-deny" 21 | ] 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /amazon-vpc/custom-vpc-prod.md: -------------------------------------------------------------------------------- 1 | # Create VPC 2 | Name: MyVPC-PROD 3 | IPv4 CIDR Block: 10.1.0.0/16 4 | 5 | # Create Subnets 6 | 7 | Name: Public-1A 8 | Availability Zone: us-east-1a 9 | IPv4 CIDR Block: 10.1.1.0/24 10 | 11 | Name: Public-1B 12 | Availability Zone: us-east-1b 13 | IPv4 CIDR Block: 10.1.2.0/24 14 | 15 | Name: Private-1A 16 | Availability Zone: us-east-1a 17 | IPv4 CIDR Block: 10.1.3.0/24 18 | 19 | Name: Private-1B 20 | Availability Zone: us-east-1b 21 | IPv4 CIDR Block: 10.1.4.0/24 22 | 23 | # Create private route table 24 | 25 | Name: Private-RT 26 | VPC: MyVPC-PROD 27 | Subnet associations: Private-1A, Private-1B 28 | 29 | # Create Internet Gateway 30 | 31 | Name: MyIGW-PROD 32 | VPC: MyVPC-PROD 33 | 34 | # Account ID 35 | 36 | 37 | # VPC ID (Prod) 38 | 39 | 40 | # Instance IP (Prod) 41 | 42 | -------------------------------------------------------------------------------- /aws-organizations/Amazon VPC/custom-vpc-prod.md: -------------------------------------------------------------------------------- 1 | # Create VPC 2 | Name: MyVPC-PROD 3 | IPv4 CIDR Block: 10.1.0.0/16 4 | 5 | # Create Subnets 6 | 7 | Name: Public-1A 8 | Availability Zone: us-east-1a 9 | IPv4 CIDR Block: 10.1.1.0/24 10 | 11 | Name: Public-1B 12 | Availability Zone: us-east-1b 13 | IPv4 CIDR Block: 10.1.2.0/24 14 | 15 | Name: Private-1A 16 | Availability Zone: us-east-1a 17 | IPv4 CIDR Block: 10.1.3.0/24 18 | 19 | Name: Private-1B 20 | Availability Zone: us-east-1b 21 | IPv4 CIDR Block: 10.1.4.0/24 22 | 23 | # Create private route table 24 | 25 | Name: Private-RT 26 | VPC: MyVPC-PROD 27 | Subnet associations: Private-1A, Private-1B 28 | 29 | # Create Internet Gateway 30 | 31 | Name: MyIGW-PROD 32 | VPC: MyVPC-PROD 33 | 34 | # Account ID 35 | 36 | 37 | # VPC ID (Prod) 38 | 39 | 40 | # Instance IP (Prod) 41 | 42 | -------------------------------------------------------------------------------- /amazon-vpc/user-data-subnet-id.md: -------------------------------------------------------------------------------- 1 | # CODE UPDATED SO IT WORKS WITH AMAZON LINUX 2 AMI AND AMAZON LINUX 2023 2 | *** COPY CODE FROM LINES 4-12 *** 3 | 4 | #!/bin/bash 5 | yum update -y 6 | yum install -y httpd 7 | systemctl start httpd 8 | systemctl enable httpd 9 | INTERFACE=$(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/network/interfaces/macs/) 10 | SUBNETID=$(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/network/interfaces/macs/${INTERFACE}/subnet-id) 11 | echo '

This instance is in the subnet wih ID: SUBNETID

' > /var/www/html/index.txt 12 | sed "s/SUBNETID/$SUBNETID/" /var/www/html/index.txt > /var/www/html/index.html -------------------------------------------------------------------------------- /iam-access-control/abac-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": [ 7 | "rds:DescribeDBInstances", 8 | "rds:DescribeDBClusters", 9 | "rds:DescribeGlobalClusters" 10 | ], 11 | "Resource": "*" 12 | }, 13 | 14 | { 15 | "Effect": "Allow", 16 | "Action": [ 17 | "rds:RebootDBInstance", 18 | "rds:StartDBInstance", 19 | "rds:StopDBInstance" 20 | ], 21 | "Resource": "*", 22 | "Condition": { 23 | "StringEquals": { 24 | "aws:PrincipalTag/Department": "DBAdmins", 25 | "rds:db-tag/Environment": "Production" 26 | } 27 | } 28 | } 29 | ] 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /operating-system-commands/basic-windows-commands.md: -------------------------------------------------------------------------------- 1 | # print working directory 2 | 3 | cd 4 | 5 | echo %cd% 6 | 7 | # view the files in a directory 8 | 9 | dir 10 | 11 | # change directory 12 | 13 | cd 14 | 15 | Example: "cd Documents\mydata" 16 | 17 | # move back to home directory 18 | 19 | cd %homepath% 20 | 21 | # create a directory 22 | 23 | mkdir 24 | 25 | Example: "mkdir mydata" 26 | 27 | # delete directory 28 | 29 | rmdir (if empty) 30 | 31 | rm /s (if not empty) 32 | 33 | Example: "rmdir mydata" 34 | 35 | # create an empty file 36 | 37 | type nul > testfile.txt 38 | 39 | # create file with text 40 | 41 | echo "hello world" > mytestfile.txt 42 | 43 | # delete a file 44 | 45 | del 46 | 47 | Example: "del mytestfile.txt" 48 | 49 | # copy a file 50 | 51 | copy 52 | 53 | Example: "copy mytestfile.txt Desktop" 54 | 55 | # get help for a command 56 | 57 | help 58 | 59 | Example: "help copy" 60 | 61 | # display contents of file on screen 62 | 63 | type 64 | 65 | Example: "type mytestfile.txt" 66 | 67 | # clear screen 68 | 69 | cls 70 | 71 | -------------------------------------------------------------------------------- /operating-system-commands/basic-linux-mac-commands.md: -------------------------------------------------------------------------------- 1 | # print working directory 2 | 3 | pwd 4 | 5 | # view the files in a directory 6 | 7 | ls 8 | 9 | # change directory 10 | 11 | cd 12 | 13 | Example: "cd Documents/mydata" 14 | 15 | # move back to home directory 16 | 17 | cd ~ 18 | 19 | # create a directory 20 | 21 | mkdir 22 | 23 | Example: "mkdir mydata" 24 | 25 | # delete directory 26 | 27 | rmdir (if empty) 28 | 29 | rm -rf (if not empty) 30 | 31 | Example: "rmdir mydata" 32 | 33 | # create an empty file 34 | 35 | touch 36 | 37 | Example: "touch mytestfile" 38 | 39 | # create file with text 40 | 41 | echo "text" > 42 | 43 | Example: echo "hello world" > mytestfile 44 | 45 | # delete a file 46 | 47 | rm 48 | 49 | Example: "rm mytestfile" 50 | 51 | # copy a file 52 | 53 | cp 54 | 55 | Example: "cp mytestfile mydata" 56 | 57 | # get help for a command 58 | 59 | man 60 | 61 | Example: "man cp" 62 | 63 | # display contents of file on screen 64 | 65 | cat 66 | 67 | Example: "cat mytestfile" 68 | 69 | # clear screen 70 | 71 | cls 72 | 73 | 74 | -------------------------------------------------------------------------------- /amazon-cloudfront/Static-Website-ACM/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #232f3e; 3 | font-family: Arial, sans-serif; 4 | font-size: 16px; 5 | color: #F2F2F2; 6 | margin: 0; 7 | } 8 | 9 | header { 10 | background-color: #FF9900; 11 | padding: 20px; 12 | } 13 | 14 | img { 15 | border-radius: 50%; 16 | } 17 | 18 | h1 { 19 | font-size: 36px; 20 | color: #232f3e; 21 | margin: 0; 22 | } 23 | 24 | main { 25 | padding: 20px; 26 | } 27 | 28 | p { 29 | line-height: 1.5; 30 | margin-bottom: 20px; 31 | text-align: justify; 32 | } 33 | 34 | p:last-child { 35 | margin-bottom: 0; 36 | } 37 | 38 | button { 39 | background-color: #FF9900; 40 | border: 1px solid #FF9900; 41 | color: #232f3e; 42 | font-size: 18px; 43 | padding: 12px 24px; 44 | margin: 10px 0; 45 | border: none; 46 | cursor: pointer; 47 | border-radius: 4px; 48 | text-align: center; 49 | text-decoration: none; 50 | display: inline-block; 51 | } 52 | 53 | button:hover { 54 | background-color: #232f3e; 55 | color: #F2F2F2; 56 | border: 1px solid #FF9900; 57 | } 58 | 59 | 60 | footer { 61 | background-color: #232f3e; 62 | padding: 20px; 63 | text-align: center; 64 | font-size: 14px; 65 | } 66 | 67 | footer p { 68 | margin: 0; 69 | color: #F2F2F2; 70 | } 71 | -------------------------------------------------------------------------------- /ec2-instance-profile/commands.sh: -------------------------------------------------------------------------------- 1 | # Step 1 - if you didn't do the previous lab, run these commands, otherwise go to step 2 2 | # Create user 3 | aws iam create-user --user-name jack 4 | # Create access keys and record access keys for later use 5 | aws iam create-access-key --user-name jack 6 | # Configure CLI with profile for Jack 7 | aws configure --profile jack 8 | 9 | # Step 2 - Execute commands using your own Admin account 10 | # Create policy 11 | aws iam create-policy --policy-name jack-ec2 --policy-document file://jack-ec2.json 12 | # Attach policy 13 | aws iam attach-user-policy --user-name jack --policy-arn "arn:aws:iam::ACCOUNT_A_ID:policy/jack-ec2" 14 | # List policies attached to Jack 15 | aws iam list-attached-user-policies --user-name jack 16 | 17 | # Step 3 - Now we start using Jack's profile to execute commands 18 | # Create instance profile 19 | aws iam create-instance-profile --instance-profile-name mytestinstanceprofile --profile jack 20 | # Add role to instance profile 21 | aws iam add-role-to-instance-profile --role-name S3ReadOnly --instance-profile-name mytestinstanceprofile --profile jack 22 | # Associate instance profile with EC2 instance 23 | aws ec2 associate-iam-instance-profile --instance-id YOUR_EC2_INSTANCE_ID --iam-instance-profile Name=mytestinstanceprofile --profile jack 24 | 25 | # Step 4 Cleanup (optional) 26 | # Remove role from instance profile 27 | aws iam remove-role-from-instance-profile --role-name S3ReadOnly --instance-profile-name mytestinstanceprofile --profile jack 28 | # Delete instance profile 29 | aws iam delete-instance-profile --instance-profile-name mytestinstanceprofile --profile jack -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS Certified Security Specialty 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 | The AWS Certified Security Specialty certification a highly popular AWS certification with many employers requiring those working with AWS to get this certification. Your chances of getting a job in cloud will increase dramatically by getting AWS certified. 11 | 12 | In this course, you’ll learn everything you need to know to pass your AWS Certified Security Specialty exam. The course is taught in a style that includes theory lessons with lots of visualization such as architectural diagrams and animated graphics (this is not death by bullet point). 13 | 14 | After the theory lessons you’ll get to put your knowledge into practical use with hands-on lessons that teach you how to use AWS and complete exercises that reflect real-world situations. Learning by doing is the best way to ensure you build practical skills and increases knowledge retention. 15 | 16 | The course includes the following features to ensure you are well prepared for the exam: 17 | - Coverage of the latest exam topics for the SCS-C02 18 | - Hands-on lessons using the AWS Management Console 19 | - Separate theory lessons with amazing architectural diagrams 20 | 21 | The course overs the following topics in-depth: 22 | 23 | - AWS IAM User, Groups, Roles and Policies 24 | - AWS Security Token Service (STS) 25 | - Multi-Factor Authentication (MFA) 26 | - Identity-Based Policies and Resource-Based Policies 27 | - AWS Organizations and Service Control Policies (SCPs) 28 | - Use Cases for IAM Roles 29 | - AWS Directory Services, Identity Federation, AWS Single Sign-On, Amazon Cognito 30 | - Amazon VPC Security 31 | - Data Protection 32 | - Logging, Monitoring, and Compliance 33 | - Security Management and Automation 34 | - Infrastructure and Edge Security 35 | - Incident Response 36 | 37 | Learn more and [enroll in this course](https://digitalcloud.training/aws-certified-security-specialty/) now to get your AWS Certified Security Specialty certification 38 | -------------------------------------------------------------------------------- /aws-kms/kms-key-ebs-rds.md: -------------------------------------------------------------------------------- 1 | # Policy Statement for KMS key "kms-key-ebs-rds" 2 | 3 | ```json 4 | { 5 | "Version": "2012-10-17", 6 | "Id": "KMSKeyPolicy", 7 | "Statement": [ 8 | { 9 | "Sid": "Allow access for Key Administrators", 10 | "Effect": "Allow", 11 | "Principal": { 12 | "AWS": "arn:aws:iam::111122223333:user/User" 13 | }, 14 | "Action": [ 15 | "kms:Create*", 16 | "kms:Describe*", 17 | "kms:Enable*", 18 | "kms:List*", 19 | "kms:Put*", 20 | "kms:Update*", 21 | "kms:Revoke*", 22 | "kms:Disable*", 23 | "kms:Get*", 24 | "kms:Delete*", 25 | "kms:TagResource", 26 | "kms:UntagResource", 27 | "kms:ScheduleKeyDeletion", 28 | "kms:CancelKeyDeletion" 29 | ], 30 | "Resource": "*" 31 | }, 32 | { 33 | "Sid": "RestrictKeyUsageToEC2andRDS", 34 | "Effect": "Allow", 35 | "Principal": { 36 | "AWS": "arn:aws:iam::111122223333:user/User" 37 | }, 38 | "Action": [ 39 | "kms:Encrypt", 40 | "kms:Decrypt", 41 | "kms:ReEncrypt*", 42 | "kms:GenerateDataKey*", 43 | "kms:CreateGrant", 44 | "kms:ListGrants", 45 | "kms:DescribeKey" 46 | ], 47 | "Resource": "*", 48 | "Condition": { 49 | "StringEquals": { 50 | "kms:ViaService": [ 51 | "ec2.us-east-1.amazonaws.com", 52 | "rds.us-east-1.amazonaws.com" 53 | ] 54 | } 55 | } 56 | } 57 | ] 58 | } 59 | ``` 60 | # Policy Statement for Cross Account copy 61 | 62 | ```json 63 | { 64 | "Sid": "Allow use of the key with destination account", 65 | "Effect": "Allow", 66 | "Principal": { 67 | "AWS": "arn:aws:iam::TARGET-ACCOUNT-ID:role/ROLENAME" 68 | }, 69 | "Action": [ 70 | "kms:Decrypt", 71 | "kms:CreateGrant" 72 | ], 73 | "Resource": "*", 74 | "Condition": { 75 | "StringEquals": { 76 | "kms:ViaService": "ec2.REGION.amazonaws.com", 77 | "kms:CallerAccount": "TARGET-ACCOUNT-ID" 78 | } 79 | } 80 | } 81 | ``` 82 | 83 | -------------------------------------------------------------------------------- /iam-access-control/PermissionsBoundary.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "IAMAccess", 6 | "Effect": "Allow", 7 | "Action": "iam:*", 8 | "Resource": "*" 9 | }, 10 | { 11 | "Sid": "DenyPermBoundaryIAMPolicyAlteration", 12 | "Effect": "Deny", 13 | "Action": [ 14 | "iam:DeletePolicy", 15 | "iam:DeletePolicyVersion", 16 | "iam:CreatePolicyVersion", 17 | "iam:SetDefaultPolicyVersion" 18 | ], 19 | "Resource": [ 20 | "arn:aws:iam::YourAccount_ID:policy/PermissionsBoundary" 21 | ] 22 | }, 23 | { 24 | "Sid": "DenyRemovalOfPermBoundaryFromAnyUserOrRole", 25 | "Effect": "Deny", 26 | "Action": [ 27 | "iam:DeleteUserPermissionsBoundary", 28 | "iam:DeleteRolePermissionsBoundary" 29 | ], 30 | "Resource": [ 31 | "arn:aws:iam::YourAccount_ID:user/*", 32 | "arn:aws:iam::YourAccount_ID:role/*" 33 | ], 34 | "Condition": { 35 | "StringEquals": { 36 | "iam:PermissionsBoundary": "arn:aws:iam::YourAccount_ID:policy/PermissionsBoundary" 37 | } 38 | } 39 | }, 40 | { 41 | "Sid": "DenyAccessIfRequiredPermBoundaryIsNotBeingApplied", 42 | "Effect": "Deny", 43 | "Action": [ 44 | "iam:PutUserPermissionsBoundary", 45 | "iam:PutRolePermissionsBoundary" 46 | ], 47 | "Resource": [ 48 | "arn:aws:iam::YourAccount_ID:user/*", 49 | "arn:aws:iam::YourAccount_ID:role/*" 50 | ], 51 | "Condition": { 52 | "StringNotEquals": { 53 | "iam:PermissionsBoundary": "arn:aws:iam::YourAccount_ID:policy/PermissionsBoundary" 54 | } 55 | } 56 | }, 57 | { 58 | "Sid": "DenyUserAndRoleCreationWithOutPermBoundary", 59 | "Effect": "Deny", 60 | "Action": [ 61 | "iam:CreateUser", 62 | "iam:CreateRole" 63 | ], 64 | "Resource": [ 65 | "arn:aws:iam::YourAccount_ID:user/*", 66 | "arn:aws:iam::YourAccount_ID:role/*" 67 | ], 68 | "Condition": { 69 | "StringNotEquals": { 70 | "iam:PermissionsBoundary": "arn:aws:iam::YourAccount_ID:policy/PermissionsBoundary" 71 | } 72 | } 73 | } 74 | ] 75 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /cross-account-access/cross-account-access-s3.md: -------------------------------------------------------------------------------- 1 | # Create a role in Account B with an external ID in the trust policy 2 | 3 | ***The following tasks should be executed in ACCOUNT B (DCT-PRODUCTION in the video)*** 4 | 5 | Before starting make sure you have a bucket in Account B with some objects in it. 6 | 7 | 1. In AWS CloudShell create a file named 'trust-policy.json' with the following JSON (update the account ID): 8 | ```json 9 | { 10 | "Version": "2012-10-17", 11 | "Statement": [ 12 | { 13 | "Effect": "Allow", 14 | "Principal": { 15 | "AWS": "arn:aws:iam::ACCOUNT_A_ID:root" 16 | }, 17 | "Action": "sts:AssumeRole", 18 | "Condition": { 19 | "StringEquals": { 20 | "sts:ExternalId": "XX9812DDF2V" 21 | } 22 | } 23 | } 24 | ] 25 | } 26 | ``` 27 | 2. Create the role 28 | ```bash 29 | aws iam create-role \ 30 | --role-name S3AccessRoleForExternalAccount \ 31 | --assume-role-policy-document file://trust-policy.json 32 | ``` 33 | 3. Attach the S3 full access policy 34 | ```bash 35 | aws iam attach-role-policy \ 36 | --role-name S3AccessRoleForExternalAccount \ 37 | --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess 38 | ``` 39 | 40 | # Create a test user and assume the role in Account B 41 | 42 | ***The following tasks should be executed in ACCOUNT A (DCT-MANAGEMENT in the video)*** 43 | 44 | 1. In AWS CloudShell create a file named 'jack-s3.json' with the following JSON: 45 | ```json 46 | { 47 | "Version": "2012-10-17", 48 | "Statement": [ 49 | { 50 | "Effect": "Allow", 51 | "Action": [ 52 | "iam:ListRoles", 53 | "sts:AssumeRole" 54 | ], 55 | "Resource": "*" 56 | } 57 | ] 58 | } 59 | ``` 60 | 2. Create user 61 | ```bash 62 | aws iam create-user --user-name jack 63 | ``` 64 | 3. Create policy 65 | ```bash 66 | aws iam create-policy --policy-name jack-s3 --policy-document file://jack-s3.json 67 | ``` 68 | 4. Attach policy (update the account ID) 69 | ```bash 70 | aws iam attach-user-policy --user-name jack --policy-arn "arn:aws:iam::ACCOUNT_A_ID:policy/jack-s3" 71 | ``` 72 | 5. List policies attached to Jack 73 | ```bash 74 | aws iam list-attached-user-policies --user-name jack 75 | ``` 76 | 6. Create access keys and record access keys for later use 77 | ```bash 78 | aws iam create-access-key --user-name jack 79 | ``` 80 | 7. Configure CLI with profile for Jack 81 | ```bash 82 | aws configure --profile jack 83 | ``` 84 | 8. Shows the identity being used to execute commands (without any profile) 85 | ```bash 86 | aws sts get-caller-identity 87 | ``` 88 | 9. Assume the role in Account B with external ID (update the account ID) 89 | ```bash 90 | aws sts assume-role --profile jack --role-arn "arn:aws:iam::ACCOUNT_B_ID:role/S3AccessRoleForExternalAccount" --role-session-name AWSCLI-Session --external-id XX9812DDF2V 91 | ``` 92 | 10. Configure access key ID, secret access key and session token as environment variables 93 | ```bash 94 | export AWS_ACCESS_KEY_ID=RoleAccessKeyID 95 | export AWS_SECRET_ACCESS_KEY=RoleSecretKey 96 | export AWS_SESSION_TOKEN=RoleSessionToken 97 | ``` 98 | 11. The following command shows that we're now executing commands as the assumed role 99 | ```bash 100 | aws sts get-caller-identity 101 | ``` 102 | 12. Run S3 commands to list bucket, make bucket, and delete bucket 103 | ```bash 104 | aws s3 ls 105 | aws s3 mb s3://test-create-bucket-account-b-e32e090290d 106 | aws s3 rb s3://test-create-bucket-account-b-e32e090290d 107 | ``` 108 | 13. Remove environment variables 109 | ```bash 110 | unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN 111 | ``` 112 | 14. Show that we are now executing commands as our Admin user again 113 | ```bash 114 | aws sts get-caller-identity 115 | ``` -------------------------------------------------------------------------------- /aws-iam/access-keys-and-iam-roles.md: -------------------------------------------------------------------------------- 1 | # Using access keys and IAM roles with Amazon EC2 2 | ## Ensure that you are connecting to the US-East-1 region 3 | 4 | # Exercise 1: Using access keys with EC2 5 | 6 | ## 1. Create Access Keys in CloudShell 7 | 8 | Run the following command in AWS CloudShell: 9 | 10 | ```bash 11 | aws iam create-access-key 12 | ``` 13 | 14 | You'll get output like this: 15 | 16 | ```json 17 | { 18 | "AccessKey": { 19 | "AccessKeyId": "AKIAxxxxxxxxxxxxxxxx", 20 | "SecretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 21 | } 22 | } 23 | ``` 24 | 25 | **Copy and save both keys.** You'll paste them into the EC2 instance soon. 26 | 27 | --- 28 | 29 | ## 2. Launch an EC2 Instance 30 | 31 | In CloudShell, run (update the AMI ID): 32 | 33 | ```bash 34 | aws ec2 run-instances \ 35 | --image-id ami-05ffe3c48a9991133 \ 36 | --instance-type t2.micro \ 37 | --region us-east-1 38 | ``` 39 | 40 | ## 3. Configure AWS CLI on the EC2 Instance 41 | 42 | Use EC2 Instance Connect to connect to the instnace and in the EC2 terminal run: 43 | 44 | ```bash 45 | aws configure 46 | ``` 47 | 48 | Enter: 49 | 50 | * **Access Key ID**: (from CloudShell step) 51 | * **Secret Access Key**: (from CloudShell step) 52 | * **Region**: `us-east-1` (or whatever you used) 53 | * **Output format**: `json` 54 | 55 | ## 5. Run AWS CLI Commands 56 | 57 | You can now test access with: 58 | 59 | ```bash 60 | aws sts get-caller-identity 61 | ``` 62 | 63 | Should return your IAM user identity. 64 | 65 | List S3 buckets (if you have permission): 66 | 67 | ```bash 68 | aws s3 ls 69 | ``` 70 | 71 | ## 6. Show That Access Keys Are Stored in Plaintext 72 | 73 | Run: 74 | 75 | ```bash 76 | cat ~/.aws/credentials 77 | ``` 78 | 79 | You'll see: 80 | 81 | ```bash 82 | [default] 83 | aws_access_key_id = AKIAxxxxxxxxxxxxxx 84 | aws_secret_access_key = xxxxxxxxxxxxxxxxxxx 85 | ``` 86 | 87 | * The AWS CLI stores credentials **in plaintext** 88 | * These credentials can be stolen if an instance is compromised 89 | 90 | ## 7. Delete the access keys 91 | 92 | Run the following command to delete ALL access keys from the instance: 93 | 94 | ```bash 95 | rm -rf ~/.aws/credentials 96 | ``` 97 | 98 | Run the following commands to validate credentials are lost: 99 | 100 | ```bash 101 | aws s3 ls 102 | aws sts get-caller-identity 103 | ``` 104 | 105 | # Exercise 2: Create IAM Role for EC2 106 | 107 | 1. Create an IAM role with a trust policy that uses the EC2 use case 108 | 2. Attach the 'AmazonS3FullAccess' permissions policy 109 | 3. Name the role 'sts-assumerole-test' 110 | 111 | ## 1. Launch instance and assume role 112 | 113 | ### 1a. Create a Security Group 114 | 115 | 1. Create a security group 116 | ```bash 117 | aws ec2 create-security-group --group-name IAMRoleLab --description "Temporary SG for the IAM Labs" 118 | ``` 119 | 2. Add a rule for SSH inbound to the security group 120 | ```bash 121 | aws ec2 authorize-security-group-ingress --group-name IAMRoleLab --protocol tcp --port 22 --cidr 0.0.0.0/0 122 | ``` 123 | 124 | ### 1b. Launch Instance 125 | 126 | 1. Launch EC2 instance 127 | ```bash 128 | aws ec2 run-instances --instance-type t2.micro --image-id ami-0440d3b780d96b29d --region us-east-1 --security-group-ids 129 | ``` 130 | 2. Describe EC2 instance 131 | ```bash 132 | aws ec2 describe-instances --instance-ids 133 | ``` 134 | 135 | ### 2. Create and Attach an Instance Profile 136 | 137 | 3. Create instance profile 138 | ```bash 139 | aws iam create-instance-profile --instance-profile-name s3-instance-profile 140 | ``` 141 | 4. Add role to instance profile 142 | ```bash 143 | aws iam add-role-to-instance-profile --role-name sts-assumerole-test --instance-profile-name s3-instance-profile 144 | ``` 145 | 5. Connect to EC2 Instance Connect and run the same S3 test commands as earlier. They should fail 146 | 6. Attach instance profile to EC2 instance 147 | ```bash 148 | aws ec2 associate-iam-instance-profile --iam-instance-profile Name=s3-instance-profile --instance-id 149 | ``` 150 | 7. Using EC2 instance connect, run the same S3 test commands as earlier. They should now work successfully 151 | 152 | ## 3. Cleanup 153 | 154 | 6. Terminate EC2 instance 155 | ```bash 156 | aws ec2 terminate-instances --instance-ids 157 | ``` 158 | 7. Remove role from instance profile 159 | ```bash 160 | aws iam remove-role-from-instance-profile --role-name sts-assumerole-test --instance-profile-name s3-instance-profile 161 | ``` 162 | 8. Delete instance profile 163 | ```bash 164 | aws iam delete-instance-profile --instance-profile-name s3-instance-profile 165 | ``` -------------------------------------------------------------------------------- /aws-cloudformation/create-vpc-cf-1-NGW.yaml: -------------------------------------------------------------------------------- 1 | Description: This template deploys a VPC, with a pair of public and private subnets spread 2 | across two Availability Zones. It deploys an internet gateway, with a default 3 | route on the public subnets. It deploys a pair of NAT gateways (one in each AZ), 4 | and default routes for them in the private subnets. 5 | 6 | Parameters: 7 | EnvironmentName: 8 | Description: An environment name that is prefixed to resource names 9 | Type: String 10 | 11 | VpcCIDR: 12 | Description: Please enter the IP range (CIDR notation) for this VPC 13 | Type: String 14 | Default: 10.8.0.0/16 15 | 16 | PublicSubnet1CIDR: 17 | Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone 18 | Type: String 19 | Default: 10.8.10.0/24 20 | 21 | PublicSubnet2CIDR: 22 | Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone 23 | Type: String 24 | Default: 10.8.11.0/24 25 | 26 | PrivateSubnet1CIDR: 27 | Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone 28 | Type: String 29 | Default: 10.8.20.0/24 30 | 31 | PrivateSubnet2CIDR: 32 | Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone 33 | Type: String 34 | Default: 10.8.21.0/24 35 | 36 | Resources: 37 | VPC: 38 | Type: AWS::EC2::VPC 39 | Properties: 40 | CidrBlock: !Ref VpcCIDR 41 | EnableDnsSupport: true 42 | EnableDnsHostnames: true 43 | Tags: 44 | - Key: Name 45 | Value: !Ref EnvironmentName 46 | 47 | InternetGateway: 48 | Type: AWS::EC2::InternetGateway 49 | Properties: 50 | Tags: 51 | - Key: Name 52 | Value: !Ref EnvironmentName 53 | 54 | InternetGatewayAttachment: 55 | Type: AWS::EC2::VPCGatewayAttachment 56 | Properties: 57 | InternetGatewayId: !Ref InternetGateway 58 | VpcId: !Ref VPC 59 | 60 | PublicSubnet1: 61 | Type: AWS::EC2::Subnet 62 | Properties: 63 | VpcId: !Ref VPC 64 | AvailabilityZone: !Select [ 0, !GetAZs '' ] 65 | CidrBlock: !Ref PublicSubnet1CIDR 66 | MapPublicIpOnLaunch: true 67 | Tags: 68 | - Key: Name 69 | Value: !Sub ${EnvironmentName} Public Subnet (AZ1) 70 | 71 | PublicSubnet2: 72 | Type: AWS::EC2::Subnet 73 | Properties: 74 | VpcId: !Ref VPC 75 | AvailabilityZone: !Select [ 1, !GetAZs '' ] 76 | CidrBlock: !Ref PublicSubnet2CIDR 77 | MapPublicIpOnLaunch: true 78 | Tags: 79 | - Key: Name 80 | Value: !Sub ${EnvironmentName} Public Subnet (AZ2) 81 | 82 | PrivateSubnet1: 83 | Type: AWS::EC2::Subnet 84 | Properties: 85 | VpcId: !Ref VPC 86 | AvailabilityZone: !Select [ 0, !GetAZs '' ] 87 | CidrBlock: !Ref PrivateSubnet1CIDR 88 | MapPublicIpOnLaunch: false 89 | Tags: 90 | - Key: Name 91 | Value: !Sub ${EnvironmentName} Private Subnet (AZ1) 92 | 93 | PrivateSubnet2: 94 | Type: AWS::EC2::Subnet 95 | Properties: 96 | VpcId: !Ref VPC 97 | AvailabilityZone: !Select [ 1, !GetAZs '' ] 98 | CidrBlock: !Ref PrivateSubnet2CIDR 99 | MapPublicIpOnLaunch: false 100 | Tags: 101 | - Key: Name 102 | Value: !Sub ${EnvironmentName} Private Subnet (AZ2) 103 | 104 | NatGateway1EIP: 105 | Type: AWS::EC2::EIP 106 | DependsOn: InternetGatewayAttachment 107 | Properties: 108 | Domain: vpc 109 | 110 | NatGateway1: 111 | Type: AWS::EC2::NatGateway 112 | Properties: 113 | AllocationId: !GetAtt NatGateway1EIP.AllocationId 114 | SubnetId: !Ref PublicSubnet1 115 | 116 | PublicRouteTable: 117 | Type: AWS::EC2::RouteTable 118 | Properties: 119 | VpcId: !Ref VPC 120 | Tags: 121 | - Key: Name 122 | Value: !Sub ${EnvironmentName} Public Routes 123 | 124 | DefaultPublicRoute: 125 | Type: AWS::EC2::Route 126 | DependsOn: InternetGatewayAttachment 127 | Properties: 128 | RouteTableId: !Ref PublicRouteTable 129 | DestinationCidrBlock: 0.0.0.0/0 130 | GatewayId: !Ref InternetGateway 131 | 132 | PublicSubnet1RouteTableAssociation: 133 | Type: AWS::EC2::SubnetRouteTableAssociation 134 | Properties: 135 | RouteTableId: !Ref PublicRouteTable 136 | SubnetId: !Ref PublicSubnet1 137 | 138 | PublicSubnet2RouteTableAssociation: 139 | Type: AWS::EC2::SubnetRouteTableAssociation 140 | Properties: 141 | RouteTableId: !Ref PublicRouteTable 142 | SubnetId: !Ref PublicSubnet2 143 | 144 | 145 | PrivateRouteTable1: 146 | Type: AWS::EC2::RouteTable 147 | Properties: 148 | VpcId: !Ref VPC 149 | Tags: 150 | - Key: Name 151 | Value: !Sub ${EnvironmentName} Private Routes (AZ1) 152 | 153 | DefaultPrivateRoute1: 154 | Type: AWS::EC2::Route 155 | Properties: 156 | RouteTableId: !Ref PrivateRouteTable1 157 | DestinationCidrBlock: 0.0.0.0/0 158 | NatGatewayId: !Ref NatGateway1 159 | 160 | PrivateSubnet1RouteTableAssociation: 161 | Type: AWS::EC2::SubnetRouteTableAssociation 162 | Properties: 163 | RouteTableId: !Ref PrivateRouteTable1 164 | SubnetId: !Ref PrivateSubnet1 165 | 166 | PrivateRouteTable2: 167 | Type: AWS::EC2::RouteTable 168 | Properties: 169 | VpcId: !Ref VPC 170 | Tags: 171 | - Key: Name 172 | Value: !Sub ${EnvironmentName} Private Routes (AZ2) 173 | 174 | PrivateSubnet2RouteTableAssociation: 175 | Type: AWS::EC2::SubnetRouteTableAssociation 176 | Properties: 177 | RouteTableId: !Ref PrivateRouteTable2 178 | SubnetId: !Ref PrivateSubnet2 179 | 180 | NoIngressSecurityGroup: 181 | Type: AWS::EC2::SecurityGroup 182 | Properties: 183 | GroupName: "no-ingress-sg" 184 | GroupDescription: "Security group with no ingress rule" 185 | VpcId: !Ref VPC 186 | 187 | Outputs: 188 | VPC: 189 | Description: A reference to the created VPC 190 | Value: !Ref VPC 191 | 192 | PublicSubnets: 193 | Description: A list of the public subnets 194 | Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]] 195 | 196 | PrivateSubnets: 197 | Description: A list of the private subnets 198 | Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]] 199 | 200 | PublicSubnet1: 201 | Description: A reference to the public subnet in the 1st Availability Zone 202 | Value: !Ref PublicSubnet1 203 | 204 | PublicSubnet2: 205 | Description: A reference to the public subnet in the 2nd Availability Zone 206 | Value: !Ref PublicSubnet2 207 | 208 | PrivateSubnet1: 209 | Description: A reference to the private subnet in the 1st Availability Zone 210 | Value: !Ref PrivateSubnet1 211 | 212 | PrivateSubnet2: 213 | Description: A reference to the private subnet in the 2nd Availability Zone 214 | Value: !Ref PrivateSubnet2 215 | 216 | NoIngressSecurityGroup: 217 | Description: Security group with no ingress rule 218 | Value: !Ref NoIngressSecurityGroup -------------------------------------------------------------------------------- /aws-cloudformation/create-vpc-cf.yaml: -------------------------------------------------------------------------------- 1 | Description: This template deploys a VPC, with a pair of public and private subnets spread 2 | across two Availability Zones. It deploys an internet gateway, with a default 3 | route on the public subnets. It deploys a pair of NAT gateways (one in each AZ), 4 | and default routes for them in the private subnets. 5 | 6 | Parameters: 7 | EnvironmentName: 8 | Description: An environment name that is prefixed to resource names 9 | Type: String 10 | 11 | VpcCIDR: 12 | Description: Please enter the IP range (CIDR notation) for this VPC 13 | Type: String 14 | Default: 10.8.0.0/16 15 | 16 | PublicSubnet1CIDR: 17 | Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone 18 | Type: String 19 | Default: 10.8.10.0/24 20 | 21 | PublicSubnet2CIDR: 22 | Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone 23 | Type: String 24 | Default: 10.8.11.0/24 25 | 26 | PrivateSubnet1CIDR: 27 | Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone 28 | Type: String 29 | Default: 10.8.20.0/24 30 | 31 | PrivateSubnet2CIDR: 32 | Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone 33 | Type: String 34 | Default: 10.8.21.0/24 35 | 36 | Resources: 37 | VPC: 38 | Type: AWS::EC2::VPC 39 | Properties: 40 | CidrBlock: !Ref VpcCIDR 41 | EnableDnsSupport: true 42 | EnableDnsHostnames: true 43 | Tags: 44 | - Key: Name 45 | Value: !Ref EnvironmentName 46 | 47 | InternetGateway: 48 | Type: AWS::EC2::InternetGateway 49 | Properties: 50 | Tags: 51 | - Key: Name 52 | Value: !Ref EnvironmentName 53 | 54 | InternetGatewayAttachment: 55 | Type: AWS::EC2::VPCGatewayAttachment 56 | Properties: 57 | InternetGatewayId: !Ref InternetGateway 58 | VpcId: !Ref VPC 59 | 60 | PublicSubnet1: 61 | Type: AWS::EC2::Subnet 62 | Properties: 63 | VpcId: !Ref VPC 64 | AvailabilityZone: !Select [ 0, !GetAZs '' ] 65 | CidrBlock: !Ref PublicSubnet1CIDR 66 | MapPublicIpOnLaunch: true 67 | Tags: 68 | - Key: Name 69 | Value: !Sub ${EnvironmentName} Public Subnet (AZ1) 70 | 71 | PublicSubnet2: 72 | Type: AWS::EC2::Subnet 73 | Properties: 74 | VpcId: !Ref VPC 75 | AvailabilityZone: !Select [ 1, !GetAZs '' ] 76 | CidrBlock: !Ref PublicSubnet2CIDR 77 | MapPublicIpOnLaunch: true 78 | Tags: 79 | - Key: Name 80 | Value: !Sub ${EnvironmentName} Public Subnet (AZ2) 81 | 82 | PrivateSubnet1: 83 | Type: AWS::EC2::Subnet 84 | Properties: 85 | VpcId: !Ref VPC 86 | AvailabilityZone: !Select [ 0, !GetAZs '' ] 87 | CidrBlock: !Ref PrivateSubnet1CIDR 88 | MapPublicIpOnLaunch: false 89 | Tags: 90 | - Key: Name 91 | Value: !Sub ${EnvironmentName} Private Subnet (AZ1) 92 | 93 | PrivateSubnet2: 94 | Type: AWS::EC2::Subnet 95 | Properties: 96 | VpcId: !Ref VPC 97 | AvailabilityZone: !Select [ 1, !GetAZs '' ] 98 | CidrBlock: !Ref PrivateSubnet2CIDR 99 | MapPublicIpOnLaunch: false 100 | Tags: 101 | - Key: Name 102 | Value: !Sub ${EnvironmentName} Private Subnet (AZ2) 103 | 104 | NatGateway1EIP: 105 | Type: AWS::EC2::EIP 106 | DependsOn: InternetGatewayAttachment 107 | Properties: 108 | Domain: vpc 109 | 110 | NatGateway2EIP: 111 | Type: AWS::EC2::EIP 112 | DependsOn: InternetGatewayAttachment 113 | Properties: 114 | Domain: vpc 115 | 116 | NatGateway1: 117 | Type: AWS::EC2::NatGateway 118 | Properties: 119 | AllocationId: !GetAtt NatGateway1EIP.AllocationId 120 | SubnetId: !Ref PublicSubnet1 121 | 122 | NatGateway2: 123 | Type: AWS::EC2::NatGateway 124 | Properties: 125 | AllocationId: !GetAtt NatGateway2EIP.AllocationId 126 | SubnetId: !Ref PublicSubnet2 127 | 128 | PublicRouteTable: 129 | Type: AWS::EC2::RouteTable 130 | Properties: 131 | VpcId: !Ref VPC 132 | Tags: 133 | - Key: Name 134 | Value: !Sub ${EnvironmentName} Public Routes 135 | 136 | DefaultPublicRoute: 137 | Type: AWS::EC2::Route 138 | DependsOn: InternetGatewayAttachment 139 | Properties: 140 | RouteTableId: !Ref PublicRouteTable 141 | DestinationCidrBlock: 0.0.0.0/0 142 | GatewayId: !Ref InternetGateway 143 | 144 | PublicSubnet1RouteTableAssociation: 145 | Type: AWS::EC2::SubnetRouteTableAssociation 146 | Properties: 147 | RouteTableId: !Ref PublicRouteTable 148 | SubnetId: !Ref PublicSubnet1 149 | 150 | PublicSubnet2RouteTableAssociation: 151 | Type: AWS::EC2::SubnetRouteTableAssociation 152 | Properties: 153 | RouteTableId: !Ref PublicRouteTable 154 | SubnetId: !Ref PublicSubnet2 155 | 156 | 157 | PrivateRouteTable1: 158 | Type: AWS::EC2::RouteTable 159 | Properties: 160 | VpcId: !Ref VPC 161 | Tags: 162 | - Key: Name 163 | Value: !Sub ${EnvironmentName} Private Routes (AZ1) 164 | 165 | DefaultPrivateRoute1: 166 | Type: AWS::EC2::Route 167 | Properties: 168 | RouteTableId: !Ref PrivateRouteTable1 169 | DestinationCidrBlock: 0.0.0.0/0 170 | NatGatewayId: !Ref NatGateway1 171 | 172 | PrivateSubnet1RouteTableAssociation: 173 | Type: AWS::EC2::SubnetRouteTableAssociation 174 | Properties: 175 | RouteTableId: !Ref PrivateRouteTable1 176 | SubnetId: !Ref PrivateSubnet1 177 | 178 | PrivateRouteTable2: 179 | Type: AWS::EC2::RouteTable 180 | Properties: 181 | VpcId: !Ref VPC 182 | Tags: 183 | - Key: Name 184 | Value: !Sub ${EnvironmentName} Private Routes (AZ2) 185 | 186 | DefaultPrivateRoute2: 187 | Type: AWS::EC2::Route 188 | Properties: 189 | RouteTableId: !Ref PrivateRouteTable2 190 | DestinationCidrBlock: 0.0.0.0/0 191 | NatGatewayId: !Ref NatGateway2 192 | 193 | PrivateSubnet2RouteTableAssociation: 194 | Type: AWS::EC2::SubnetRouteTableAssociation 195 | Properties: 196 | RouteTableId: !Ref PrivateRouteTable2 197 | SubnetId: !Ref PrivateSubnet2 198 | 199 | NoIngressSecurityGroup: 200 | Type: AWS::EC2::SecurityGroup 201 | Properties: 202 | GroupName: "no-ingress-sg" 203 | GroupDescription: "Security group with no ingress rule" 204 | VpcId: !Ref VPC 205 | 206 | Outputs: 207 | VPC: 208 | Description: A reference to the created VPC 209 | Value: !Ref VPC 210 | 211 | PublicSubnets: 212 | Description: A list of the public subnets 213 | Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]] 214 | 215 | PrivateSubnets: 216 | Description: A list of the private subnets 217 | Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]] 218 | 219 | PublicSubnet1: 220 | Description: A reference to the public subnet in the 1st Availability Zone 221 | Value: !Ref PublicSubnet1 222 | 223 | PublicSubnet2: 224 | Description: A reference to the public subnet in the 2nd Availability Zone 225 | Value: !Ref PublicSubnet2 226 | 227 | PrivateSubnet1: 228 | Description: A reference to the private subnet in the 1st Availability Zone 229 | Value: !Ref PrivateSubnet1 230 | 231 | PrivateSubnet2: 232 | Description: A reference to the private subnet in the 2nd Availability Zone 233 | Value: !Ref PrivateSubnet2 234 | 235 | NoIngressSecurityGroup: 236 | Description: Security group with no ingress rule 237 | Value: !Ref NoIngressSecurityGroup --------------------------------------------------------------------------------