Deploy Environment

Deploy our application, service, and environment

In this section, it is important to match the names as described in order for the tutorial to work (so that it matches the format of the manifest in the tutorial repository):

cd ~/environment/secretecs
copilot init
Optional Shortcut - pass all parameters through CLI
  • Application Name: ecsworkshop #note this should be unique in your AWS account
  • Workload Type: Load Balanced Web Service
  • Service Name: todo-app - this must be left ‘as-is’ for demo purposes
  • Dockerfile: ./Dockerfile

After a brief moment, you will be prompted to created a local environment.

  • Deploy local test environment: yes
Secrets Diagram

During this stage of the process, copilot is doing the initial infrastructure setup and preparing to creates a new environment, including creating an ECR repository to store the container build images.

✔ Proposing infrastructure changes for the ecsworkshop environment.
- Creating the infrastructure for the ecsworkshop environment.           [create complete]  [82.1s]
  - An IAM Role for AWS CloudFormation to manage resources               [create complete]  [19.5s]
  - An ECS cluster to group your services                                [create complete]  [12.7s]
  - An IAM Role to describe resources in your environment                [create complete]  [17.9s]
  - A security group to allow your containers to talk to each other      [create complete]  [4.9s]
  - An Internet Gateway to connect to the public internet                [create complete]  [16.6s]
  - Private subnet 1 for resources with no internet access               [create complete]  [16.4s]
  - Private subnet 2 for resources with no internet access               [create complete]  [16.4s]
  - Public subnet 1 for resources that can access the internet           [create complete]  [16.4s]
  - Public subnet 2 for resources that can access the internet           [create complete]  [16.4s]
  - A Virtual Private Cloud to control networking of your AWS resources  [create complete]  [16.6s]
    Linking account XXXXXXX and region us-west-2 to application ecsworkshop. 

Next, copilot pulls the application image from the ECR repository and builds the application, including VPC, Aurora Serverless DB, and deploys the application to a newly created ECS cluster.

Deployment of the app via copilot goes through the following stages:

- Creating the infrastructure for stack ecsworkshop-test-todo-app              [create in progress]  
  - An Addons CloudFormation Stack for your additional AWS resources           [review in progress]  
  - Service discovery for your services to communicate within the VPC          [create complete]    
  - Update your environments shared resources                                  [update in progress]  
    - A security group for your load balancer allowing HTTP and HTTPS traffic  [create in progress] 
  - An IAM Role for the Fargate agent to make AWS API calls on your behalf     [create complete]    
  - A CloudWatch log group to hold your service logs                           [create complete]   
  - An ECS service to run and maintain your tasks in the environment cluster   [not started]         
  - A target group to connect the load balancer to your service                [create complete]   
  - An ECS task definition to group your containers and run them on ECS        [not started]         
  - An IAM role to control permissions for the containers in your tasks        [create complete]   

This step in the process takes a few minutes, so let’s dive into what is going on behind the scenes.

Copilot creates a new environment by default called test which is used throughout the rest of the tutorial. The manifest file created in the project defines everything needed for a load balanced web application. Read the full specification for the “Load Balanced Web Service” type at

https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/

Now lets review the manifest file itself:

Click to review copilot/todo-app/manifest.yml

Next, we create an Aurora Serverless Postgres Database Cluster via the addons functionality of copilot.

Click to review copilot/todo-app/addons/db.yml

Once the copilot process is finished, the last step for this tutorial is to get the LoadBalancer URL from copilot and make a call to the application’s migrate endpoint to populate the database.

URL=$(copilot svc show --json | jq -r .routes[].url)
curl -s $URL/migrate | jq

This will produce JSON output showing a DROP, CREATE, and UPDATE to populate the database app with an initial todo item.

To view the app, open a browser and go to the Loadbalancer URL ECSST-Farga-xxxxxxxxxx.yyyyy.elb.amazonaws.com: Secrets Todo

This is a fully functional todo app. Try creating, editing, and deleting todos. Using the information output from deploy along with the secrets stored in Secrets Manager, connect to the Postgres Database using a database client or the psql command line tool to browse the database.

Since this application uses Aurora Serverless, you can also use the query editor in the AWS Management Console - find more information here. All you need is the secret ARN created by Copilot, you can fetch it at the terminal and copy/paste into the query editor dialog box:

aws secretsmanager list-secrets | jq -r '.SecretList[].ARN'

Deploy our application, service, and environment

First, let’s test the existing code for any errors.

cd ~/environment/secret-ecs-cdk-example
cdk synth

This creates the cloudformation templates which output to a local directory cdk.out. Successful output will contain (ignore any warnings generated):

Successfully synthesized to /home/ec2-user/environment/secret-ecs-cdk-example/cdk.out
Supply a stack id (VPCStack, RDSStack, ECSStack) to display its template.

(Note this is not a required step as cdk deploy will generate the templates again - this is an intermediary step to ensure there are no errors in the stack before proceeding. If you encounter errors here stop and address them before deployment.)

Then, to deploy this application and all of its stacks, run:

cdk deploy --all --require-approval never --outputs-file result.json

The process takes approximately 10 minutes. The results of all the actions will be stored in result.json for later reference.

Expand to view deployment screenshots

Code Review

Let’s review whats happening behind the scenes.

The repository contains a sample application that deploys a ECS Fargate Service. The service runs this NodeJS application that connects to a AWS RDS Aurora Serverless Database Cluster. The credentials for this application are stored in AWS Secrets Manager.

First, let’s look at the application context variables:

Review cdk.json

Next, let’s look at the Cloudformation stacks constructs. The files in lib each represent a Cloudformation Stack containing the component parts of the application infrastructure.

Review lib/vpc-stack.ts
Review lib/rds-stack.ts
Review lib/ecs-fargate-stack.ts
Review bin/secret-ecs-app.ts

After deployment finishes, the last step for this tutorial is to get the LoadBalancer URL and run the migration which populates the database.

url=$(jq -r '.ECSStack.LoadBalancerDNS' result.json)
curl -s $url/migrate | jq

(Note that the migration may take a few seconds to connect and run.)

The custom method migrate creates the database schema and a single row of data for the sample application. It is part of the sample application in this tutorial.

To view the app, open a browser and go to the Load Balancer URL ECSST-Farga-xxxxxxxxxx.yyyyy.elb.amazonaws.com (the URL is clickable in the Cloud9 interface): Secrets Todo

This is a fully functional todo app. Try creating, editing, and deleting todo items. Using the information output from deploy along with the secrets stored in Secrets Manager, connect to the Postgres Database using a database client or the psql command line tool to browse the database.

As an added benefit of using RDS Aurora Postgres Serverless, you can also use the query editor in the AWS Management Console - find more information here. All you need is the secret ARN created during stack creation. Fetch this value at the Cloud9 terminal and copy/paste into the query editor dialog box. Use the database name tododb as the target database to connect.

aws secretsmanager list-secrets | jq -r '.SecretList[].ARN'