Going to AWS Summit London? 🇬🇧🇬🇧

Meet us there →

Terraform

Using Terraform to Set Up and Deploy Docker Containers

Using Terraform to Set Up and Deploy Docker Containers

This article will explain how to use Terraform for automation to set up and deploy Docker containers. We will be using Docker for Windows Desktop to show how to deploy a demo container.

Set up Windows Subsystem for Linux 2 (WSL2)

Firstly we will need to set up the Windows Subsystem for Linux if you have not already done so. To do this, follow the instructions here.

Set up Docker for Windows Desktop

If you don’t already have Docker installed, you can download it for free.

During the installation process, you should also check the ‘Use the WSL 2 based engine’. This uses the Windows Subsystem for Linux, which provides better Docker performance.

Once Docker is installed, for our demo purposes, we will need to expose the daemon without TLS.

Go to the Docker Desktop for Windows settings and make sure ‘Expose daemon on TCP:localhost:2375 without TLS’ is ticked. Apply the settings, and Docker will restart.

expose the daemon without TLS

Setup & Deploy Docker Containers Using Terraform

We will be using the Docker provider as found on the Terraform registry:

The localhost:2375 is the default address for the Docker daemon.

terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "2.23.1"
    }
  }
}

provider "docker" {
  host = "tcp://localhost:2375"
}

Note for reference to connect to a Linux machine with Docker installed you would use the host line:

host = "unix:///var/run/docker.sock"

Next we need to add the container configuration to the main.tf file:

# Creating a Docker Image ubuntu with the latest as the Tag.
resource "docker_image" "ubuntu" {
  name = "ubuntu:latest"
}

# Creating a Docker Container using the latest ubuntu image.
resource "docker_container" "webserver" {
  image             = docker_image.ubuntu.latest
  name              = "terraform-docker-test"
  must_run          = true
  publish_all_ports = true
  command = [
    "tail",
    "-f",
    "/dev/null"
  ]
}
terraform docker - terraform init
terraform creating docker image
terraform creating docker image complete

Back in the Docker Desktop for Windows GUI you can see the Container running:

terraform docker Container running

Or on the command line using  docker container ls.

docker container ls

Lets add an NGINX (web server) image and container resource to the main.tf config file:

resource "docker_image" "nginx" {
  name         = "nginx:latest"
  keep_locally = false
}

resource "docker_container" "nginx" {
  image = docker_image.nginx.latest
  name  = "nginx-test"
  ports {
    internal = 80
    external = 8000
  }
}

This specifies the internal and external ports that allow the container to be accessed from the localhost. Run terraform apply again and accept the changes.

You should now see two containers running, not the ports against the nginx-test container.

terraform docker creating two containers
terraform docker two containers running

Browse to http://localhost:8000/ to view the default web page:

terraform docker nginx

You can also use Terraform to deploy other aspects of Docker containers, such as volumes, secrets, tags, and networking.

resource "docker_network" "private_network" {
  name = "my_network"
}

resource "docker_secret" "foo" {
  name = "foo"
  data = base64encode("{\"foo\": \"s3cr3t\"}")
}

resource "docker_volume" "shared_volume" {
  name = "shared_volume"
}

#The source image must exist on the machine running the docker daemon.
resource "docker_tag" "tag" {
  source_image = "xxxx"
  target_image = "xxxx"
}

To cleanup, type terraform destroy.

terraform docker clean up

Key Points

If you need any help managing your Terraform infrastructure, building more complex workflows based on Terraform, and managing AWS credentials per run, instead of using a static pair on your local machine, Spacelift is a fantastic tool for this. It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more great features right out of the box.

Note: New versions of Terraform will be placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that will expand on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6. OpenTofu retained all the features and functionalities that had made Terraform popular among developers while also introducing improvements and enhancements. OpenTofu is not going to have its own providers and modules, but it is going to use its own registry for them.

Manage Terraform Better with Spacelift

Build more complex workflows based on Terraform using policy as code, programmatic configuration, context sharing, drift detection, resource visualization and many more.

Start free trial
Terraform CLI Commands Cheatsheet

Initialize/ plan/ apply your IaC, manage modules, state, and more.

Share your data and download the cheatsheet