Docker the Terraform Way
Problem Challenge for Orchestrating Docker Containers with Terraform
I create a series of articles that demonstrates how to orchestrate Docker in a variety of methods using Ansible, Docker Compose, or scripting languages. This article shows how to create do the same thing with Terraform.
About Terraform
Though some may not want to admit, but Terraform is essentially a change configuration and orchestration tool for resources exposed through a RESTful web interface. Terraform is popular with cloud infrastructure provisioning, using the web API from popular cloud providers like AWS, Google Cloud, and Azure.
On a system, as the Docker service (daemon) communicates through a web interface, it is a perfect candidate to automate through Terraform, and sure enough, there’s a Docker Provider.
Prerequisites
The tools needed for this are:
- Docker: https://docs.docker.com/install/
- Terraform: https://www.terraform.io/downloads.html
- InSpec (for automated verification): https://downloads.chef.io/inspec
jq
json process: https://stedolan.github.io/jq/
The Problem Challenge
For this problem, we want to orchestrate two Docker containers: WordPress and MySQL. These containers will always restart should they fail, the database will persist outside the life of the MySQL container, and the WordPress will be accessible through a user defined port, and will communicate to the database on a private network.
Below are details on what exactly to implement.
Basic Feature Requirements
We get started by just bringing up the containers.
For specifics, we want to do the following:
- Launch the MySQL 5.7 container (
mysql:5.7
) with restart policy of always, container name ofdb
, and send environment variables to the container that will trigger the container’s internal automation to configure root password,wordpress
user and password, andwordpress
database. - Launch the WordPress container (
wordpress:latest
) with restart policy of always, container name of wordpress, and send environment variables to the container that will trigger the container’s internal automation to configure hostname (db
) and port (3306
), and password to thewordpress
database.
Advanced Feature Requirements
Now we can configure a private container network, persistent volume, and add support to changing the wordpress
host or external port.
For specifics:
- Add support for
wordpress_port
input variable with a default of8080
. When using theterraform
, we can set the variable to be equal to theWORDPRESS_PORT
environment variable. - Create a network called
wordpress_net
, and have both containers use this network by settingnetwork_mode
. - Create a volume called
db_data
, and mount this volume as/var/lib/mysql
on thedb
container.
Getting Started
Below is a script to get your started.
Download the script and then run terraform init
do download and install the Docker Provider.
You can try out the Terraform script by running these commands:
terraform plan # list changes needed
terraform apply # launch containers
terraform destroy # cleanup
When you are ready to try out wordpress_port
input variable with WORDPRESS_PORT
environment variables, you can do this:
export WORDPRESS_PORT=8888
terraform plan -var="wordpress_port=$WORDPRESS_PORT"
terraform apply -var="wordpress_port=$WORDPRESS_PORT"
Verification
Once completed or as you create this, you can verify your solution by manually checking with the following command line tools: docker
, jq
, and grep
; or you can use automated verification using InSpec.
Manual Verification of Basic Features
Manual Verification of Adv Features
Automated Verification with InSpec
Once you download this script, you can run the tests with verify doing the following:
terraform apply
inspec exec container_test.rb
When testing out an alternative port, you can do this:
export WORDPRESS_PORT=8888
terraform apply -var="wordpress_port=$WORDPRESS_PORT"
echo "port: $WORDPRESS_PORT" > attributes.yml
inspec exec container_test.rb --attrs=attributes.yml
Resources
- Terraform Docker Provider: https://www.terraform.io/docs/providers/docker/index.html
- MySQL Docker Image: https://hub.docker.com/_/mysql
- WordPress Docker Image: https://hub.docker.com/_/wordpress
To Be Continued
This article only details out the problem challenge and verification scripts, and afterward, I will present the final solution.