Setup containerized Application in AWS ECS - Part 1/3
Tags: aws, terraform, cicd, rds
Published: 2023-12-07 08:44:29

In the article, I'll dive into the details that how to setup a containerized application in AWS Cloud. The AWS services leveraged in the project include ECS, RDS, ALB, IAM etc. All source code is stored in GitHub that publicly available. 

Before getting started, I assume you that:
1. Have basic knowledge about AWS services: ECS, RDS, ALB, IAM etc and hands-on experience on AWS.
2. Have basic understanding about containerization and the benefits of containerization.
3. Experience on Terraform and CICD.
4. Love coding and be eager to learn.

As there are lots of topics and knowledge in the article, I separate it into three sections, which include:
1. Build MySQL Database in AWS RDS
2. [Build ECS Cluster in AWS ECS](https://dev.to/camillehe1992/setup-containerized-application-in-aws-ecs-part-23-2of3)
2. [Build containerized application in AWS ECS](https://dev.to/camillehe1992/setup-containerized-application-in-aws-ecs-part-33-3fee)

Something you'd better know:
1. I'm working on MacBook M1, so some scripts in the source code may not work in other OS. Besides, you should configure the environment if you want to debug, develop and deploy the application on the machine. 
2. As the project is intended for demo purpose, which means it's not a best practice from the security and stability perspective. At the end of the article, I'll share some ideas about how to improve the project in real world.

## :anchor: Project Background

In the demo, I will build a containerized application in AWS. The application is hosted in EC2 as containers. Users can access the application via an internet ALB (Application Load Balancer). A RDS instance will be launched for data persistence. The application is built based on [Strapi](https://strapi.io/), which is an open-source headless CMS. The Strapi application provides an admin panel and makes it easy to build standard backend API. Meanwhile, it integrates with most of popular database engines smoothly, for example MYSQL, Postgres and sqlite. All the features makes it the best fit in my demonstration. You can dive into Strapi via its official website portal if interested. 

The architecture diagram in AWS shows as below.
![Arch-Overall](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxox9ovao8miq3p8g9tf.png)

All AWS resources in above diagram will be created in the project, except for network things. I will use the default VPC, Subnets and Security Groups in the AWS account. Well it's unsafe but easier to setup a project just for demo purpose.

## :house_with_garden: Setup Database in AWS RDS

Now, let's focus on the RDS database setup (AWS resources in green box). Find the source code from https://github.com/camillehe1992/aws-terraform-examples/tree/main/rds-mysql-instance

The source code contains two parts, the Terraform resources and Lambda function source code. The AWS resources created in the project include:

### AWS RDS Instance & Secrets
A RDS instance with custom parameter group is created. The database secret (username and password) is managed in Secrets Manager. The secret is auto-generated by AWS and will be used when interacting with database.

### AWS Lambda Function & Lambda Execution IAM Role & CloudWatch Logs Group 
A Lambda function and CloudWatch Logs group for function logs persistence. The function is used to initialize database, such as create a database or tables. A Lambda function execution IAM role with appropriate permissions.

Replace the default SQL script in `src/script.sql` with below script. I need to create a database name `strapi` after the instance is available.
```sql
CREATE DATABASE IF NOT EXISTS strapi;
```
You can invoke the Lambda function via AWS CLI from local or console directly.

Go to the README documentation in above GitHub repository to setup local environment if you want to deploy AWS resources from local machine or via GitHub Actions workflows. 

After done, you can get three environment variables that will be used in next part.
```bash
# the endpoint of RDS database (retrieved from RDS)
DATABASE_HOST
# the username of RDS database (retrieved from Secrets Manager)
DATABASE_USERNAME
# the password of RDS database (retrieved from Secrets Manager)
DATABASE_PASSWORD
```

Next to [Setup containerized Application in AWS ECS - Part 2/3](https://dev.to/camillehe1992/setup-containerized-application-in-aws-ecs-part-23-2of3)

## :books: References
- https://strapi.io/
- https://www.terraform.io/
- https://registry.terraform.io/providers/hashicorp/aws/5.25.0/docs
- https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html
- https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html

Always appreciate for your ideas and comments. Thanks for reading! :smile: