Scroll to top
© 2018 All Rights Reserved.
Share

Creating a Docker Swarm on AWS using Terraform


Dominik Sachsenhofer - 4. October 2017 - 1 comment

What is Terraform?

Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.

Configuration files describe to Terraform the components needed to run a single application or your entire datacenter. Terraform generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied.

The infrastructure Terraform can manage includes low-level components such as compute instances, storage, and networking, as well as high-level components such as DNS entries, SaaS features, etc.

 

1. Requirements

1.1 Docker

See this article on how to install Docker.

1.2 AWS Command Line Interface

See this article on how to install the AWS Command Line Interface.

1.3 Packer

See this article on how to install Packer.

1.4 Terraform

See this article on how to install Terraform.

1.5 (Optional) Dynatrace Account

See http://www.dynatrace.com for more information.

2. Create a dockerized microservice

2.1 Required Software:

  • docker (1.6.0 or above)
  • python (2.7 or above)
  • ubuntu

2.2 Create a simple Python Flask App (python_example)

Create a folder python_example. All our files will be inside this directory.

Create a new file app.py inside python_example and add the following python code.

File /python_example/app.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
return 'SUCCESS: This Flask application is dockerized.'

@app.route('/health')
def health():
return 'OK'

if __name__ == '__main__':
app.run(debug=False, host='0.0.0.0')

2.3 Requirements File:

Requirements file states the software required to be installed in the container. Create a file requirements.txt inside python_example folder.

File: /python_example/requirements.txt

Flask==1.0.0

 

2.4 Dockerfile

This file is needed to create a docker image:

File: /python_example/Dockerfile

FROM ubuntu:latest
MAINTAINER Dominik Sachsenhofer "dominik@sachsenhofer.io"
RUN apt-get update
RUN apt-get install -y python-pip python-dev build-essential wget curl
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["app.py"]

 

 

2.5 Build the Docker Image

Run the following command to build the docker image python_example from python_example directory.
$ docker build -t python_example:latest .

2.6 Run the Docker Container

$ docker run -d -p 5000:5000 python_example

2.7 Optional

Connect Docker with your GitHub Repository: Create an GitHub account and push your work to a repository called “python_example”. Create an Docker account and create a new Docker Image and connect the image to your GitHub repository “python_example”. Whenever you push code into your GitHub repository, the corresponding Docker Image is rebuilt.

Download:

GitHub: https://github.com/sachsenhofer/python_example

Dockerized microservice: sachsenhofer/python_example

3. Set up your Environment

3.1 Create a new Key Pair

Create a new Key Pair in your Amazon AWS EC2 Management Console. You will get a file with filename [AWS_SSH_KEY_ID].pem. See this article for more information. 

 

3.1 Set your environment variables

nano ~/.bash_profile
Append the following lines:
export AWS_ACCESS_KEY_ID=[AWS_ACCESS_KEY_ID]
export AWS_SECRET_ACCESS_KEY=[AWS_SECRET_ACCESS_KEY]
export AWS_DEFAULT_REGION=eu-central-1
export AWS_SSH_KEY_ID=[AWS_SSH_KEY_ID]
export AWS_SSH_KEY=/[PATH]/[AWS_SSH_KEY_ID].pem

 

3.2 Clone this repository:

git clone https://github.com/sachsenhofer/terraform_example.git

4. Build an AWS AMI with Docker using Packer

Creating a AMI with docker preinstalled will speed up the creation of the docker swarm as all the nodes will be exactly the same.

4.1 Create a VPC

cd packer
terraform plan
terraform apply

 

4.2 Get the values of [AWS_VPC_ID], [AWS_SUBNET_ID] and [AWS_SECURITY_GROUP_ID]

terraform show

 

4.3 Create the AMI

packer build \
       -var aws_vpc_id=[AWS_VPC_ID] \
       -var aws_subnet_id=[AWS_SUBNET_ID] \
       -var aws_security_group_id=[AWS_SECURITY_GROUP_ID] \
       docker-aws.json

 

