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:

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.

Basic Features Table

For specifics, we want to do the following:

  1. Launch the MySQL 5.7 container (mysql:5.7) with restart policy of always, container name of db, and send environment variables to the container that will trigger the container’s internal automation to configure root password, wordpress user and password, and wordpress database.
  2. 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 the wordpress 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:

  1. Add support for wordpress_port input variable with a default of 8080. When using the terraform, we can set the variable to be equal to the WORDPRESS_PORT environment variable.
  2. Create a network called wordpress_net, and have both containers use this network by setting network_mode.
  3. Create a volume called db_data, and mount this volume as /var/lib/mysql on the db 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

To Be Continued

This article only details out the problem challenge and verification scripts, and afterward, I will present the final solution.

Linux NinjaPants Automation Engineering Mutant — exploring DevOps, o11y, k8s, progressive deployment (ci/cd), cloud native infra, infra as code

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Create an augmented reality portfolio (No code and free)

5 Massive FinTech Software Development Fields You Could Invest In

The Making of an Interactive Portfolio Experience

The basics of Garbage Collection

Serverless Lock-in doesn’t exist (if your Team knows Hexagoxal Architecture): an example in Go

Open Banking: The API journey continues

My Favorite Automation Hack

Free TON Governance 2.0:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Joaquín Menchaca (智裕)

Joaquín Menchaca (智裕)

Linux NinjaPants Automation Engineering Mutant — exploring DevOps, o11y, k8s, progressive deployment (ci/cd), cloud native infra, infra as code

More from Medium

Allowing access to a Linux web app (app service) via Front Door using Terraform

How to Deploy Linux Virtual Machines in Azure using Terraform

How To Monitor An ASP.NET Core API Running On AWS Fargate Using Amazon CloudWatch And CDK

Connect to an Azure VM via RDP on Linux using Remmina