In the spirit of the CKAD exercises this is a todo list of tasks - and the example source used to accomplish those tasks - that I worked through when studying for the AWS Certified SysOps Administrator Associate exam.
The overall objective is to stand-up an off the shelf web app (Drupal), with a stereotypical ALB ⇨ EC2 ⇨ RDS / EFS architecture, using only CloudFormation, along with some nice to haves (CloudWatch monitoring, logs exported to CloudTrail, VPC security, etc).
If you work through these tasks then you should have practical hands on exposure to most of the technologies and services covered by the exam (noticeably missing are e.g. Organizations, Guard Duty, Direct Connect, Snowball, Storage Gateway, anything to do with VPN's). Beyond that you'll need to know some theory, for which I recommend the acloud.guru AWS Certified SysOps Administrator course. You can pass the exam with just the theory but getting hands on will ensure you actually learn it all above just passing the exam.
The code in this repository should not be taken as a template for standing up a best practices application and infrastructure. I've cheaped out on various components just because it's my credit card on the account. I've put the whole thing in a single CloudFormation stack just because it makes it easier to stand up and tear down each night. In some places the infrastructure is more complicated than it needs to be just so that I could play more with a given service. Here be dragons!
- Create initial stack, update stack:
aws cloudformation deploy --template-file drupal.yaml --stack-name mydrupalstack --parameter-overrides KeyName=MyKeyPair MyHomeCIDR=203.0.113.123/24 DatabaseMasterPassword=my53cr37p455w0rd LogsBucketName=mys3logsbucket MyMobilePhoneNumber=+61412345678 --capabilities CAPABILITY_NAMED_IAM - Connect to a given webserver:
ssh-add $env:userprofile\.ssh\MyKeyPair.pemssh -A ec2-user@$env:bastion_ipssh $drupal_ip
- Install Drupal:
bash /tmp/install.cmd(would be nice to automate this...) - Delete stack and all of its resources:
aws cloudformation delete-stack --stack-name mydrupalstack
- CloudTrail logs saved to S3
- Config snapshots saved to S3
- Custom VPC
- DMZ (public subnets): ELB, bastion, NAT
- Internal (private subnets): web servers, RDS
- HTTPS access to the ELB
- SSH access to the bastion, only from your home IP
- SSH access to the web servers, only from the bastion
- HTTP access to the web servers, only from the ELB
- MySQL access to RDS, only from the web servers
- NAT instance to allow the EC2 servers to connect out for e.g. Yum updates (NAT instances are much cheaper than gateways...)
- Registered domain name for the ELB
- Elastic IP for the bastion
- EC2 bastion host
- Route AWS traffic internally with a VPC endpoint
- EC2 web servers (Drupal)
- Autoscaling
- Minimum 3 instances, spread across 3 availability zones
- Self configured on launch
- RDS MySQL
- ELB
- Uploads stored in EFS
- Sensitive parameters stored in Parameter Store
- ELB logs saved to S3
- All resources tagged and displayed within a resource group (manually)
- CloudWatch dashboard (manually)
- baseline monitoring
- Plus disk and memory usage custom metrics
- With dimensions to allow easily filtering metrics to just the webservers
- Ship Apache logs to CloudWatch logs
- Alarm on unexpectedly high billing (manually)
- Alarm on zero healthy hosts
- ACM certificate provisioned on the ELB
- Compliance check on worldwide port 22 access
- Basic WAF
- Encryption in transit to RDS
- RDS encrypted at rest
- NACL per VPC recommended NACL rules
- Read replicas for RDS
- ElastiCache cluster to cache database queries
- Autoscale target group
- Use lifecycle hooks to only bring instances into service once everything is running
- CloudFront CDN
- Static asset (e.g. images, CSS, JS) caching with a high TTL
- Dynamic asset (e.g. webpage) caching with a low TTL
- Multi-AZ RDS
- Failover (via Route 53) to a static page in S3 if ELB unhealthy
- Event and notification on RDS failover to secondary
- Automated backups for RDS
- Turn on MFA delete and versioning for logs bucket
- Use NAT gateway if prod
- Bastion HA if prod (https://aws.amazon.com/quickstart/architecture/linux-bastion/)
- Apply stack via AWS CLI
- Export CloudWatch logs to S3
- Query logs with Athena
- Install AWS Inspector via SSM and run an assessment