├── README.md ├── amazon-cloudfront ├── aws-waf-command.md └── index.html ├── amazon-cloudwatch ├── custom-cloudwatch-metrics.md ├── cw-config.json ├── cw-log-and-filters.md ├── install-cloudwatch-agent.md └── launch-instances-with-a-tag.md ├── amazon-dynamodb └── ProductCatalog.json ├── amazon-eventbridge ├── eventbridge-lambda-function.js ├── eventbridge-schedule.md └── run-instance-stop-instance.md ├── amazon-route-53 ├── cloudformation-ec2-alb.yml ├── ec2-user-data-web-app.md └── launch-ec2-alb.md ├── amazon-s3 ├── bucket-policy.json ├── error.html ├── index.html └── website.css ├── amazon-vpc ├── create-nat-gateway.md ├── custom-vpc.md ├── vpc-peering-us-east-1.yaml └── vpc-peering-us-west-1.yaml ├── auto-scaling-and-elb ├── create-asg-alb-cli.md ├── ec2-user-data-web-app.md ├── iam-permissions-policy-lambda.json ├── lambda-lifecycle-action.py └── lifecycle-action.md ├── aws-cloudformation ├── 1 EC2Instance.yml ├── 2 EC2InstanceIP.yml ├── 3 EC2InstanceMappings.yml ├── 4 EC2InstanceParameters.yml ├── 5 EC2InstanceIPandSG.yml ├── 6 EC2InstanceWithUserData.yml └── 7 ELBWithLockedDownAutoScaledInstances.json ├── aws-elastic-beanstalk └── nodejs.zip ├── aws-fundamentals ├── launching-ec2-and-ebs.md ├── working-with-files-on-efs.md └── working-with-objects-on-s3.md ├── aws-iam ├── aws-cli-with-mfa.md └── cross-account-role.md ├── aws-organizations └── create-organization-scp.md ├── aws-secrets-manager └── retrieve-secret-lambda-code.js ├── operating-system-commands ├── basic-linux-mac-commands.md └── basic-windows-commands.md └── ssm-automation-and-config ├── automation-iam-role.json └── config-rule-and-remediation.md /README.md: -------------------------------------------------------------------------------- 1 | # AWS Certified SysOps Administrator Associate 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 SysOps Administrator Associate (SOA-C02) exam. 11 | 12 | The guided practical exercises will teach you how to deploy, manage and operate scalable, highly available and fault-tolerant systems on AWS. 13 | 14 | The course includes highly visual slides available for download. 15 | 16 | With the help of the innovative exam scenario lessons, you'll learn how to best answer the scenarios that feature on the SOA-C02 exam. 17 | 18 | ***What you will learn:*** 19 | 20 | This course covers all of the following topics that are included in the AWS Certified SysOps Administrator Associate (SOA-C02) exam guide and are featuring on the exam today: 21 | 22 | - Amazon EC2, AWS Lambda, Amazon EC2 Auto Scaling, Elastic Load Balancing, EBS, EFS, and AWS Storage Gateway 23 | - AWS Systems Manager, AWS OpsWorks, AWS Elastic Beanstalk, AWS CloudFormation, and Amazon VPC 24 | - Amazon Route 53, Amazon S3, Amazon CloudFront, AWS Organizations, Amazon CloudWatch, AWS CloudTrail 25 | - AWS Config, AWS Service Catalog, AWS Trusted Advisor, AWS IAM, Amazon Inspector, AWS KMS, AWS CloudHSM, AWS WAF & Shield, AWS Artifact, and AWS Directory Services 26 | 27 | Learn more and [enroll in this course](https://digitalcloud.training/aws-certified-sysops-administrator-associate/) now to earn your AWS Certified SysOps Administrator Associate certification 28 | -------------------------------------------------------------------------------- /amazon-cloudfront/aws-waf-command.md: -------------------------------------------------------------------------------- 1 | # Use this command on CloudShell to trip the WAF rule 2 | for i in {1..140}; do curl https://dcttestlabs.link/; done -------------------------------------------------------------------------------- /amazon-cloudfront/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 |

This website was securely accessed through Amazon CloudFront

