Skip to content

scaffold-sh/aws-serverless-docker

Repository files navigation

Docker

AWS Serverless Docker

+ $70 / month      ~ 4min / create

Node version Yarn version AWS version Terraform version CDKTF version License

$ scaffold aws:serverless-docker

This infrastructure uses AWS Fargate to host your Docker container in a serverless way.

Your GitHub account will be connected to CodePipeline and CodeBuild, so you will be able to build, test and deploy your application using the usual git push command.

Your pipeline will be configured with 5 stages: Source, Test, Build, Pre-deploy and Deploy. The test, build and pre-deploy stages will run in CodeBuild.

The test stage may be used to run your unit/integration/e2e tests. CodeBuild is configured to run in your VPC so you will be able to access all your infrastructure components, including your database.

The build stage will build and push your Docker container in ECR.

The pre-deploy stage will run a command in a newly created production container, just before deployment. You can use this stage to run your database migrations, for example.

This infrastructure also uses ACM to add a fully-managed SSL certificate to your application and SSM Parameters Store to store your environment variables.

The number of Availability Zones used may be configured for high availability. This infrastructure is load-balanced, auto-scaled and with zero downtime deployment.

Requirements

  • You will need a GitHub account to create this infrastructure. Support for GitLab and BitBucket is coming soon.

  • If you plan to use an apex domain for your website (i.e. a root domain that does not contain a subdomain), make sure that your domain host support the ANAME, ALIAS or naked CNAME DNS record type.

Components

Name Source Price
VPC (one)
All your infrastructure components will be contained in one VPC.
src/lib/constructs/network/vpc.ts Free
Public subnet(s) (one or more)
One or more public subnet(s) that will contain your application load balancer and your NAT gateway(s).
src/lib/constructs/network/subnets.ts Free
Private subnet(s) (one or more)
One or more private subnet(s) that will contain your Fargate and CodeBuild instances.
src/lib/constructs/network/subnets.ts Free
Application load balancer (one)
One application load balancer (replicated in public subnet(s)) that will be used to distribute incoming traffic across your Fargate instances.
src/lib/constructs/network/applicationLoadBalancer.ts +$18 / month
NAT gateway(s) (one or more)
One or more NAT gateway(s) that will enable Fargate and CodeBuild instances in private subnet(s) to connect to the internet.
src/lib/constructs/network/natGateways.ts +$35 / month
ACM (one certificate)
ACM will be used to manage the SSL certificate of your application.
src/lib/constructs/network/ssl.ts Free

Computing

Name Source Price
Fargate (one cluster)
Fargate will be used to run your containers without having to manage servers.
src/lib/constructs/computing/cluster.ts
src/lib/constructs/computing/service.ts
src/lib/constructs/computing/tasks.ts
+$15 / month
ECR (one repository)
ECR will be used to store your Docker images.
src/lib/constructs/computing/repository.ts Usage
SSM (one parameter store)
SSM Parameter Store will be used to store the environment variables of your application.
src/lib/constructs/computing/environmentVariables.ts Usage

Continuous Deployment

Name Source Price
CodePipeline (one pipeline)
CodePipeline will be used to manage the builds and deployments of your application.
src/lib/constructs/continuousDeployment/pipeline.ts +$1 / month
CodeBuild (three build projects)
CodeBuild will be used to run the test, build and pre-deploy stages of your pipeline.
src/lib/constructs/continuousDeployment/builds.ts +$1.5 / month

Dashboard

Name Source Price
CloudWatch (one dashboard)
CloudWatch will be used to display the metrics of your infrastructure components.
src/lib/constructs/dashboard/index.ts Free

Environment variables

These environment variables will be automatically configured each time you create an environment (or a sandbox) for your infrastructure.

Name Description
CONTAINER_LISTEN_PORT The port that needs to be used to send requests to your Docker container.
DOMAIN_NAMES The domain names that need to be covered by your ACM certificate.
ENABLE_AUTO_SCALING Do auto-scaling needs to be enabled?
ENABLE_HTTPS We need to wait for the ACM certificate to be "issued" to enable HTTPS. See the "after install" section to learn more.
FARGATE_TASKS_CPU The CPU that could be used by your Fargate tasks.
FARGATE_TASKS_MEMORY The memory that could be used by your Fargate tasks.
GITHUB_BRANCH The branch from which you want to deploy.
GITHUB_OAUTH_TOKEN The GitHub OAuth token that will be used by CodePipeline to pull your source code from your repository.
GITHUB_REPO The GitHub repository that contains your source code.
GITHUB_REPO_OWNER The owner of your GitHub repository. Can be a regular user or an organization.
GITHUB_WEBHOOK_TOKEN A random token that will be used by CodePipeline and GitHub to prevent impersonation.
NUMBER_OF_AVAILABILITY_ZONES_USED The number of availability zones used by your infrastructure.
PRE_DEPLOY_COMMAND A command that will run in a newly created production container, just before deployment.