4.4 Teardown the VPC

terraform destroy -force

5. A deep dive into Terraform

How to setup Terraform configuration files.

See: https://github.com/sachsenhofer/terraform_example

6. Creating the Swarm

Use terraform to create several masters and slaves.

Get the AMI name

aws ec2 describe-images --owners self --filters "Name=name,Values=docker*" --query 'Images[*].[ImageId,Name,CreationDate]' --output text

 

Test the configuration

cd swarm
terraform plan -var 'amis={eu-central-1 = "..." }' \
               -var aws_region=$AWS_DEFAULT_REGION \
               -var ssh_key_filename=$AWS_SSH_KEY \
               -var ssh_key_name=$AWS_SSH_KEY_ID

 

Build the swarm

terraform apply -var 'amis={eu-central-1 = "..." }' \
                -var aws_region=$AWS_DEFAULT_REGION \
                -var ssh_key_filename=$AWS_SSH_KEY \
                -var ssh_key_name=$AWS_SSH_KEY_ID

 

Teardown the swarm

terraform destroy -force \
                  -var 'amis={eu-central-1 = "..." }' \
                  -var aws_region=$AWS_DEFAULT_REGION \
                  -var ssh_key_filename=$AWS_SSH_KEY \
                  -var ssh_key_name=$AWS_SSH_KEY_ID

6. Using the Swarm

Log into the swarm manager

6.1 View services

docker service ls

 

6.1 Docker Cloud stack

A stack is a collection of services that make up an application in a specific environment. Learn more about stacks for Docker Cloud here. A stack file is a file in YAML format that defines one or more services, similar to a docker-compose.yml file for Docker Compose but with a few extensions. The default name for this file is docker-cloud.yml.

Looking for information on stack files for Swarm? A good place to start is the Compose reference file, particularly the section on deploy key and its sub-options, and the reference on Docker stacks. Also, the new Getting Started tutorial demos use of a stack file to deploy an application to a swarm.

6.2 Stack file example

Below is an example docker-stack.yml:
File: docker-stack.yml

version: "3"
services:

  redis:
    image: redis:alpine
    ports:
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        constraints: [node.role == manager]

  python_backend:
    image: sachsenhofer/python_example:latest
    ports:
      - 5000:5000
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure

networks:
  frontend:
  backend:

volumes:
  db-data:

 

6.3 Deploying the stack

wget https://raw.githubusercontent.com/sachsenhofer/terraform_example/master/docker-stack.yml
docker stack deploy --compose-file docker-stack.yml python_example

 

6.4 View the stack

docker stack ls

7. Install Dynatrace OneAgent on Linux hosts

Run the installation script on each Linux machine that you want to monitor.

7.1 Use this command on the target host:

wget -O Dynatrace-OneAgent-Linux-1.127.133.sh "https://cvq20253.live.dynatrace.com/api/v1/deployment/installer/agent/unix/default/latest?Api-Token=[API_TOKEN]&arch=x86"

7.2 Verify signature:

wget https://ca.dynatrace.com/dt-root.cert.pem ; ( echo 'Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="--SIGNED-INSTALLER"'; echo ; echo ; echo '----SIGNED-INSTALLER' ; cat Dynatrace-OneAgent-Linux-1.127.133.sh ) | openssl cms -verify -CAfile dt-root.cert.pem > /dev/null

7.3 And run the installer with root rights:

/bin/sh Dynatrace-OneAgent-Linux-1.127.133.sh APP_LOG_CONTENT_ACCESS=1

Restart the processes that you want to monitor.

Conclusion

Terraform is a powerful tool to programmatically create infrastructure (infrastructure-as-code) and to automate the deployment of dockerized images and services.

1 comment

  1. John

    Good article! Worked for me!

Post a Comment