15 | 16 | -------------------------------------------------------------------------------- /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 | 1. Create an IAM policy 5 | aws iam create-policy --policy-name "CloudWatch-Put-Metric-Data" --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["cloudwatch:PutMetricData"],"Resource":"*"}]}' 6 | 2. Create an IAM role that uses the policy document 7 | 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"}]}' 8 | 3. Attach the policy to the role (update policy ARN) 9 | aws iam attach-role-policy --role-name "CloudWatch-Role" --policy-arn "arn:aws:iam::821711655051:policy/CloudWatch-Put-Metric-Data" 10 | 4. Create an instance profile 11 | aws iam create-instance-profile --instance-profile-name "CloudWatch-Instance-Profile" 12 | 5. Add the role to the instance profile 13 | aws iam add-role-to-instance-profile --instance-profile-name "CloudWatch-Instance-Profile" --role-name "CloudWatch-Role" 14 | 15 | ## Launch an EC2 instance 16 | 1. Create a security group 17 | aws ec2 create-security-group --group-name CustomMetricLab --description "Temporary SG for the Custom Metric Lab" 18 | 2. Add a rule for SSH inbound to the security group 19 | aws ec2 authorize-security-group-ingress --group-name CustomMetricLab --protocol tcp --port 22 --cidr 0.0.0.0/0 20 | 3. Launch instance in US-EAST-1A 21 | aws ec2 run-instances --image-id ami-0aa7d40eeae50c9a9 --instance-type t2.micro --placement AvailabilityZone=us-east-1a --security-group-ids sg-0c6f4290d647e7813 --iam-instance-profile Name="CloudWatch-Instance-Profile" 22 | 23 | # Run the remaining commands from the EC2 instance 24 | 25 | ## Install stress 26 | (Amazon Linux 2 command) `sudo amazon-linux-extras install epel -y` 27 | (Amazon Linux 2 command) `sudo yum install stress-ng -y` 28 | 29 | (Amazon Linux 2023 command): `sudo dnf install stress-ng -y` 30 | 31 | ## Configure a shell script that uses the put-metric-data API 32 | 1. Create a shell script named mem-usage.sh 33 | sudo nano mem-usage.sh 34 | 2. Add the following code and save: 35 | 36 | #!/bin/bash 37 | 38 | aws cloudwatch put-metric-data --region us-east-1 --namespace "Custom/Memory" --metric-name "MemUsage" --value "$(free | awk '/Mem/{printf("%d", ($2-$7)/$2*100)}')" --unit "Percent" --dimensions "Name=InstanceId,Value=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)" 39 | 40 | 3. Make the script executable 41 | sudo chmod +x mem-usage.sh 42 | 4. Add the script to crontab, first open crontab 43 | crontab -e 44 | 5. Then, add the following line to execute the script every minute 45 | * * * * * /home/ec2-user/mem-usage.sh 46 | 6. Save by typing the following and pressing enter 47 | :wq 48 | 49 | ## Run the stres utility to generate load 50 | stress-ng --vm 15 --vm-bytes 80% --vm-method all --verify -t 60m -v 51 | 52 | ## Create an alarm in CloudWatch 53 | 1. Create an alarm that is based on the custom metric 54 | 55 | 56 | -------------------------------------------------------------------------------- /amazon-cloudwatch/cw-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "agent": { 3 | "metrics_collection_interval": 10, 4 | "run_as_user": "root" 5 | }, 6 | "logs": { 7 | "logs_collected": { 8 | "files": { 9 | "collect_list": [ 10 | { 11 | "file_path": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log", 12 | "log_group_name": "/apps/CloudWatchAgentLog/", 13 | "log_stream_name": "{ip_address}_{instance_id}", 14 | "timezone": "Local" 15 | }, 16 | { 17 | "file_path": "/var/log/messages", 18 | "log_group_name": "/apps/system/messages", 19 | "log_stream_name": "{ip_address}_{instance_id}", 20 | "timestamp_format": "%b %d %H:%M:%S", 21 | "timezone": "Local" 22 | }, 23 | { 24 | "file_path": "/var/log/httpd/access_log", 25 | "log_group_name": "/apps/webservers/httpd/access", 26 | "log_stream_name": "{ip_address}_{instance_id}", 27 | "timestamp_format": "%d/%b/%Y:%H:%M:%S %z", 28 | "timezone": "Local" 29 | } 30 | ] 31 | } 32 | } 33 | }, 34 | "metrics": { 35 | "aggregation_dimensions": [ 36 | [ 37 | "InstanceId" 38 | ] 39 | ], 40 | "append_dimensions": { 41 | "AutoScalingGroupName": "${aws:AutoScalingGroupName}", 42 | "ImageId": "${aws:ImageId}", 43 | "InstanceId": "${aws:InstanceId}", 44 | "InstanceType": "${aws:InstanceType}" 45 | }, 46 | "metrics_collected": { 47 | "collectd": { 48 | "metrics_aggregation_interval": 60 49 | }, 50 | "disk": { 51 | "measurement": [ 52 | "used_percent" 53 | ], 54 | "metrics_collection_interval": 10, 55 | "resources": [ 56 | "*" 57 | ] 58 | }, 59 | "mem": { 60 | "measurement": [ 61 | "mem_used_percent" 62 | ], 63 | "metrics_collection_interval": 10 64 | }, 65 | "statsd": { 66 | "metrics_aggregation_interval": 60, 67 | "metrics_collection_interval": 10, 68 | "service_address": ":8125" 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /amazon-cloudwatch/cw-log-and-filters.md: -------------------------------------------------------------------------------- 1 | # Install Apache and Configure Logging 2 | 1. If not already installed, install the CloudWatch agent 3 | sudo yum install amazon-cloudwatch-agent 4 | 2. Also, install collectd 5 | sudo amazon-linux-extras install collectd 6 | 3. Install and enable Apache 7 | sudo yum install -y httpd 8 | sudo systemctl start httpd 9 | sudo systemctl enable httpd 10 | 4. If the config file exists, delete it 11 | sudo rm -rf /opt/aws/amazon-cloudwatch-agent/bin/config.json 12 | 5. Create the config.json 13 | sudo nano /opt/aws/amazon-cloudwatch-agent/bin/config.json 14 | 6. Add the contents from the cw-config.json file provided 15 | 7. Run the following commmand 16 | sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s 17 | 8. Then make sure the agent is started 18 | sudo systemctl start amazon-cloudwatch-agent 19 | 9. Generate some traffic to Apache including some 404s 20 | 21 | # Create a metric filter and alarm 22 | 1. Create a metric filter and use the following pattern 23 | [host, logName, user, timestamp, request, statusCode=404, size] 24 | 2. Define the filter and create 25 | Name = 404 26 | Metric namespace = HTTPStatusCode 27 | Metric name = 404Error 28 | Metric value = 1 29 | Unit = Count 30 | 3. Create an alarm for the filter with count greater than 2 in 5 minutes 31 | 4. Create a new SNS Topic or use an existing one 32 | 5. Generate more 404 errors -------------------------------------------------------------------------------- /amazon-cloudwatch/install-cloudwatch-agent.md: -------------------------------------------------------------------------------- 1 | # Create the IAM role for SSM/CloudWatch 2 | 1. Create an IAM role with an EC2 trust policy 3 | 2. Add the following managed policies 4 | CloudWatchAgentServerPolicy 5 | AmazonSSMManagedInstanceCore 6 | 3. Name the IAM role as below and create 7 | CloudWatchAgentServerRole 8 | 4. Launch an EC2 instance and attach the role 9 | 10 | # Install the CloudWatch agent using SSM Run Command 11 | 1. Choose AWS-ConfigureAWSPackage 12 | 2. Under name enter AmazonCloudWatchAgent 13 | 3. Install collectd 14 | sudo amazon-linux-extras install collectd 15 | 4. Run the wizard on the EC2 instance command line 16 | sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard 17 | 5. During the wizard specify additional log file collection 18 | /var/log/messages 19 | 6. Run the following commmand 20 | sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s 21 | 7. Then make sure the agent is started 22 | sudo systemctl start amazon-cloudwatch-agent -------------------------------------------------------------------------------- /amazon-cloudwatch/launch-instances-with-a-tag.md: -------------------------------------------------------------------------------- 1 | # Launch instances with a tag 2 | aws ec2 run-instances --image-id ami-0dfcb1ef8550277af --count 2 --instance-type t2.micro --tag-specifications 'ResourceType=instance,Tags=[{Key=Department,Value=Operations}]' 3 | 4 | # CloudWatch Logs Insights query 5 | fields @timestamp, @message | sort @timestamp desc | limit 25 6 | -------------------------------------------------------------------------------- /amazon-dynamodb/ProductCatalog.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProductCatalog": [ 3 | { 4 | "PutRequest": { 5 | "Item": { 6 | "Id": { 7 | "N": "101" 8 | }, 9 | "Title": { 10 | "S": "Book 101 Title" 11 | }, 12 | "ISBN": { 13 | "S": "111-1111111111" 14 | }, 15 | "Authors": { 16 | "L": [ 17 | { 18 | "S": "Author1" 19 | } 20 | ] 21 | }, 22 | "Price": { 23 | "N": "2" 24 | }, 25 | "Dimensions": { 26 | "S": "8.5 x 11.0 x 0.5" 27 | }, 28 | "PageCount": { 29 | "N": "500" 30 | }, 31 | "InPublication": { 32 | "BOOL": true 33 | }, 34 | "ProductCategory": { 35 | "S": "Book" 36 | } 37 | } 38 | } 39 | }, 40 | { 41 | "PutRequest": { 42 | "Item": { 43 | "Id": { 44 | "N": "102" 45 | }, 46 | "Title": { 47 | "S": "Book 102 Title" 48 | }, 49 | "ISBN": { 50 | "S": "222-2222222222" 51 | }, 52 | "Authors": { 53 | "L": [ 54 | { 55 | "S": "Author1" 56 | }, 57 | { 58 | "S": "Author2" 59 | } 60 | ] 61 | }, 62 | "Price": { 63 | "N": "20" 64 | }, 65 | "Dimensions": { 66 | "S": "8.5 x 11.0 x 0.8" 67 | }, 68 | "PageCount": { 69 | "N": "600" 70 | }, 71 | "InPublication": { 72 | "BOOL": true 73 | }, 74 | "ProductCategory": { 75 | "S": "Book" 76 | } 77 | } 78 | } 79 | }, 80 | { 81 | "PutRequest": { 82 | "Item": { 83 | "Id": { 84 | "N": "103" 85 | }, 86 | "Title": { 87 | "S": "Book 103 Title" 88 | }, 89 | "ISBN": { 90 | "S": "333-3333333333" 91 | }, 92 | "Authors": { 93 | "L": [ 94 | { 95 | "S": "Author1" 96 | }, 97 | { 98 | "S": "Author2" 99 | } 100 | ] 101 | }, 102 | "Price": { 103 | "N": "2000" 104 | }, 105 | "Dimensions": { 106 | "S": "8.5 x 11.0 x 1.5" 107 | }, 108 | "PageCount": { 109 | "N": "600" 110 | }, 111 | "InPublication": { 112 | "BOOL": false 113 | }, 114 | "ProductCategory": { 115 | "S": "Book" 116 | } 117 | } 118 | } 119 | }, 120 | { 121 | "PutRequest": { 122 | "Item": { 123 | "Id": { 124 | "N": "201" 125 | }, 126 | "Title": { 127 | "S": "18-Bike-201" 128 | }, 129 | "Description": { 130 | "S": "201 Description" 131 | }, 132 | "BicycleType": { 133 | "S": "Road" 134 | }, 135 | "Brand": { 136 | "S": "Mountain A" 137 | }, 138 | "Price": { 139 | "N": "100" 140 | }, 141 | "Color": { 142 | "L": [ 143 | { 144 | "S": "Red" 145 | }, 146 | { 147 | "S": "Black" 148 | } 149 | ] 150 | }, 151 | "ProductCategory": { 152 | "S": "Bicycle" 153 | } 154 | } 155 | } 156 | }, 157 | { 158 | "PutRequest": { 159 | "Item": { 160 | "Id": { 161 | "N": "202" 162 | }, 163 | "Title": { 164 | "S": "21-Bike-202" 165 | }, 166 | "Description": { 167 | "S": "202 Description" 168 | }, 169 | "BicycleType": { 170 | "S": "Road" 171 | }, 172 | "Brand": { 173 | "S": "Brand-Company A" 174 | }, 175 | "Price": { 176 | "N": "200" 177 | }, 178 | "Color": { 179 | "L": [ 180 | { 181 | "S": "Green" 182 | }, 183 | { 184 | "S": "Black" 185 | } 186 | ] 187 | }, 188 | "ProductCategory": { 189 | "S": "Bicycle" 190 | } 191 | } 192 | } 193 | }, 194 | { 195 | "PutRequest": { 196 | "Item": { 197 | "Id": { 198 | "N": "203" 199 | }, 200 | "Title": { 201 | "S": "19-Bike-203" 202 | }, 203 | "Description": { 204 | "S": "203 Description" 205 | }, 206 | "BicycleType": { 207 | "S": "Road" 208 | }, 209 | "Brand": { 210 | "S": "Brand-Company B" 211 | }, 212 | "Price": { 213 | "N": "300" 214 | }, 215 | "Color": { 216 | "L": [ 217 | { 218 | "S": "Red" 219 | }, 220 | { 221 | "S": "Green" 222 | }, 223 | { 224 | "S": "Black" 225 | } 226 | ] 227 | }, 228 | "ProductCategory": { 229 | "S": "Bicycle" 230 | } 231 | } 232 | } 233 | }, 234 | { 235 | "PutRequest": { 236 | "Item": { 237 | "Id": { 238 | "N": "204" 239 | }, 240 | "Title": { 241 | "S": "18-Bike-204" 242 | }, 243 | "Description": { 244 | "S": "204 Description" 245 | }, 246 | "BicycleType": { 247 | "S": "Mountain" 248 | }, 249 | "Brand": { 250 | "S": "Brand-Company B" 251 | }, 252 | "Price": { 253 | "N": "400" 254 | }, 255 | "Color": { 256 | "L": [ 257 | { 258 | "S": "Red" 259 | } 260 | ] 261 | }, 262 | "ProductCategory": { 263 | "S": "Bicycle" 264 | } 265 | } 266 | } 267 | }, 268 | { 269 | "PutRequest": { 270 | "Item": { 271 | "Id": { 272 | "N": "205" 273 | }, 274 | "Title": { 275 | "S": "18-Bike-204" 276 | }, 277 | "Description": { 278 | "S": "205 Description" 279 | }, 280 | "BicycleType": { 281 | "S": "Hybrid" 282 | }, 283 | "Brand": { 284 | "S": "Brand-Company C" 285 | }, 286 | "Price": { 287 | "N": "500" 288 | }, 289 | "Color": { 290 | "L": [ 291 | { 292 | "S": "Red" 293 | }, 294 | { 295 | "S": "Black" 296 | } 297 | ] 298 | }, 299 | "ProductCategory": { 300 | "S": "Bicycle" 301 | } 302 | } 303 | } 304 | } 305 | ] 306 | } 307 | -------------------------------------------------------------------------------- /amazon-eventbridge/eventbridge-lambda-function.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/eventbridge-schedule.md: -------------------------------------------------------------------------------- 1 | # Create a Lambda function with Nodejs 16 and the below code 2 | 3 | exports.handler = async (event, context) => { 4 | const message = event['message']; 5 | console.log(message); 6 | }; 7 | 8 | 9 | # Create an Eventbridge schedule with the following payload 10 | 11 | { 12 | "message": "Hello from EventBridge!" 13 | } 14 | -------------------------------------------------------------------------------- /amazon-eventbridge/run-instance-stop-instance.md: -------------------------------------------------------------------------------- 1 | # Launch instance, stop instance 2 | 1. Launch an EC2 instance 3 | aws ec2 run-instances --image-id ami-0aa7d40eeae50c9a9 --instance-type t2.micro --placement AvailabilityZone=us-east-1a 4 | 2. Stop the EC2 instance 5 | aws ec2 stop-instances --instance-id i-XXXXXXXXXXXXXXX -------------------------------------------------------------------------------- /amazon-route-53/cloudformation-ec2-alb.yml: -------------------------------------------------------------------------------- 1 | Resources: 2 | VPC: 3 | Type: AWS::EC2::VPC 4 | Properties: 5 | CidrBlock: 10.0.0.0/16 6 | EnableDnsSupport: true 7 | EnableDnsHostnames: true 8 | Tags: 9 | - Key: Name 10 | Value: VPC1 11 | 12 | InternetGateway: 13 | Type: AWS::EC2::InternetGateway 14 | 15 | 16 | AttachGateway: 17 | Type: AWS::EC2::VPCGatewayAttachment 18 | Properties: 19 | VpcId: !Ref VPC 20 | InternetGatewayId: !Ref InternetGateway 21 | 22 | PublicSubnet1: 23 | Type: AWS::EC2::Subnet 24 | Properties: 25 | VpcId: !Ref VPC 26 | CidrBlock: 10.0.1.0/24 27 | AvailabilityZone: us-east-1a 28 | MapPublicIpOnLaunch: true 29 | Tags: 30 | - Key: Name 31 | Value: Public Subnet 1 32 | 33 | 34 | PublicSubnet2: 35 | Type: AWS::EC2::Subnet 36 | Properties: 37 | VpcId: !Ref VPC 38 | CidrBlock: 10.0.3.0/24 39 | AvailabilityZone: us-east-1b 40 | MapPublicIpOnLaunch: true 41 | Tags: 42 | - Key: Name 43 | Value: Public Subnet 2 44 | 45 | 46 | PublicRouteTable: 47 | Type: AWS::EC2::RouteTable 48 | Properties: 49 | VpcId: !Ref VPC 50 | Tags: 51 | - Key: Name 52 | Value: Public Route Table 53 | 54 | PublicRoute: 55 | Type: AWS::EC2::Route 56 | Properties: 57 | RouteTableId: !Ref PublicRouteTable 58 | DestinationCidrBlock: 0.0.0.0/0 59 | GatewayId: !Ref InternetGateway 60 | 61 | PublicSubnetRouteTableAssociation1: 62 | Type: AWS::EC2::SubnetRouteTableAssociation 63 | Properties: 64 | SubnetId: !Ref PublicSubnet1 65 | RouteTableId: !Ref PublicRouteTable 66 | 67 | PublicSubnetRouteTableAssociation2: 68 | Type: AWS::EC2::SubnetRouteTableAssociation 69 | Properties: 70 | SubnetId: !Ref PublicSubnet2 71 | RouteTableId: !Ref PublicRouteTable 72 | 73 | 74 | #EC2 Instances 75 | EC2Instance1: 76 | Type: AWS::EC2::Instance 77 | Properties: 78 | ImageId: ami-006dcf34c09e50022 79 | InstanceType: t2.micro 80 | SecurityGroupIds: 81 | - !Ref EC2SecurityGroup 82 | SubnetId: !Ref PublicSubnet1 83 | 84 | UserData: 85 | Fn::Base64: !Sub | 86 | #!/bin/bash 87 | yum update -y 88 | yum install -y httpd 89 | service httpd start 90 | chkconfig httpd on 91 | echo "This EC2 instance is in the $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone) Availability Zone." > /var/www/html/index.html 92 | 93 | # EC2 and ALB Security Groups 94 | ELBSecurityGroup: 95 | Type: AWS::EC2::SecurityGroup 96 | Properties: 97 | GroupDescription: ELB Security Group 98 | VpcId: !Ref VPC 99 | SecurityGroupIngress: 100 | - IpProtocol: tcp 101 | FromPort: 80 102 | ToPort: 80 103 | CidrIp: 0.0.0.0/0 104 | 105 | EC2SecurityGroup: 106 | Type: AWS::EC2::SecurityGroup 107 | Properties: 108 | GroupDescription: 'My Security Group' 109 | VpcId: !Ref VPC 110 | SecurityGroupIngress: 111 | - IpProtocol: tcp 112 | FromPort: 80 113 | ToPort: 80 114 | SourceSecurityGroupId: 115 | Fn::GetAtt: 116 | - ELBSecurityGroup 117 | - GroupId 118 | - IpProtocol: tcp 119 | FromPort: 22 120 | ToPort: 22 121 | CidrIp: 0.0.0.0/0 122 | 123 | # Target Group, Listener and Application Load Balancer 124 | EC2TargetGroup: 125 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 126 | Properties: 127 | HealthCheckIntervalSeconds: 30 128 | HealthCheckProtocol: HTTP 129 | HealthCheckTimeoutSeconds: 15 130 | HealthyThresholdCount: 5 131 | Matcher: 132 | HttpCode: '200' 133 | Name: EC2TargetGroup 134 | Port: 80 135 | Protocol: HTTP 136 | TargetGroupAttributes: 137 | - Key: deregistration_delay.timeout_seconds 138 | Value: '20' 139 | Targets: 140 | - Id: !Ref EC2Instance1 141 | Port: 80 142 | Port: 80 143 | UnhealthyThresholdCount: 3 144 | VpcId: !Ref VPC 145 | 146 | ALBListener: 147 | Type: AWS::ElasticLoadBalancingV2::Listener 148 | Properties: 149 | DefaultActions: 150 | - Type: forward 151 | TargetGroupArn: !Ref EC2TargetGroup 152 | LoadBalancerArn: !Ref ApplicationLoadBalancer 153 | Port: 80 154 | Protocol: HTTP 155 | 156 | ApplicationLoadBalancer: 157 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer 158 | Properties: 159 | Scheme: internet-facing 160 | Subnets: 161 | - !Ref PublicSubnet1 162 | - !Ref PublicSubnet2 163 | SecurityGroups: 164 | - !GetAtt ELBSecurityGroup.GroupId 165 | 166 | -------------------------------------------------------------------------------- /amazon-route-53/ec2-user-data-web-app.md: -------------------------------------------------------------------------------- 1 | # CODE UPDATED SO IT WORKS WITH AMAZON LINUX 2 AMI AND AMAZON LINUX 2023 2 | *** COPY CODE FROM LINES UNDERNEATH ONLY *** 3 | 4 | #!/bin/bash 5 | yum update -y 6 | yum install -y httpd 7 | systemctl start httpd 8 | systemctl enable httpd 9 | 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) 10 | echo '