Inherited

Name Description
SCAFFOLD_AWS_PROFILE The AWS named profile used to create your infrastructure.
SCAFFOLD_AWS_REGION The AWS region where you want to create your infrastructure.
SCAFFOLD_AWS_S3_BACKEND_BUCKET The AWS S3 bucket that will contain the Terraform state of your infrastructure.
SCAFFOLD_AWS_S3_BACKEND_DYNAMODB_TABLE The AWS DynamoDB table that will be used to store the Terraform state locks.
SCAFFOLD_AWS_S3_BACKEND_KEY The S3 bucket key under which your Terraform state will be saved.
SCAFFOLD_RESOURCE_NAMES_PREFIX An unique custom prefix used to avoid name colision with existing resources.

After install

Your load balancer will display a "503 Service Temporarily Unavailable" error until the end of the first deployment.

This infrastructure exports four Terraform outputs: application_load_balancer_uri, dashboard_url, pipeline_execution_details_url and ssl_validation_dns_records.

The application_load_balancer_uri output value contains the URI of your load balancer. You could use it to access your application while your DNS are propagating.

The dashboard_url and pipeline_execution_details_url output values contains the URLs of your CloudWatch dashboard and your pipeline executions details.

The ssl_validation_dns_records output value contains the DNS records that you need to set in order to validate your ACM certificate (see below).

How do I set up my domain name?

The way you will set up your domain name will vary according to the presence or absence of a subdomain.

If your domain name doesn't have any subdomains, you will need to add two DNS records:

  • Name: or @
  • Type: ALIASE, ANAME or CNAME
  • Value: application_load_balancer_uri

  • Name: www
  • Type: CNAME
  • Value: application_load_balancer_uri

If your domain name has a subdomain, you will need to add one CNAME record:

  • Name: subdomain
  • Type: CNAME
  • Value: application_load_balancer_uri

How do I set up HTTPS?

The ssl_validation_dns_records output value contains the DNS records that you need to set in order to validate your ACM certificate.

Once set, you will need to wait for the status of your certificate to switch from "pending" to "issued" to use it with your application load balancer.

You could then set the ENABLE_HTTPS environment variable to "true" in your local env file and run the scaffold apply command to update your infrastructure.

If you want to automate this process, you could use AWS Route 53 as your domain host then use the aws_route53_record and aws_acm_certificate_validation resources to wait for certificate validation. See the Terraform documentation to learn more.

How do I add environment variables to my application?

To add an environment variable to your application all you have to do is to add an environment variable that starts with APPLICATION_ to your infrastructure code.

For example, let's say that you want to add a TOKEN variable to your application. You will first add it to your .env file:

# .env
APPLICATION_TOKEN=

Then, given that this value is secret you choose to define it in your local env file:

# .env.{environment}.local
APPLICATION_TOKEN=MY_SECRET_TOKEN

That's it! Run the scaffold apply command and re-deploy your application to access your TOKEN environment variable.

How do I customize the test, build and pre-deploy stages of my pipeline?

CodeBuild uses a YAML file to describe all the steps that a stage requires. These files are located in the templates directory at the root of your infrastructure:

# ./templates                                  
buildspec.yml
predeployspec.yml
testspec.yml

You could update these files directly to customize your pipeline stages.

How do I access environment variables from my *spec files?

The process to add an environment variable to your *spec files is identical to the one used for you application except than you need to prefix your environment variables with BUILD_:

# .env.{environment}.local
BUILD_TOKEN=MY_SECRET_TOKEN

One done, you could access your environment variables in all your *spec files:

# templates/testspec.yml

version: 0.2

phases:
  pre_build:
    commands:
      - echo $TOKEN

Remember to run the scaffold apply command each time you update your infrastructure code.

How do I customize my CloudWatch dashboard?

Your CloudWatch dashboard is composed of widgets defined as JSON in the dashboard/index.ts file:

// ./src/lib/constructs/dashboard/index.ts

this.self = new CloudwatchDashboard(this, "cloudwatch_dashboard", {
  dashboardName: props.resourceNamesPrefix,
  dashboardBody: JSON.stringify({
    widgets: [
      {
        type: "metric",
        width: 12,
        height: 6,
        // ...
      }
    ]
  })
})

You could safely add, update or delete widgets using the structure defined in the AWS documentation.

Releases

No releases published

Packages

No packages published