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.
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.
John
Good article! Worked for me!