This Amazon EC2 instance is located in Availability Zone: AZID

' > /var/www/html/index.txt 11 | sed "s/AZID/$EC2AZ/" /var/www/html/index.txt > /var/www/html/index.html -------------------------------------------------------------------------------- /amazon-route-53/launch-ec2-alb.md: -------------------------------------------------------------------------------- 1 | # Perform the following actions per Region 2 | 3 | aws ec2 create-security-group --group-name R53PolicyTest --description "Route 53 Policy Test" --region us-east-1 4 | 5 | aws ec2 authorize-security-group-ingress --group-name R53PolicyTest --protocol tcp --port 22 --cidr 0.0.0.0/0 --region us-east-1 6 | 7 | aws ec2 authorize-security-group-ingress --group-name R53PolicyTest --protocol tcp --port 80 --cidr 0.0.0.0/0 --region us-east-1 8 | 9 | aws ec2 run-instances --image-id --count 1 --instance-type t2.micro --security-group-ids --subnet-id --user-data file://ec2-user-data-web-app.txt --region us-east-1 10 | 11 | aws elbv2 create-load-balancer --name ALB1 --subnets --security-groups --type application 12 | 13 | aws elbv2 create-target-group --name TG1 --protocol HTTP --port 80 --vpc-id 14 | 15 | aws elbv2 register-targets --target-group-arn --targets Id= 16 | 17 | aws elbv2 create-listener --load-balancer-arn --protocol HTTP --port 80 --default-actions Type=forward,TargetGroupArn= -------------------------------------------------------------------------------- /amazon-s3/bucket-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "AllowPublicAccesstoObjects", 6 | "Effect": "Allow", 7 | "Principal": "*", 8 | "Action": "s3:GetObject", 9 | "Resource": "YOUR-BUCKET-ARN/*" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /amazon-s3/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | S3 Static Website 5 | 6 | 7 | 8 | 9 |
10 |

Oops, there was an error in your request

11 |
12 | 13 | -------------------------------------------------------------------------------- /amazon-s3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | S3 Static Website 5 | 6 | 7 | 8 | 9 |
10 |

Welcome to the S3 Static Website!

