├── .gitignore ├── clean.sh ├── terraform.tfvars ├── Dockerrun.aws.json ├── variables.tf ├── README.md ├── main.tf └── deploy.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | *= 3 | *.backup 4 | *.tfstate 5 | *.tfplan 6 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Cleans directory 3 | 4 | rm -fr *.tfstate 5 | rm -fr *.tfstate.* 6 | rm -fr *.tfplan 7 | rm -fr *.zip 8 | rm -fr Dockerrun.aws.json= 9 | -------------------------------------------------------------------------------- /terraform.tfvars: -------------------------------------------------------------------------------- 1 | # You can place variables from `variables.tf` here instead of defining them in CLI 2 | # 3 | # E.g. 4 | # aws_secret_key=thisIsSuperSecret 5 | # 6 | 7 | -------------------------------------------------------------------------------- /Dockerrun.aws.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSEBDockerrunVersion": "1", 3 | "Image": { 4 | "Name": ".dkr.ecr..amazonaws.com/:", 5 | "Update": "true" 6 | }, 7 | "Ports": [ 8 | { 9 | "ContainerPort": "8080" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "profile" { 2 | description = "Name of your profile inside ~/.aws/credentials" 3 | } 4 | 5 | variable "application_name" { 6 | description = "Name of your application" 7 | } 8 | 9 | variable "application_description" { 10 | description = "Sample application based on Elastic Beanstalk & Docker" 11 | } 12 | 13 | variable "application_environment" { 14 | description = "Deployment stage e.g. 'staging', 'production', 'test', 'integration'" 15 | } 16 | 17 | variable "region" { 18 | default = "us-east-1" 19 | description = "Defines where your app should be deployed" 20 | } 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS Elastic Beanstalk + Docker Deploy Setup 2 | 3 | Purpose of this repo is to document and simplify deployment & setup process of Docker-based applications on AWS Elastic Beanstalk. 4 | 5 | ### Prerequisities 6 | - AWS IAM Role with access to IAM, EC2, Beanstalk & Elastic Container Registry/Engine and it's access & secret keys. Profile must be set inside `~/.aws/credentials` directory. 7 | - Terraform 8 | 9 | ### Contents of repo 10 | - ```Dockerrun.aws.json``` - AWS Beanstalk standard task definition. Tells Beanstalk which image from ECR it should use 11 | - ```deploy.sh``` - script for deploying applications. App must be first set up 12 | - ```*.tf``` files - Terraform infrastructure definition written in HCL (HashiCorp Configuration Language) 13 | - ```clean.sh``` - script for cleaning temporary files 14 | 15 | ### Setup 16 | 1. Run ```terraform plan -out plan.tfplan``` 17 | - Fill out Name, Description & environment 18 | - Profile is name of your profile inside `~/.aws/credentials` file (Standard AWS way). Default profile is called `default`. You can insert many profiles inside `credentials` file. 19 | 2. Run ```terraform apply plan.tfplan``` - this may take up to 15 minutes 20 | 21 | Alternatively you can place variables inside `terraform.tfvars` file instead of pasting them into CLI input. 22 | 23 | ### Rollbacking setup 24 | ``` 25 | terraform destroy 26 | ``` 27 | 28 | ### Manual deployment 29 | ``` 30 | ./deploy.sh 31 | ``` 32 | For example: 33 | ``` 34 | ./deploy.sh my-app-name staging us-east-1 f0478bd7c2f584b41a49405c91a439ce9d944657 35 | ``` 36 | 37 | If you don't have your AWS credentials set as ENV variables: 38 | ``` 39 | AWS_ACCOUNT_ID=XX677677XXXX \ 40 | AWS_ACCESS_KEY_ID=AKIAIXEXIX5JW5XM6XXX \ 41 | AWS_SECRET_ACCESS_KEY=XXXxmxxXlxxbA3vgOxxxxCk+uXXXXOrdmpC/oXxx \ 42 | ./deploy.sh my-app-name staging us-east-1 f0478bd7c2f584b41a49405c91a439ce9d944657 43 | ``` 44 | 45 | ### Automatic deployment 46 | Edit your `circle.yml` file to invoke `deploy.sh` script in `post.test` or `deploy` hook. Don't forget to fill out ENV variables in CircleCI setup. 47 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | # Configure AWS Credentials & Region 2 | provider "aws" { 3 | profile = "${var.profile}" 4 | region = "${var.region}" 5 | } 6 | 7 | # S3 Bucket for storing Elastic Beanstalk task definitions 8 | resource "aws_s3_bucket" "ng_beanstalk_deploys" { 9 | bucket = "${var.application_name}-deployments" 10 | } 11 | 12 | # Elastic Container Repository for Docker images 13 | resource "aws_ecr_repository" "ng_container_repository" { 14 | name = "${var.application_name}" 15 | } 16 | 17 | # Beanstalk instance profile 18 | resource "aws_iam_instance_profile" "ng_beanstalk_ec2" { 19 | name = "ng-beanstalk-ec2-user" 20 | roles = ["${aws_iam_role.ng_beanstalk_ec2.name}"] 21 | } 22 | 23 | resource "aws_iam_role" "ng_beanstalk_ec2" { 24 | name = "ng-beanstalk-ec2-role" 25 | 26 | assume_role_policy = < with your ID 88 | sed -i='' "s//$AWS_ACCOUNT_ID/" Dockerrun.aws.json 89 | # Replace the with the your name 90 | sed -i='' "s//$NAME/" Dockerrun.aws.json 91 | # Replace the with the selected region 92 | sed -i='' "s//$REGION/" Dockerrun.aws.json 93 | # Replace the with the your version number 94 | sed -i='' "s//$VERSION/" Dockerrun.aws.json 95 | 96 | # Zip up the Dockerrun file 97 | zip -r $ZIP Dockerrun.aws.json 98 | 99 | # Send zip to S3 Bucket 100 | aws s3 cp $ZIP s3://$EB_BUCKET/$ZIP 101 | 102 | # Create a new application version with the zipped up Dockerrun file 103 | aws elasticbeanstalk create-application-version --application-name $NAME --version-label $VERSION --source-bundle S3Bucket=$EB_BUCKET,S3Key=$ZIP 104 | 105 | # Update the environment to use the new application version 106 | aws elasticbeanstalk update-environment --environment-name $ENV --version-label $VERSION 107 | 108 | end=`date +%s` 109 | 110 | echo Deploy ended with success! Time elapsed: $((end-start)) seconds 111 | --------------------------------------------------------------------------------