Skip to main content

Command Palette

Search for a command to run...

3.4 Terraform with Docker: Managing Containers as Code

Updated
5 min readView as Markdown
3.4 Terraform with Docker: Managing Containers as Code

Terraform with Docker: Managing Containers as Code (Simplified!)

Containers are like shipping containers for your applications. Docker lets you create and manage these containers. But what if you have lots of containers, or complex setups across multiple environments? That's where Terraform comes in! Think of Terraform as a master blueprint for building and managing your entire container infrastructure.

What is Terraform?

Terraform is an "Infrastructure as Code" (IaC) tool. It lets you define your infrastructure (servers, networks, containers, etc.) using code, not by clicking around in a web interface. This code can be version controlled, reviewed, and automated, just like your application code.

Why use Terraform with Docker?

Imagine building a house. You could lay each brick by hand, measure everything manually, and hope it all fits. Or, you could use a blueprint to guide the construction, ensuring consistency and accuracy. Terraform is that blueprint for your Docker containers.

Here's why combining Terraform with Docker is a powerful combination:

  • Reproducibility: Deploy your container environment the same way every time, across different environments (development, staging, production).

  • Automation: Automate the creation, updating, and deletion of your container infrastructure. No more manual, error-prone steps!

  • Version Control: Track changes to your infrastructure code. Rollback to previous states if needed.

  • Collaboration: Teams can collaborate on infrastructure setup, using standard code review processes.

A Real-World Example: Deploying a Simple Web App

Let's say you want to deploy a simple web application using Docker on a cloud provider like AWS. Here's how Terraform can help:

# Configure the AWS provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-east-1" # Change to your desired region
}

# Create an EC2 instance (your server)
resource "aws_instance" "web_server" {
  ami           = "ami-0c55b9121719250c9" # Amazon Linux AMI ID
  instance_type = "t2.micro"
  key_name      = "my-key" # Your SSH key

  # Install Docker and run the web app
  user_data = <<-EOF
              #!/bin/bash
              sudo yum update -y
              sudo yum install docker -y
              sudo systemctl start docker
              sudo systemctl enable docker
              sudo docker run -d -p 80:80 nginx
              EOF

  tags = {
    Name = "Web Server"
  }
}

# Output the public IP address of the instance
output "public_ip" {
  value = aws_instance.web_server.public_ip
}

Explanation:

  1. Provider Configuration: The code tells Terraform we're using AWS and specifies the region.

  2. EC2 Instance Creation: We define an AWS EC2 instance (a virtual server) using the aws_instance resource. We specify the AMI (the operating system image), instance type, and SSH key.

  3. User Data (Initialization Script): The user_data section contains a shell script that runs when the instance starts. It installs Docker, starts the Docker service, and then runs an Nginx container, exposing port 80.

  4. Output: The output block displays the public IP address of the instance once it's created.

How to run this:

  1. Install Terraform: Download and install Terraform from https://www.terraform.io/downloads.

  2. Configure AWS Credentials: Configure your AWS credentials so Terraform can access your AWS account. You can do this using environment variables (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) or by configuring an IAM role.

  3. Save the code: Save the code above into a file named main.tf.

  4. Initialize Terraform: Run terraform init in the directory containing your main.tf file. This downloads the necessary provider plugins.

  5. Apply the configuration: Run terraform apply. Terraform will show you a plan of what it will create. Type yes to confirm.

  6. Access your web app: Once the process completes, Terraform will output the public IP address of the instance. Open that IP address in your web browser, and you should see the Nginx default page.

Diagram:

+---------------------+      Terraform Code (main.tf)
|                     |
| Terraform CLI       |-----> AWS Cloud Provider
| (terraform apply)   |      +-------------------+
|                     |      |                   |
+---------------------+      | EC2 Instance      |
                               | (running Docker)  |
                               |                   |
                               | Nginx Container   |
                               |                   |
                               +-------------------+

Challenge: Docker Image Updates

One common challenge is updating your Docker images. Let's say you updated your web app code and rebuilt your Docker image. How do you tell Terraform to update the running container on the EC2 instance?

Solution: Using docker run with an if-modified-since header to pull the image only if it is changed, and then restart the docker.

You can modify the user data section of your main.tf to achieve this:

user_data = <<-EOF
              #!/bin/bash
              sudo yum update -y
              sudo yum install docker -y
              sudo systemctl start docker
              sudo systemctl enable docker
              # Pull the latest image only if there is a new version
              sudo docker pull <your-docker-image>
              sudo docker stop <your-container-name> || true
              sudo docker rm <your-container-name> || true
              sudo docker run -d --name <your-container-name> -p 80:80 <your-docker-image>
              EOF

Replace <your-docker-image> and <your-container-name> with your actual Docker image name and container name. This script:

  1. Pulls the latest image.

  2. Stops the existing container (if it's running). || true ensures the script doesn't fail if the container doesn't exist.

  3. Removes the existing container (if it exists). || true ensures the script doesn't fail if the container doesn't exist.

  4. Runs a new container using the latest image.

When you run terraform apply again, Terraform will update the instance, and the script will pull the latest Docker image and restart the container. Make sure your Docker container name is consistent across deployments!

Conclusion

Terraform and Docker together empower you to manage your containerized applications as code. This leads to more reliable, reproducible, and maintainable deployments. Start with simple examples like the one above, and gradually build more complex infrastructure configurations. Happy coding!

More from this blog

TechZen

136 posts