How do I make a Docker Container using Terraform?
- 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?
![](https://hestia.ghost.io/content/images/2024/05/image.png)
![](https://hestia.ghost.io/content/images/2024/05/image-1.png)
![](https://hestia.ghost.io/content/images/2024/05/image-2.png)
![](https://hestia.ghost.io/content/images/2024/05/image-4.png)
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.
![](https://hestia.ghost.io/content/images/2024/05/image-5.png)
Minor Digression
If you get the error below on an Ubuntu VM/EC2...
![](https://hestia.ghost.io/content/images/2024/05/image-7.png)
.. 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.
terraform validate -json
![](https://hestia.ghost.io/content/images/2024/05/image-6.png)
Step 5: Execute terraform plan
terraform plan
![](https://hestia.ghost.io/content/images/2024/05/image-8.png)
Step 6: Execute terraform apply
terraform apply
![](https://hestia.ghost.io/content/images/2024/05/image-9.png)
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.
![](https://hestia.ghost.io/content/images/2024/05/image-10.png)
![](https://hestia.ghost.io/content/images/2024/05/image-11.png)
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.
![](https://hestia.ghost.io/content/images/2024/05/image-12.png)
Step 9: Optionally use terraform destroy to remove the Container and Image.
docker container stop <name of container>
docker container rm <name of container>
![](https://hestia.ghost.io/content/images/2024/05/image-13.png)
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.