Deploy any containerized app on AWS ElasticBeanstalk with GitHub actions and Terraform.
While working on a side project, I needed a quick, seamless, and cheap way to host a containerized application in the cloud. I came up with this solution, using GitHub Actions, Dockerhub, and AWS ElasticBeanstalk.
Amazon ElasticBeanstalk, is a service that abstracts all the setup needed to host a web application, it will take care of creating the ec2 instances, autoscaling, security groups, and so on.
I always choose to use IaC, so it offers me the ability to destroy, recreate, and operate my infrastructure resources in an easy way. It also helps you to keep your cloud provider account clean and prevent surprises on the bill.
Terraform code
We will be creating a bunch of AWS Resources, in order to have our ElasticBeanstalk environment ready to host our application.
I will also be creating a database.
The following terraform file, creates all the necessary resources in order to have a running ElasticBeanstalk application, and environment.
Terraform vars
Note that I'm using a "dynamic" block to set all the app environment variables, my variables.tf looks
like:
The locals
section, is the one use on the settings dynamic block, to iterate over it and generate all the environment settings.
Since we want to deploy just a docker image, our app descriptor will be a Dockerrun.aws.json
containing the following code
The terraform code, will create an s3 bucket, upload this file, and it will create an ElasticBeanstalk application version, that we will furtherly deploy using our GitHub integration.
In this case, I used nginx:latest
as an example, but you can use any image of your choice, even privately hosted docker images.
If you access your AWS Console, you should see your environment ready
GitHub Actions
I will assume you have your docker registry already setup, and you're familiar with this concepts. In this example I'm using Dockerhub to host my images.
This is how my github workflow file looks like:
The first workflow, will build the docker image, and do the following:
- if it's the
master
branch, it will push an image tag with the git hash, and it will update the latest tag too. - if it's a tag, named
v1.x
it will strip the v and tag the image with the version, it won't update the latest tag.
The second workflow, will use the aws-cli action to update the environment, note that we don't need another version of the EBS app, we just need the environment to update, pull the latest image, and restart.
I hope this setup will be useful for you and look forward to questions.