4 min read

How do I make a Docker Container using Terraform?

💡
Tools used:
- Docker
- An AWS EC2 Ubuntu Instance
- Terraform installed on the EC2 Ubuntu Instance

Install Terraform

The official instructions for installing Terraform are here. I used Ubuntu-based EC2 for this "How do I", instructions for which are here.

Install Docker

The official instructions for installing Docker are here.

Steps

Step # 1: Create an empty main.tf File

nano main.tf

Step # 2: Write Configuration Code in main.tf

# Block 1
terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "3.0.1"
    }
  }
}

# Block 2
provider "docker" {
}

# Block 3
resource "docker_image" "image" {
  name = "nginx:latest"
}

# Block 4
resource "docker_container" "container" {
  name  = "demo"
  image = docker_image.image.image_id
}

What's going on here?

Refer to Terraform Documentation for the docker_image resource type.
Refer to Terraform Documentation for docker_container resource type.

Step # 3: Initialize Terraform's Working Environment

terraform init

terraform init will ensure the right providers and other dependencies listed in main.tf are downloaded and set up. Typically say is run just once for new configuration files but no rules say you can't execute this command again.

The image below shows how terraform init will find and download the components required for our example today.


Minor Digression

If you get the error below on an Ubuntu VM/EC2...

.. update permissions using

sudo chmod 666 /var/run/docker.sock

Step 4: Optionally validate the contents of main.tf

The terraform validate command validates the configuration files in a directory, referring only to the configuration and not accessing any remote services such as remote state, provider APIs, etc.

Validate runs checks that verify whether a configuration is syntactically valid and internally consistent, regardless of any provided variables or existing state. It is thus primarily useful for the general verification of reusable modules, including the correctness of attribute names and value types.

🪧
Validation requires an initialized working directory with any referenced plugins and modules installed.
terraform validate -json
Refer to Terraform Documentation to read more about terraform validate.

Step 5: Execute terraform plan

terraform plan
TF Engine will list the resources it will create along with the attributes of the resource.

Step 6: Execute terraform apply

terraform apply
Yes, we do.
"Alright, if you say so".

Step 7: Confirm the Image and Container exist

We can use our trusty docker container ps and docker images ls to list both the running container (named demo in main.tf) and the nginx image that was downloaded.

Yup, image was downloaded.
docker container ps -a shows demo was also created.

Step 8: Optional additional testing

The nginx container has Port 80 through which external traffic can get in. If our container was indeed working and was created correctly, we could try to send a simple HTTP request to it and receive a response in return.

docker run -d -p 81:80 --name optional_test nginx 

The command above is telling the docker daemon to

  • Use the nginx image
  • Spin up a container called optional_test
  • Map Port 81 on the host system (i.e. the VM or EC2 you are using) to Port 80 inside the container.

Finally, send a simple HTTP request to the optional_test container using curl

curl http://localhost:81

The response will be HTML markup from the container.

Step 9: Optionally use terraform destroy to remove the Container and Image.

💡
Make sure the container has been removed. You can use:
docker container stop <name of container>
docker container rm <name of container>

I write to remember, and if, in the process, I can help someone learn about Containers, Orchestration (Docker Compose, Kubernetes), GitOps, DevSecOps, VR/AR, Architecture, and Data Management, that is just icing on the cake.