11 |
12 | 13 | -------------------------------------------------------------------------------- /amazon-s3/website.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family:monospace; 3 | font-weight:bold; 4 | width: 100%; 5 | height: 100vh; 6 | display: flex; 7 | align-items: center; 8 | justify-content: center; 9 | background-size: 300% 300%; 10 | background-image: linear-gradient( 11 | -45deg, 12 | rgba(59,173,227,1) 0%, 13 | rgba(87,111,230,1) 25%, 14 | rgba(152,68,183,1) 51%, 15 | rgba(255,53,127,1) 100% 16 | ); 17 | animation: AnimateBG 20s ease infinite; 18 | } 19 | .mainBox { 20 | width: 100%; 21 | display: flex; 22 | flex-direction: column; 23 | align-items: center; 24 | } 25 | .textBox { 26 | width: 30%; 27 | text-align: center; 28 | } 29 | h1 { 30 | color: #fff; 31 | } 32 | img { 33 | width: 50%; 34 | border: 1px solid #fff; 35 | } 36 | 37 | @keyframes AnimateBG { 38 | 0%{background-position:0% 50%} 39 | 50%{background-position:100% 50%} 40 | 100%{background-position:0% 50%} 41 | } 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /amazon-vpc/create-nat-gateway.md: -------------------------------------------------------------------------------- 1 | # Create private subnets and NAT gateway 2 | 3 | ## Create a private subnet in us-east-1a 4 | aws ec2 create-subnet --vpc-id --cidr-block 172.31.96.0/20 --availability-zone us-east-1a --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-1a}]' 5 | ## Create a private subnet in us-east-1b 6 | aws ec2 create-subnet --vpc-id --cidr-block 172.31.112.0/20 --availability-zone us-east-1b --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-1b}]' 7 | ## Create a route table in the default VPC 8 | aws ec2 create-route-table --vpc-id --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=PrivateRT}]' 9 | ## Associate private subnets to the route table 10 | aws ec2 associate-route-table --route-table-id --subnet-id 11 | aws ec2 associate-route-table --route-table-id --subnet-id 12 | ## Create an Elastic IP 13 | aws ec2 allocate-address 14 | ## Create a NAT gateway 15 | aws ec2 create-nat-gateway --subnet-id --allocation-id 16 | ## Update the private route table to point to the NAT gateway 17 | aws ec2 create-route --route-table-id --destination-cidr-block 0.0.0.0/0 --nat-gateway-id 18 | 19 | # Launch EC2 instance 20 | 21 | 1. Create a security group 22 | aws ec2 create-security-group --group-name NAT-GW-LAB --description "Temporary SG for the NAT gateway Lab" 23 | 2. Launch instance in US-EAST-1A 24 | aws ec2 run-instances --image-id ami-005f9685cb30f234b --instance-type t2.micro --subnet-id --security-group-ids --iam-instance-profile Name=SSMInstanceProfile -------------------------------------------------------------------------------- /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 33 | 34 | ## Create NAT Gateway 35 | 36 | Name: MyNatGW 37 | Subnet: Public-1A -------------------------------------------------------------------------------- /amazon-vpc/vpc-peering-us-east-1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Description: A CloudFormation template to create a VPC with networking components, an EC2 instance, and a simple web page 4 | 5 | Resources: 6 | VPC: 7 | Type: AWS::EC2::VPC 8 | Properties: 9 | CidrBlock: 10.0.0.0/16 10 | EnableDnsHostnames: true 11 | EnableDnsSupport: true 12 | InstanceTenancy: default 13 | 14 | InternetGateway: 15 | Type: AWS::EC2::InternetGateway 16 | Properties: {} 17 | 18 | VPCGatewayAttachment: 19 | Type: AWS::EC2::VPCGatewayAttachment 20 | Properties: 21 | InternetGatewayId: !Ref InternetGateway 22 | VpcId: !Ref VPC 23 | 24 | PublicSubnet: 25 | Type: AWS::EC2::Subnet 26 | Properties: 27 | VpcId: !Ref VPC 28 | CidrBlock: 10.0.1.0/24 29 | AvailabilityZone: !Select [ 0, !GetAZs ] 30 | MapPublicIpOnLaunch: true 31 | 32 | RouteTable: 33 | Type: AWS::EC2::RouteTable 34 | Properties: 35 | VpcId: !Ref VPC 36 | 37 | Route: 38 | Type: AWS::EC2::Route 39 | Properties: 40 | RouteTableId: !Ref RouteTable 41 | DestinationCidrBlock: 0.0.0.0/0 42 | GatewayId: !Ref InternetGateway 43 | 44 | SubnetRouteTableAssociation: 45 | Type: AWS::EC2::SubnetRouteTableAssociation 46 | Properties: 47 | RouteTableId: !Ref RouteTable 48 | SubnetId: !Ref PublicSubnet 49 | 50 | SecurityGroup: 51 | Type: AWS::EC2::SecurityGroup 52 | Properties: 53 | GroupDescription: Allow all traffic from the internet 54 | VpcId: !Ref VPC 55 | SecurityGroupIngress: 56 | - IpProtocol: tcp 57 | FromPort: 80 58 | ToPort: 80 59 | CidrIp: 0.0.0.0/0 60 | - IpProtocol: tcp 61 | FromPort: 22 62 | ToPort: 22 63 | CidrIp: 0.0.0.0/0 64 | - IpProtocol: icmp 65 | FromPort: -1 66 | ToPort: -1 67 | CidrIp: 10.1.0.0/16 68 | 69 | EC2Instance: 70 | Type: AWS::EC2::Instance 71 | Properties: 72 | InstanceType: t2.micro 73 | ImageId: ami-006dcf34c09e50022 74 | SecurityGroupIds: 75 | - !Ref SecurityGroup 76 | SubnetId: !Ref PublicSubnet 77 | UserData: 78 | Fn::Base64: | 79 | #!/bin/bash 80 | yum update -y 81 | yum install -y httpd 82 | service httpd start 83 | chkconfig httpd on 84 | echo "Successful connection!

Successful connection!

" > /var/www/html/index.html 85 | 86 | 87 | Outputs: 88 | PublicIp: 89 | Description: The public IP address of the EC2 instance 90 | Value: !GetAtt EC2Instance.PublicIp 91 | -------------------------------------------------------------------------------- /amazon-vpc/vpc-peering-us-west-1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Description: A CloudFormation template to create a VPC with networking components, an EC2 instance, and a simple web page 4 | 5 | Resources: 6 | VPC: 7 | Type: AWS::EC2::VPC 8 | Properties: 9 | CidrBlock: 10.1.0.0/16 10 | EnableDnsHostnames: true 11 | EnableDnsSupport: true 12 | InstanceTenancy: default 13 | 14 | InternetGateway: 15 | Type: AWS::EC2::InternetGateway 16 | Properties: {} 17 | 18 | VPCGatewayAttachment: 19 | Type: AWS::EC2::VPCGatewayAttachment 20 | Properties: 21 | InternetGatewayId: !Ref InternetGateway 22 | VpcId: !Ref VPC 23 | 24 | PublicSubnet: 25 | Type: AWS::EC2::Subnet 26 | Properties: 27 | VpcId: !Ref VPC 28 | CidrBlock: 10.1.1.0/24 29 | AvailabilityZone: !Select [ 0, !GetAZs ] 30 | MapPublicIpOnLaunch: true 31 | 32 | RouteTable: 33 | Type: AWS::EC2::RouteTable 34 | Properties: 35 | VpcId: !Ref VPC 36 | 37 | Route: 38 | Type: AWS::EC2::Route 39 | Properties: 40 | RouteTableId: !Ref RouteTable 41 | DestinationCidrBlock: 0.0.0.0/0 42 | GatewayId: !Ref InternetGateway 43 | 44 | SubnetRouteTableAssociation: 45 | Type: AWS::EC2::SubnetRouteTableAssociation 46 | Properties: 47 | RouteTableId: !Ref RouteTable 48 | SubnetId: !Ref PublicSubnet 49 | 50 | SecurityGroup: 51 | Type: AWS::EC2::SecurityGroup 52 | Properties: 53 | GroupDescription: Allow all traffic from the internet 54 | VpcId: !Ref VPC 55 | SecurityGroupIngress: 56 | - IpProtocol: tcp 57 | FromPort: 80 58 | ToPort: 80 59 | CidrIp: 0.0.0.0/0 60 | - IpProtocol: tcp 61 | FromPort: 22 62 | ToPort: 22 63 | CidrIp: 0.0.0.0/0 64 | - IpProtocol: icmp 65 | FromPort: -1 66 | ToPort: -1 67 | CidrIp: 10.0.0.0/16 68 | 69 | EC2Instance: 70 | Type: AWS::EC2::Instance 71 | Properties: 72 | InstanceType: t2.micro 73 | ImageId: ami-0925fd223898ee5ba 74 | SecurityGroupIds: 75 | - !Ref SecurityGroup 76 | SubnetId: !Ref PublicSubnet 77 | UserData: 78 | Fn::Base64: | 79 | #!/bin/bash 80 | yum update -y 81 | yum install -y httpd 82 | service httpd start 83 | chkconfig httpd on 84 | echo "Successful connection!

Successful connection!

" > /var/www/html/index.html 85 | 86 | 87 | Outputs: 88 | PublicIp: 89 | Description: The public IP address of the EC2 instance 90 | Value: !GetAtt EC2Instance.PublicIp 91 | -------------------------------------------------------------------------------- /auto-scaling-and-elb/create-asg-alb-cli.md: -------------------------------------------------------------------------------- 1 | 2 | ## Create a security group 3 | 4 | aws ec2 create-security-group --group-name ALB-EC2-Access --description "Route 53 Policy Test" --region us-east-1 5 | 6 | aws ec2 authorize-security-group-ingress --group-name ALB-EC2-Access --protocol tcp --port 22 --cidr 0.0.0.0/0 --region us-east-1 7 | 8 | aws ec2 authorize-security-group-ingress --group-name ALB-EC2-Access --protocol tcp --port 80 --cidr 0.0.0.0/0 --region us-east-1 9 | 10 | ## create auto scaling group 11 | 12 | aws autoscaling create-auto-scaling-group --auto-scaling-group-name ASG1 --launch-template "LaunchTemplateName=LT1" --min-size 1 --max-size 3 --desired-capacity 2 --availability-zones "us-east-1a" "us-east-1b" --vpc-zone-identifier ", " 13 | 14 | ## create target group, load balancer, listener, and then link it all up 15 | 16 | aws elbv2 create-target-group --name TG1 --protocol HTTP --port 80 --vpc-id 17 | 18 | aws elbv2 create-load-balancer --name ALB1 --subnets --security-groups 19 | 20 | aws elbv2 create-listener --load-balancer-arn --protocol HTTP --port 80 --default-actions Type=forward,TargetGroupArn= 21 | 22 | aws autoscaling attach-load-balancer-target-groups --auto-scaling-group-name ASG1 --target-group-arns 23 | 24 | ## delete ASG and ALB 25 | 26 | aws elbv2 delete-load-balancer --load-balancer-arn 27 | 28 | aws autoscaling delete-auto-scaling-group --auto-scaling-group-name ASG1 --force-delete -------------------------------------------------------------------------------- /auto-scaling-and-elb/ec2-user-data-web-app.md: -------------------------------------------------------------------------------- 1 | # CODE UPDATED SO IT WORKS WITH AMAZON LINUX 2 AMI AND AMAZON LINUX 2023 2 | *** COPY CODE FROM LINES 4-11 *** 3 | 4 | #!/bin/bash 5 | yum update -y 6 | yum install -y httpd 7 | systemctl start httpd 8 | systemctl enable httpd 9 | 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) 10 | echo '

This Amazon EC2 instance is located in Availability Zone: AZID

' > /var/www/html/index.txt 11 | sed "s/AZID/$EC2AZ/" /var/www/html/index.txt > /var/www/html/index.html -------------------------------------------------------------------------------- /auto-scaling-and-elb/iam-permissions-policy-lambda.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": [ 7 | "sns:Publish" 8 | ], 9 | "Resource": "arn:aws:sns:us-east-1:821711655051:my-lifecycle-topic" 10 | }, 11 | { 12 | "Effect": "Allow", 13 | "Action": [ 14 | "ec2:CreateSnapshot", 15 | "ec2:DescribeInstances", 16 | "ec2:DescribeVolumes" 17 | ], 18 | "Resource": "*" 19 | }, 20 | { 21 | "Effect": "Allow", 22 | "Action": [ 23 | "logs:CreateLogGroup", 24 | "logs:CreateLogStream", 25 | "logs:PutLogEvents" 26 | ], 27 | "Resource": "arn:aws:logs:us-east-1:821711655051:*" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /auto-scaling-and-elb/lambda-lifecycle-action.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import json 3 | import logging 4 | 5 | logger = logging.getLogger() 6 | logger.setLevel(logging.INFO) 7 | 8 | def lambda_handler(event, context): 9 | logger.info('Received event: %s', event) 10 | 11 | # Parse the SNS message payload 12 | message = event['Records'][0]['Sns']['Message'] 13 | logger.info('Received message: %s', message) 14 | 15 | try: 16 | message_data = json.loads(message) 17 | except json.JSONDecodeError: 18 | logger.error('Unable to decode message payload') 19 | return 20 | 21 | instance_id = message_data['EC2InstanceId'] 22 | logger.info('Instance ID: %s', instance_id) 23 | 24 | # Create an EC2 resource and get the instance object 25 | ec2 = boto3.resource('ec2') 26 | instance = ec2.Instance(instance_id) 27 | 28 | # Get the instance's root EBS volume ID 29 | root_device = instance.block_device_mappings[0] 30 | volume_id = root_device['Ebs']['VolumeId'] 31 | logger.info('Volume ID: %s', volume_id) 32 | 33 | # Create a snapshot of the root EBS volume 34 | snapshot = ec2.create_snapshot(VolumeId=volume_id, Description='Auto Scaling Group snapshot') 35 | 36 | logger.info('Snapshot created: %s', snapshot.id) 37 | -------------------------------------------------------------------------------- /auto-scaling-and-elb/lifecycle-action.md: -------------------------------------------------------------------------------- 1 | 2 | 1. Create an SNS Topic 3 | 4 | aws sns create-topic --name my-lifecycle-topic 5 | 6 | 2. Create a lifecycle hook 7 | 8 | aws autoscaling put-lifecycle-hook --auto-scaling-group-name ASG1 --lifecycle-hook-name my-lifecycle-hook --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING --notification-target-arn --role-arn arn:aws:iam::821711655051:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling --heartbeat-timeout 300 9 | 10 | 3. Create a role that can be assumed by Lambda with the permissions in the iam-permissions-policy-lambda.json file 11 | 12 | 4. Create a Lambda function with the code in the lambda-lifecycle-action.py file 13 | 14 | 5. Subscribe the function to the topic 15 | 16 | aws sns subscribe --topic-arn --protocol lambda --notification-endpoint arn:aws:lambda:us-east-1:821711655051:function:lambda-lifecycle 17 | 18 | 6. Check that the trigger is present in Lambda, create if necessary 19 | 20 | 7. Test the lifecycle hook by terminating an EC2 instance (change the desired capacity to 0) 21 | 22 | -------------------------------------------------------------------------------- /aws-cloudformation/1 EC2Instance.yml: -------------------------------------------------------------------------------- 1 | Resources: 2 | MyEC2Instance: 3 | Type: AWS::EC2::Instance 4 | Properties: 5 | AvailabilityZone: us-east-1a 6 | ImageId: ami-006dcf34c09e50022 7 | InstanceType: t2.micro -------------------------------------------------------------------------------- /aws-cloudformation/2 EC2InstanceIP.yml: -------------------------------------------------------------------------------- 1 | Resources: 2 | MyEC2Instance: 3 | Type: AWS::EC2::Instance 4 | Properties: 5 | AvailabilityZone: us-east-1a 6 | ImageId: ami-006dcf34c09e50022 7 | InstanceType: t2.micro 8 | 9 | MyEIP: 10 | Type: AWS::EC2::EIP 11 | Properties: 12 | InstanceId: !Ref MyEC2Instance -------------------------------------------------------------------------------- /aws-cloudformation/3 EC2InstanceMappings.yml: -------------------------------------------------------------------------------- 1 | Mappings: 2 | InstanceMap: 3 | us-east-1: 4 | dev: t2.micro 5 | prod: m1.small 6 | us-west-1: 7 | dev: m1.small 8 | prod: m1.large 9 | AMIMap: 10 | us-east-1: 11 | dev: ami-006dcf34c09e50022 12 | prod: ami-006dcf34c09e50022 13 | us-west-1: 14 | dev: ami-060d3509162bcc386 15 | prod: ami-060d3509162bcc386 16 | Resources: 17 | MyEC2Instance: 18 | Type: AWS::EC2::Instance 19 | Properties: 20 | ImageId: !FindInMap [AMIMap, !Ref "AWS::Region", dev] 21 | InstanceType: !FindInMap [InstanceMap,!Ref "AWS::Region", dev] -------------------------------------------------------------------------------- /aws-cloudformation/4 EC2InstanceParameters.yml: -------------------------------------------------------------------------------- 1 | Mappings: 2 | InstanceMap: 3 | us-east-1: 4 | dev: t2.micro 5 | prod: m1.small 6 | us-west-1: 7 | dev: m1.small 8 | prod: m1.large 9 | AMIMap: 10 | us-east-1: 11 | dev: ami-006dcf34c09e50022 12 | prod: ami-006dcf34c09e50022 13 | us-west-1: 14 | dev: ami-060d3509162bcc386 15 | prod: ami-060d3509162bcc386 16 | Parameters: 17 | EnvironmentParameter: 18 | Type: String 19 | Default: dev 20 | AllowedValues: 21 | - dev 22 | - prod 23 | Description: Enter dev or prod. 24 | Resources: 25 | MyEC2Instance: 26 | Type: AWS::EC2::Instance 27 | Properties: 28 | ImageId: !FindInMap [AMIMap, !Ref "AWS::Region", Ref: EnvironmentParameter] 29 | InstanceType: !FindInMap [InstanceMap,!Ref "AWS::Region", Ref: EnvironmentParameter] -------------------------------------------------------------------------------- /aws-cloudformation/5 EC2InstanceIPandSG.yml: -------------------------------------------------------------------------------- 1 | Resources: 2 | MyEC2Instance: 3 | Type: AWS::EC2::Instance 4 | Properties: 5 | AvailabilityZone: us-east-1a 6 | ImageId: ami-006dcf34c09e50022 7 | InstanceType: t2.micro 8 | SecurityGroups: 9 | - !Ref MySecurityGroup 10 | 11 | MyEIP: 12 | Type: AWS::EC2::EIP 13 | Properties: 14 | InstanceId: !Ref MyEC2Instance 15 | 16 | MySecurityGroup: 17 | Type: AWS::EC2::SecurityGroup 18 | Properties: 19 | GroupDescription: Remote access on port 22 20 | SecurityGroupIngress: 21 | - CidrIp: 0.0.0.0/0 22 | FromPort: 22 23 | IpProtocol: tcp 24 | ToPort: 22 25 | -------------------------------------------------------------------------------- /aws-cloudformation/6 EC2InstanceWithUserData.yml: -------------------------------------------------------------------------------- 1 | Resources: 2 | MyEC2Instance: 3 | Type: AWS::EC2::Instance 4 | Properties: 5 | AvailabilityZone: us-east-1a 6 | ImageId: ami-006dcf34c09e50022 7 | InstanceType: t2.micro 8 | SecurityGroups: 9 | - !Ref MySecurityGroup 10 | UserData: 11 | Fn::Base64: | 12 | #!/bin/bash 13 | yum update -y 14 | yum install httpd -y 15 | systemctl start httpd 16 | systemctl enable httpd 17 | cd /var/www/html 18 | echo "This EC2 instance is running successfully!" > index.html 19 | 20 | MyEIP: 21 | Type: AWS::EC2::EIP 22 | Properties: 23 | InstanceId: !Ref MyEC2Instance 24 | 25 | MySecurityGroup: 26 | Type: AWS::EC2::SecurityGroup 27 | Properties: 28 | GroupDescription: SSH on Port 22 and Web on Port 80 29 | SecurityGroupIngress: 30 | - CidrIp: 0.0.0.0/0 31 | FromPort: 22 32 | IpProtocol: tcp 33 | ToPort: 22 34 | - CidrIp: 0.0.0.0/0 35 | FromPort: 80 36 | IpProtocol: tcp 37 | ToPort: 80 38 | 39 | 40 | -------------------------------------------------------------------------------- /aws-cloudformation/7 ELBWithLockedDownAutoScaledInstances.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion" : "2010-09-09", 3 | 4 | "Description" : "AWS CloudFormation Sample Template ELBWithLockedDownAutoScaledInstances: Create a load balanced, Auto Scaled sample website where the instances are locked down to only accept traffic from the load balancer. This example creates an Auto Scaling group behind a load balancer with a simple health check. The web site is available on port 80, however, the instances can be configured to listen on any port (8888 by default). **WARNING** This template creates one or more Amazon EC2 instances and an Application Load Balancer. You will be billed for the AWS resources used if you create a stack from this template.", 5 | 6 | "Parameters" : { 7 | "VpcId" : { 8 | "Type" : "AWS::EC2::VPC::Id", 9 | "Description" : "VpcId of your existing Virtual Private Cloud (VPC)", 10 | "ConstraintDescription" : "must be the VPC Id of an existing Virtual Private Cloud." 11 | }, 12 | 13 | "Subnets" : { 14 | "Type" : "List", 15 | "Description" : "The list of SubnetIds in your Virtual Private Cloud (VPC)", 16 | "ConstraintDescription" : "must be a list of at least two existing subnets associated with at least two different availability zones. They should be residing in the selected Virtual Private Cloud." 17 | }, 18 | 19 | "InstanceType" : { 20 | "Description" : "WebServer EC2 instance type", 21 | "Type" : "String", 22 | "Default" : "t2.small", 23 | "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge"] 24 | , 25 | "ConstraintDescription" : "must be a valid EC2 instance type." 26 | }, 27 | 28 | "KeyName" : { 29 | "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances", 30 | "Type" : "AWS::EC2::KeyPair::KeyName", 31 | "ConstraintDescription" : "must be the name of an existing EC2 KeyPair." 32 | }, 33 | 34 | "SSHLocation" : { 35 | "Description" : "The IP address range that can be used to SSH to the EC2 instances", 36 | "Type": "String", 37 | "MinLength": "9", 38 | "MaxLength": "18", 39 | "Default": "0.0.0.0/0", 40 | "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", 41 | "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." 42 | } 43 | }, 44 | 45 | "Mappings" : { 46 | "Region2Examples" : { 47 | "ap-east-1" : { "Examples" : "https://s3-ap-east-1.amazonaws.com/cloudformation-examples-ap-east-1" }, 48 | "ap-northeast-1" : { "Examples" : "https://s3-ap-northeast-1.amazonaws.com/cloudformation-examples-ap-northeast-1" }, 49 | "ap-northeast-2" : { "Examples" : "https://s3-ap-northeast-2.amazonaws.com/cloudformation-examples-ap-northeast-2" }, 50 | "ap-northeast-3" : { "Examples" : "https://s3-ap-northeast-3.amazonaws.com/cloudformation-examples-ap-northeast-3" }, 51 | "ap-south-1" : { "Examples" : "https://s3-ap-south-1.amazonaws.com/cloudformation-examples-ap-south-1" }, 52 | "ap-southeast-1" : { "Examples" : "https://s3-ap-southeast-1.amazonaws.com/cloudformation-examples-ap-southeast-1" }, 53 | "ap-southeast-2" : { "Examples" : "https://s3-ap-southeast-2.amazonaws.com/cloudformation-examples-ap-southeast-2" }, 54 | "ca-central-1" : { "Examples" : "https://s3-ca-central-1.amazonaws.com/cloudformation-examples-ca-central-1" }, 55 | "cn-north-1" : { "Examples" : "https://s3.cn-north-1.amazonaws.com.cn/cloudformation-examples-cn-north-1" }, 56 | "cn-northwest-1" : { "Examples" : "https://s3.cn-northwest-1.amazonaws.com.cn/cloudformation-examples-cn-northwest-1" }, 57 | "eu-central-1" : { "Examples" : "https://s3-eu-central-1.amazonaws.com/cloudformation-examples-eu-central-1" }, 58 | "eu-north-1" : { "Examples" : "https://s3-eu-north-1.amazonaws.com/cloudformation-examples-eu-north-1" }, 59 | "eu-west-1" : { "Examples" : "https://s3-eu-west-1.amazonaws.com/cloudformation-examples-eu-west-1" }, 60 | "eu-west-2" : { "Examples" : "https://s3-eu-west-2.amazonaws.com/cloudformation-examples-eu-west-2" }, 61 | "eu-west-3" : { "Examples" : "https://s3-eu-west-3.amazonaws.com/cloudformation-examples-eu-west-3" }, 62 | "me-south-1" : { "Examples" : "https://s3-me-south-1.amazonaws.com/cloudformation-examples-me-south-1" }, 63 | "sa-east-1" : { "Examples" : "https://s3-sa-east-1.amazonaws.com/cloudformation-examples-sa-east-1" }, 64 | "us-east-1" : { "Examples" : "https://s3.amazonaws.com/cloudformation-examples-us-east-1" }, 65 | "us-east-2" : { "Examples" : "https://s3-us-east-2.amazonaws.com/cloudformation-examples-us-east-2" }, 66 | "us-west-1" : { "Examples" : "https://s3-us-west-1.amazonaws.com/cloudformation-examples-us-west-1" }, 67 | "us-west-2" : { "Examples" : "https://s3-us-west-2.amazonaws.com/cloudformation-examples-us-west-2" } 68 | } 69 | , 70 | "AWSInstanceType2Arch" : { 71 | "t1.micro" : { "Arch" : "HVM64" }, 72 | "t2.nano" : { "Arch" : "HVM64" }, 73 | "t2.micro" : { "Arch" : "HVM64" }, 74 | "t2.small" : { "Arch" : "HVM64" }, 75 | "t2.medium" : { "Arch" : "HVM64" }, 76 | "t2.large" : { "Arch" : "HVM64" }, 77 | "m1.small" : { "Arch" : "HVM64" }, 78 | "m1.medium" : { "Arch" : "HVM64" }, 79 | "m1.large" : { "Arch" : "HVM64" }, 80 | "m1.xlarge" : { "Arch" : "HVM64" }, 81 | "m2.xlarge" : { "Arch" : "HVM64" }, 82 | "m2.2xlarge" : { "Arch" : "HVM64" }, 83 | "m2.4xlarge" : { "Arch" : "HVM64" }, 84 | "m3.medium" : { "Arch" : "HVM64" }, 85 | "m3.large" : { "Arch" : "HVM64" }, 86 | "m3.xlarge" : { "Arch" : "HVM64" }, 87 | "m3.2xlarge" : { "Arch" : "HVM64" }, 88 | "m4.large" : { "Arch" : "HVM64" }, 89 | "m4.xlarge" : { "Arch" : "HVM64" }, 90 | "m4.2xlarge" : { "Arch" : "HVM64" }, 91 | "m4.4xlarge" : { "Arch" : "HVM64" }, 92 | "m4.10xlarge" : { "Arch" : "HVM64" }, 93 | "c1.medium" : { "Arch" : "HVM64" }, 94 | "c1.xlarge" : { "Arch" : "HVM64" }, 95 | "c3.large" : { "Arch" : "HVM64" }, 96 | "c3.xlarge" : { "Arch" : "HVM64" }, 97 | "c3.2xlarge" : { "Arch" : "HVM64" }, 98 | "c3.4xlarge" : { "Arch" : "HVM64" }, 99 | "c3.8xlarge" : { "Arch" : "HVM64" }, 100 | "c4.large" : { "Arch" : "HVM64" }, 101 | "c4.xlarge" : { "Arch" : "HVM64" }, 102 | "c4.2xlarge" : { "Arch" : "HVM64" }, 103 | "c4.4xlarge" : { "Arch" : "HVM64" }, 104 | "c4.8xlarge" : { "Arch" : "HVM64" }, 105 | "g2.2xlarge" : { "Arch" : "HVMG2" }, 106 | "g2.8xlarge" : { "Arch" : "HVMG2" }, 107 | "r3.large" : { "Arch" : "HVM64" }, 108 | "r3.xlarge" : { "Arch" : "HVM64" }, 109 | "r3.2xlarge" : { "Arch" : "HVM64" }, 110 | "r3.4xlarge" : { "Arch" : "HVM64" }, 111 | "r3.8xlarge" : { "Arch" : "HVM64" }, 112 | "i2.xlarge" : { "Arch" : "HVM64" }, 113 | "i2.2xlarge" : { "Arch" : "HVM64" }, 114 | "i2.4xlarge" : { "Arch" : "HVM64" }, 115 | "i2.8xlarge" : { "Arch" : "HVM64" }, 116 | "d2.xlarge" : { "Arch" : "HVM64" }, 117 | "d2.2xlarge" : { "Arch" : "HVM64" }, 118 | "d2.4xlarge" : { "Arch" : "HVM64" }, 119 | "d2.8xlarge" : { "Arch" : "HVM64" }, 120 | "hi1.4xlarge" : { "Arch" : "HVM64" }, 121 | "hs1.8xlarge" : { "Arch" : "HVM64" }, 122 | "cr1.8xlarge" : { "Arch" : "HVM64" }, 123 | "cc2.8xlarge" : { "Arch" : "HVM64" } 124 | }, 125 | 126 | "AWSInstanceType2NATArch" : { 127 | "t1.micro" : { "Arch" : "NATHVM64" }, 128 | "t2.nano" : { "Arch" : "NATHVM64" }, 129 | "t2.micro" : { "Arch" : "NATHVM64" }, 130 | "t2.small" : { "Arch" : "NATHVM64" }, 131 | "t2.medium" : { "Arch" : "NATHVM64" }, 132 | "t2.large" : { "Arch" : "NATHVM64" }, 133 | "m1.small" : { "Arch" : "NATHVM64" }, 134 | "m1.medium" : { "Arch" : "NATHVM64" }, 135 | "m1.large" : { "Arch" : "NATHVM64" }, 136 | "m1.xlarge" : { "Arch" : "NATHVM64" }, 137 | "m2.xlarge" : { "Arch" : "NATHVM64" }, 138 | "m2.2xlarge" : { "Arch" : "NATHVM64" }, 139 | "m2.4xlarge" : { "Arch" : "NATHVM64" }, 140 | "m3.medium" : { "Arch" : "NATHVM64" }, 141 | "m3.large" : { "Arch" : "NATHVM64" }, 142 | "m3.xlarge" : { "Arch" : "NATHVM64" }, 143 | "m3.2xlarge" : { "Arch" : "NATHVM64" }, 144 | "m4.large" : { "Arch" : "NATHVM64" }, 145 | "m4.xlarge" : { "Arch" : "NATHVM64" }, 146 | "m4.2xlarge" : { "Arch" : "NATHVM64" }, 147 | "m4.4xlarge" : { "Arch" : "NATHVM64" }, 148 | "m4.10xlarge" : { "Arch" : "NATHVM64" }, 149 | "c1.medium" : { "Arch" : "NATHVM64" }, 150 | "c1.xlarge" : { "Arch" : "NATHVM64" }, 151 | "c3.large" : { "Arch" : "NATHVM64" }, 152 | "c3.xlarge" : { "Arch" : "NATHVM64" }, 153 | "c3.2xlarge" : { "Arch" : "NATHVM64" }, 154 | "c3.4xlarge" : { "Arch" : "NATHVM64" }, 155 | "c3.8xlarge" : { "Arch" : "NATHVM64" }, 156 | "c4.large" : { "Arch" : "NATHVM64" }, 157 | "c4.xlarge" : { "Arch" : "NATHVM64" }, 158 | "c4.2xlarge" : { "Arch" : "NATHVM64" }, 159 | "c4.4xlarge" : { "Arch" : "NATHVM64" }, 160 | "c4.8xlarge" : { "Arch" : "NATHVM64" }, 161 | "g2.2xlarge" : { "Arch" : "NATHVMG2" }, 162 | "g2.8xlarge" : { "Arch" : "NATHVMG2" }, 163 | "r3.large" : { "Arch" : "NATHVM64" }, 164 | "r3.xlarge" : { "Arch" : "NATHVM64" }, 165 | "r3.2xlarge" : { "Arch" : "NATHVM64" }, 166 | "r3.4xlarge" : { "Arch" : "NATHVM64" }, 167 | "r3.8xlarge" : { "Arch" : "NATHVM64" }, 168 | "i2.xlarge" : { "Arch" : "NATHVM64" }, 169 | "i2.2xlarge" : { "Arch" : "NATHVM64" }, 170 | "i2.4xlarge" : { "Arch" : "NATHVM64" }, 171 | "i2.8xlarge" : { "Arch" : "NATHVM64" }, 172 | "d2.xlarge" : { "Arch" : "NATHVM64" }, 173 | "d2.2xlarge" : { "Arch" : "NATHVM64" }, 174 | "d2.4xlarge" : { "Arch" : "NATHVM64" }, 175 | "d2.8xlarge" : { "Arch" : "NATHVM64" }, 176 | "hi1.4xlarge" : { "Arch" : "NATHVM64" }, 177 | "hs1.8xlarge" : { "Arch" : "NATHVM64" }, 178 | "cr1.8xlarge" : { "Arch" : "NATHVM64" }, 179 | "cc2.8xlarge" : { "Arch" : "NATHVM64" } 180 | } 181 | , 182 | "AWSRegionArch2AMI" : { 183 | "af-south-1" : {"HVM64" : "ami-064cc455f8a1ef504", "HVMG2" : "NOT_SUPPORTED"}, 184 | "ap-east-1" : {"HVM64" : "ami-f85b1989", "HVMG2" : "NOT_SUPPORTED"}, 185 | "ap-northeast-1" : {"HVM64" : "ami-0b2c2a754d5b4da22", "HVMG2" : "ami-09d0e0e099ecabba2"}, 186 | "ap-northeast-2" : {"HVM64" : "ami-0493ab99920f410fc", "HVMG2" : "NOT_SUPPORTED"}, 187 | "ap-northeast-3" : {"HVM64" : "ami-01344f6f63a4decc1", "HVMG2" : "NOT_SUPPORTED"}, 188 | "ap-south-1" : {"HVM64" : "ami-03cfb5e1fb4fac428", "HVMG2" : "ami-0244c1d42815af84a"}, 189 | "ap-southeast-1" : {"HVM64" : "ami-0ba35dc9caf73d1c7", "HVMG2" : "ami-0e46ce0d6a87dc979"}, 190 | "ap-southeast-2" : {"HVM64" : "ami-0ae99b503e8694028", "HVMG2" : "ami-0c0ab057a101d8ff2"}, 191 | "ca-central-1" : {"HVM64" : "ami-0803e21a2ec22f953", "HVMG2" : "NOT_SUPPORTED"}, 192 | "cn-north-1" : {"HVM64" : "ami-07a3f215cc90c889c", "HVMG2" : "NOT_SUPPORTED"}, 193 | "cn-northwest-1" : {"HVM64" : "ami-0a3b3b10f714a0ff4", "HVMG2" : "NOT_SUPPORTED"}, 194 | "eu-central-1" : {"HVM64" : "ami-0474863011a7d1541", "HVMG2" : "ami-0aa1822e3eb913a11"}, 195 | "eu-north-1" : {"HVM64" : "ami-0de4b8910494dba0f", "HVMG2" : "ami-32d55b4c"}, 196 | "eu-south-1" : {"HVM64" : "ami-08427144fe9ebdef6", "HVMG2" : "NOT_SUPPORTED"}, 197 | "eu-west-1" : {"HVM64" : "ami-015232c01a82b847b", "HVMG2" : "ami-0d5299b1c6112c3c7"}, 198 | "eu-west-2" : {"HVM64" : "ami-0765d48d7e15beb93", "HVMG2" : "NOT_SUPPORTED"}, 199 | "eu-west-3" : {"HVM64" : "ami-0caf07637eda19d9c", "HVMG2" : "NOT_SUPPORTED"}, 200 | "me-south-1" : {"HVM64" : "ami-0744743d80915b497", "HVMG2" : "NOT_SUPPORTED"}, 201 | "sa-east-1" : {"HVM64" : "ami-0a52e8a6018e92bb0", "HVMG2" : "NOT_SUPPORTED"}, 202 | "us-east-1" : {"HVM64" : "ami-032930428bf1abbff", "HVMG2" : "ami-0aeb704d503081ea6"}, 203 | "us-east-2" : {"HVM64" : "ami-027cab9a7bf0155df", "HVMG2" : "NOT_SUPPORTED"}, 204 | "us-west-1" : {"HVM64" : "ami-088c153f74339f34c", "HVMG2" : "ami-0a7fc72dc0e51aa77"}, 205 | "us-west-2" : {"HVM64" : "ami-01fee56b22f308154", "HVMG2" : "ami-0fe84a5b4563d8f27"} 206 | } 207 | 208 | }, 209 | 210 | "Resources" : { 211 | "WebServerGroup" : { 212 | "Type" : "AWS::AutoScaling::AutoScalingGroup", 213 | "Properties" : { 214 | "VPCZoneIdentifier" : { "Ref" : "Subnets" }, 215 | "LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, 216 | "MinSize" : "2", 217 | "MaxSize" : "2", 218 | "TargetGroupARNs" : [ { "Ref" : "ALBTargetGroup" } ] 219 | }, 220 | "CreationPolicy" : { 221 | "ResourceSignal" : { 222 | "Timeout" : "PT15M" 223 | } 224 | }, 225 | "UpdatePolicy": { 226 | "AutoScalingRollingUpdate": { 227 | "MinInstancesInService": "1", 228 | "MaxBatchSize": "1", 229 | "PauseTime" : "PT15M", 230 | "WaitOnResourceSignals": "true" 231 | } 232 | } 233 | }, 234 | 235 | "LaunchConfig" : { 236 | "Type" : "AWS::AutoScaling::LaunchConfiguration", 237 | "Metadata" : { 238 | "Comment" : "Install a simple application", 239 | "AWS::CloudFormation::Init" : { 240 | "config" : { 241 | "packages" : { 242 | "yum" : { 243 | "httpd" : [] 244 | } 245 | }, 246 | 247 | "files" : { 248 | "/var/www/html/index.html" : { 249 | "content" : { "Fn::Join" : ["\n", [ 250 | "\"AWS", 251 | "

Congratulations, you have successfully launched the AWS CloudFormation sample.

" 252 | ]]}, 253 | "mode" : "000644", 254 | "owner" : "root", 255 | "group" : "root" 256 | }, 257 | 258 | "/etc/cfn/cfn-hup.conf" : { 259 | "content" : { "Fn::Join" : ["", [ 260 | "[main]\n", 261 | "stack=", { "Ref" : "AWS::StackId" }, "\n", 262 | "region=", { "Ref" : "AWS::Region" }, "\n" 263 | ]]}, 264 | "mode" : "000400", 265 | "owner" : "root", 266 | "group" : "root" 267 | }, 268 | 269 | "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { 270 | "content": { "Fn::Join" : ["", [ 271 | "[cfn-auto-reloader-hook]\n", 272 | "triggers=post.update\n", 273 | "path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n", 274 | "action=/opt/aws/bin/cfn-init -v ", 275 | " --stack ", { "Ref" : "AWS::StackName" }, 276 | " --resource LaunchConfig ", 277 | " --region ", { "Ref" : "AWS::Region" }, "\n", 278 | "runas=root\n" 279 | ]]}, 280 | "mode" : "000400", 281 | "owner" : "root", 282 | "group" : "root" 283 | } 284 | }, 285 | 286 | "services" : { 287 | "sysvinit" : { 288 | "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, 289 | "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", 290 | "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} 291 | } 292 | } 293 | } 294 | } 295 | }, 296 | "Properties" : { 297 | "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, 298 | { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, 299 | "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ], 300 | "InstanceType" : { "Ref" : "InstanceType" }, 301 | "KeyName" : { "Ref" : "KeyName" }, 302 | "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ 303 | "#!/bin/bash -xe\n", 304 | "yum update -y aws-cfn-bootstrap\n", 305 | 306 | "/opt/aws/bin/cfn-init -v ", 307 | " --stack ", { "Ref" : "AWS::StackName" }, 308 | " --resource LaunchConfig ", 309 | " --region ", { "Ref" : "AWS::Region" }, "\n", 310 | 311 | "/opt/aws/bin/cfn-signal -e $? ", 312 | " --stack ", { "Ref" : "AWS::StackName" }, 313 | " --resource WebServerGroup ", 314 | " --region ", { "Ref" : "AWS::Region" }, "\n" 315 | ]]}} 316 | } 317 | }, 318 | 319 | "ApplicationLoadBalancer" : { 320 | "Type" : "AWS::ElasticLoadBalancingV2::LoadBalancer", 321 | "Properties" : { 322 | "Subnets" : { "Ref" : "Subnets"} 323 | } 324 | }, 325 | 326 | "ALBListener" : { 327 | "Type" : "AWS::ElasticLoadBalancingV2::Listener", 328 | "Properties" : { 329 | "DefaultActions" : [{ 330 | "Type" : "forward", 331 | "TargetGroupArn" : { "Ref" : "ALBTargetGroup" } 332 | }], 333 | "LoadBalancerArn" : { "Ref" : "ApplicationLoadBalancer" }, 334 | "Port" : "80", 335 | "Protocol" : "HTTP" 336 | } 337 | }, 338 | 339 | "ALBTargetGroup" : { 340 | "Type" : "AWS::ElasticLoadBalancingV2::TargetGroup", 341 | "Properties" : { 342 | "HealthCheckIntervalSeconds" : 30, 343 | "HealthCheckTimeoutSeconds" : 5, 344 | "HealthyThresholdCount" : 3, 345 | "Port" : 80, 346 | "Protocol" : "HTTP", 347 | "UnhealthyThresholdCount" : 5, 348 | "VpcId" : {"Ref" : "VpcId"} 349 | } 350 | }, 351 | 352 | "InstanceSecurityGroup" : { 353 | "Type" : "AWS::EC2::SecurityGroup", 354 | "Properties" : { 355 | "GroupDescription" : "Enable SSH access and HTTP access on the inbound port", 356 | "SecurityGroupIngress" : [ { 357 | "IpProtocol" : "tcp", 358 | "FromPort" : "80", 359 | "ToPort" : "80", 360 | "SourceSecurityGroupId" : {"Fn::Select" : [0, {"Fn::GetAtt" : ["ApplicationLoadBalancer", "SecurityGroups"]}]} 361 | },{ 362 | "IpProtocol" : "tcp", 363 | "FromPort" : "22", 364 | "ToPort" : "22", 365 | "CidrIp" : { "Ref" : "SSHLocation"} 366 | } ], 367 | "VpcId" : { "Ref" : "VpcId" } 368 | } 369 | } 370 | }, 371 | 372 | "Outputs" : { 373 | "URL" : { 374 | "Description" : "URL of the website", 375 | "Value" : { "Fn::Join" : [ "", [ "http://", { "Fn::GetAtt" : [ "ApplicationLoadBalancer", "DNSName" ]}]]} 376 | } 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /aws-elastic-beanstalk/nodejs.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nealdct/aws-soa-code/3127a703b6811b15046ec211f04cc0e56e86ad95/aws-elastic-beanstalk/nodejs.zip -------------------------------------------------------------------------------- /aws-fundamentals/launching-ec2-and-ebs.md: -------------------------------------------------------------------------------- 1 | ## Launch EC2 instance 2 | 1. Create a security group 3 | aws ec2 create-security-group --group-name EC2-EBS-Lab --description "Temporary SG for the EC2 and EBS Lab" 4 | 2. Add a rule for SSH inbound to the security group 5 | aws ec2 authorize-security-group-ingress --group-name EC2-EBS-Lab --protocol tcp --port 22 --cidr 0.0.0.0/0 6 | 3. Launch instance in US-EAST-1A 7 | aws ec2 run-instances --image-id ami-0dfcb1ef8550277af --instance-type t2.micro --placement AvailabilityZone=us-east-1a --security-group-ids sg-xxxxxxxxxxxxxx 8 | 9 | ## Create and Attach an EBS Volume 10 | 1. Create a 10GB gp2 volume in us-east-1a with a name tag of 'test-volume-1' 11 | 2. List non-loopback block devices on instance 12 | sudo lsblk -e7 13 | 3. Attach the volume to the instance in us-east-1a 14 | 4. Rerun the command to view block devices 15 | 16 | ## Create a filesystem and mount the volume 17 | 1. Create a filesystem on the EBS volume 18 | sudo mkfs -t ext4 /dev/xvdf 19 | 2. Create a mount point for the EBS volume 20 | sudo mkdir /data 21 | 3. Mount the EBS volume to the mount point 22 | sudo mount /dev/xvdf /data 23 | 4. Make the volume mount persistent 24 | Run: 'sudo nano /etc/fstab' then add '/dev/xvdf /data ext4 defaults,nofail 0 2' and save the file -------------------------------------------------------------------------------- /aws-fundamentals/working-with-files-on-efs.md: -------------------------------------------------------------------------------- 1 | # Working with Files on EFS 2 | 3 | ## Launch EC2 instances 4 | 1. Create a security group 5 | aws ec2 create-security-group --group-name EFS-Lab --description "Temporary SG for the EC2 and EBS Lab" 6 | 2. Add a rule for SSH inbound to the security group 7 | aws ec2 authorize-security-group-ingress --group-name EFS-Lab --protocol tcp --port 22 --cidr 0.0.0.0/0 8 | 3. Add rule to the security group to allow the NFS protocol from group members 9 | aws ec2 authorize-security-group-ingress --group-id sg-xxxxxxxxxxxxxxxxx --protocol tcp --port 2049 --source-group sg-xxxxxxxxxxxxxxxxx 10 | 4. Launch instance in US-EAST-1A 11 | aws ec2 run-instances --image-id ami-0dfcb1ef8550277af --instance-type t2.micro --placement AvailabilityZone=us-east-1a --security-group-ids sg-xxxxxxxxxxxxxx 12 | 5. Launch instance in US-EAST-1B 13 | aws ec2 run-instances --image-id ami-0dfcb1ef8550277af --instance-type t2.micro --placement AvailabilityZone=us-east-1b --security-group-ids sg-xxxxxxxxxxxxxx 14 | 15 | ## Create an EFS File System 16 | 1. Create an EFS file system (console, and add the EFS-Lab security group to the mount targets for each AZ 17 | 18 | ## Mount using the NFS Client (perform steps on both instances) 19 | 1. Create an EFS mount point 20 | mkdir ~/efs-mount-point 21 | 2. Install NFS client 22 | sudo yum -y install nfs-utils 23 | 3. Mount using the EFS client 24 | sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-023adf2979936b0be.efs.us-east-1.amazonaws.com:/ ~/efs-mount-point 25 | 4. Create a file on the file system 26 | 5. Add a file system policy to enforce encryption in-transit 27 | 6. Unmount (make sure to change directory out of efs-mount-point first) 28 | sudo umount ~/efs-mount-point 29 | 4. Mount again using the EFS client (what happens?) 30 | 31 | ## Mount using the EFS utils (perform steps on both instances) 32 | 1. Install EFS utils 33 | sudo yum install -y amazon-efs-utils 34 | 2. Mount using the EFS mount helper 35 | sudo mount -t efs -o tls fs-023adf2979936b0be.efs.us-east-1.amazonaws.com:/ ~/efs-mount-point -------------------------------------------------------------------------------- /aws-fundamentals/working-with-objects-on-s3.md: -------------------------------------------------------------------------------- 1 | # Working with Objects on S3 2 | 3 | 1. Upload object using the s3api (change bucket and path) 4 | aws s3api put-object --bucket my-bucket --key my-object-key --body /path/to/local/file 5 | 2. Download an object using the s3api (change bucket and path) 6 | aws s3api get-object --bucket my-bucket --key my-object-key /path/to/local/file 7 | 3. Use curl with a presigned URL to download an object (change bucket, path, and object) 8 | curl -o /path/to/local/file "$(aws s3 presign s3://my-bucket/my-object-key --expires-in 3600)" -------------------------------------------------------------------------------- /aws-iam/aws-cli-with-mfa.md: -------------------------------------------------------------------------------- 1 | # Run the following commands 2 | 3 | aws sts get-session-token --serial-number arn:aws:iam:::mfa/ --token-code 4 | 5 | ## Use 'set' rather than 'export' for Windows 6 | 7 | export AWS_ACCESS_KEY_ID= 8 | export AWS_SECRET_ACCESS_KEY= 9 | export AWS_SESSION_TOKEN= 10 | 11 | unset AWS_ACCESS_KEY_ID 12 | unset AWS_SECRET_ACCESS_KEY 13 | unset AWS_SESSION_TOKEN 14 | 15 | -------------------------------------------------------------------------------- /aws-iam/cross-account-role.md: -------------------------------------------------------------------------------- 1 | # Create a role in the target account 2 | 3 | 1. Select 'another account' as the trusted entity 4 | 2. Enter the account ID and check the 'Require external ID' checkbox 5 | 3. Enter the external ID 6 | 4. Attach the following policy to the role: 7 | 8 | { 9 | "Version": "2012-10-17", 10 | "Statement": [ 11 | { 12 | "Sid": "AllowBucketAccess", 13 | "Effect": "Allow", 14 | "Action": [ 15 | "s3:GetObject", 16 | "s3:PutObject", 17 | "s3:ListBucket" 18 | ], 19 | "Resource": [ 20 | "arn:aws:s3:::", 21 | "arn:aws:s3:::/*" 22 | ] 23 | } 24 | ] 25 | } 26 | 27 | # Assume the role in the target account 28 | 29 | 1. Run the following command to assume the role using the CLI 30 | 31 | aws sts assume-role --role-arn arn:aws:iam:::role/ --role-session-name mysession --external-id 32 | 33 | 2. Configure the credentials 34 | 35 | aws configure set aws_access_key_id --profile target-account 36 | aws configure set aws_secret_access_key --profile target-account 37 | aws configure set aws_session_token --profile target-account 38 | 39 | 3. Run CLI commands against the bucket 40 | 41 | aws s3 ls s3:// --profile target-account 42 | -------------------------------------------------------------------------------- /aws-organizations/create-organization-scp.md: -------------------------------------------------------------------------------- 1 | # Create SCP for Restricting EC2 Instance Types 2 | 3 | 1. In AWS Organizations, enable Service Control Policies (SCPs) 4 | 2. Create a policy called "RequireT2Micro" 5 | 3. Enter the following JSON code: 6 | 7 | ***Code for the SCP*** 8 | 9 | { 10 | "Version": "2012-10-17", 11 | "Statement": [ 12 | { 13 | "Sid": "RequireMicroInstanceType", 14 | "Effect": "Deny", 15 | "Action": "ec2:RunInstances", 16 | "Resource": "arn:aws:ec2:*:*:instance/*", 17 | "Condition": { 18 | "StringNotEquals":{ 19 | "ec2:InstanceType":"t2.micro" 20 | } 21 | } 22 | } 23 | ] 24 | } 25 | 26 | 4. Attach the SCP to the OU that contains the dev account (OU1) 27 | 5. Switch roles to administer the dev account 28 | 29 | ## Switch role using: 30 | Account number of the dev account 31 | Role: OrganizationAccountAccess 32 | 33 | 6. In Amazon EC2 attempt to launch a t2.micro instance. It should work 34 | 7. Next, attempt to launch any other EC2 instance type. It should fail 35 | 8. Switch back to the management account, and attach the SCP to the Root OU 36 | 9. Attempt to launch a t2.medium instance. What happens? 37 | -------------------------------------------------------------------------------- /aws-secrets-manager/retrieve-secret-lambda-code.js: -------------------------------------------------------------------------------- 1 | const AWS = require('aws-sdk'); 2 | const client = new AWS.SecretsManager(); 3 | 4 | exports.handler = async (event, context) => { 5 | try { 6 | const secretName = 'prod/sample-db'; // replace with your secret name 7 | const data = await client.getSecretValue({ SecretId: secretName }).promise(); 8 | const secret = data.SecretString; 9 | 10 | console.log(secret); // Output the secret value to CloudWatch logs 11 | 12 | return { 13 | statusCode: 200, 14 | body: 'Successfully retrieved secret', 15 | }; 16 | } catch (err) { 17 | console.error(err); 18 | return { 19 | statusCode: 500, 20 | body: 'Error retrieving secret', 21 | }; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ssm-automation-and-config/automation-iam-role.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": [ 7 | "ec2:RevokeSecurityGroupIngress" 8 | ], 9 | "Resource": "*" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /ssm-automation-and-config/config-rule-and-remediation.md: -------------------------------------------------------------------------------- 1 | # Create an AWS Config rule and remediation - removes any SG rules that have 0.0.0.0/0 as a source unless they use TCP port 80 2 | 3 | 1. Create an IAM role with a custom trust policy for Systems Manager and add the 'AmazonSSMAutomationRole' policy 4 | 2. Add an inline policy to the role with the JSON from the 'automation-iam-role.json' document 5 | 3. Create a config rule using the 'pc-sg-open-only-to-authorized-ports' managed rule 6 | 4. Add port 80 next to 'authorizedTcpPorts' 7 | 5. Add a remediation rule using the automatic action 'AWS-DisablePublicAccessForSecurityGroup' 8 | 6. For Resource ID parameter specify 'GroupId' 9 | 7. For IpAddressToBlock specify '0.0.0.0/0' 10 | 8. For AutomationAssumeRole specify the ARN of the role created earlier --------------------------------------------------------------------------------