Infrastructure as Code using AWS CloudFormation and ECS Clusters — Step 10
This story is part of a series “Initial Commit till Running on Cloud”.
Before we fly to the sky and live in the cloud, there are some recommendations from my side,
- Create different AWS accounts for each environment you have. At least for prod and non prod. This will save you from lot of pain in the future. This prevents accidental deletion of production resources, it gives you control over permissions of your employees and a clean financial management.
- Do not use root credentials for anything. Create it, write it in a paper and lock it in your locker. Everybody gets an IAM user with rights limited to their requirements.
- Do not spin resources on your own from console. You will definitely lose track of where you created it or may be someone might accidentally delete your precious resource. Always use CloudFormation to create resources. Also commit these Infrastructure as code files in a Git repository for versioning.
- Use spot instances inside ECS clusters to save huge amount of money. I repeat, huge amount of money.
- All resources in a VPC get default security group of the VPC. Internet facing ELB gets an additional security group which opens Http/Https traffic from the internet.
- Do not store files inside container, just don’t. Use S3 for this and access using S3 API.
- 2 availability zone should be more than enough on grounds of High availability. 3 is luxury, do it if you like the concept of trinity :)
- Update your nameservers of your website to AWS and use Route 53 for routing. It’s easier to have all control in one place rather jumping back and forth between 2 websites for configuring any changes in your DNS records.
- Buy reserved instances for unavoidable resources like NAT, this will save a lot of money.
- Use CloudWatch alarms to check metrics like CPU utilization and create alarms to warn you through email.
Following are the steps we will follow to spin up our resources
- Trigger a build from CodeBuild for all our latest code changes
- Create the VPC with Public, Private subnet, Internal Elastic Load Balancer and Internet facing Load Balancer. Also we will have 2 NAT instances in each Availability Zone https://raw.githubusercontent.com/richygreat/public-scripts/master/vpc-ha.yml
- Create 3 ECS clusters with 2 t3a.nano instances in all of them. 2 clusters are public and 1 in private subnets.
- Copy the DNS name of internal Elastic Load Balancer to the Task environment property internal.lb.uri
- Deploy user microservice as a service in private cluster called microservice cluster. Deploy bff application as a service in public cluster called ui cluster. Deploy api gateway as a service in public cluster called api cluster.
- Create listeners for Public and Private Load Balancers
- Create a new Security group for ELB to open port 80 to internet
- Configure Route 53 for a newly registered domain
Step 2 — VPC Creation
Download yml from https://raw.githubusercontent.com/richygreat/public-scripts/master/vpc-ha.yml
Upload the file and click Next
Step 3 — ECS Cluster creation
Now we will create 3 clusters to deploy our services.
Repeat the above steps for other 2 services with public-ui-cluster and public-api-cluster as name for others. Leave EC2 Ami Id, Root volume size and Key Pair (None) with defaults.
For ui and api public cluster choose the Public subnets.
Step 4 — ELB DNS environment property
Select the Task definitions of api gateway and bff to change the internal Load Balancer environment property
Click on Container definition and scroll down to Environment variables to paste the internal lb’s hostname with http:// prefix.
Now once you click on Update in popup and click Create in main screen you will create a new version of this task. Repeat this for bff application too.
Step 5 — Deploy the tasks as service in ECS clusters
First we will deploy user microservice to private microservice cluster
Click on Next Step buttons until you reach Create Service. Careful not to select any Load Balancing options.
Now 2 tasks are created and deployed in 2 different EC2 instances in the cluster.
Step 6 — Create target groups to route public traffic
Create 3 target groups and select the respective instances in EC2 -> Load balancing -> Target Groups
Select the port as 8081 for user-service-tg, 80 for api-service-tg and 80 for ui-service-tg
Now click on Load Balancers select public ELB and add a listener.
Do the same for internal ELB registering a listener to 8081 with private cluster instances registered
Now our Load Balancers are ready to take on internal and internet traffic
Step 7 — Additional Security Group to open port 80
Create a security group to open port 80 of the Internet Facing Load Balancer
Select both the security groups default and internet-sg and Save
All is done :) Now the icing on this cake.
Step 8 — Route 53 configuration
http://api.markoptin.com/user-service/api/v1/users/eve@apple.com
Our awesome-app is up and running in production cloud. We have achieved a great feat in just few easy steps with minimal running cost. Also with high availability in AWS.
This series will now move in the direction of event driven architecture.
How was the series? Were you able to run the whole application in AWS?Leave your feedback and if you have doubts or need advice on this type of architecture for your product send me a mail to richygreat@gmail.com