How To Use Terraform for Provisioning A Docker Container?

Relia Software

Relia Software

Thuoc Nguyen

Relia Software

development

Terraform, an open-source infrastructure as code (IaC) tool developed by HashiCorp, stands at the forefront of efficient infrastructure management.

How To Use Terraform for Provisioning A Docker Container?

Table of Contents

The guide aims to delve into the practical application of Terraform for a specific, yet fundamental task: provisioning a virtual machine (VM) and a Docker container on a local machine. Tailored for DevOps engineers, software developers, and IT professionals, this guide will navigate through the process of setting up Terraform, crafting and executing configuration files for a VM and Docker container, all within the local environment.

By mastering these skills, readers can apply them to real-world scenarios such as establishing consistent development environments or automating local test environment provisioning, thereby aligning with the dynamic demands of modern software development.

>> Read more about DevOps:

Introduction To Terraform

Terraform, an open-source infrastructure as code (IaC) tool developed by HashiCorp, stands at the forefront of efficient infrastructure management. It allows for the building, changing, and versioning of infrastructure, supporting a wide range of providers from cloud services like AWS, Azure, Google Cloud, to on-premises resources.

The essence of IaC, which Terraform exemplifies, lies in its ability to manage and provision infrastructure through code rather than manual processes. This approach brings numerous benefits, including faster deployment, consistent environments, scalability, and risk reduction through version control and automated testing. It also plays a pivotal role in the DevOps world, fostering better collaboration between development and operations teams.

Terraform Syntax and Files

The foundation of Terraform's functionality lies in its unique HashiCorp Configuration Language (HCL), designed to strike a balance between human readability and machine friendliness. HCL is a declarative language used to describe the desired state of infrastructure resources. It allows for concise descriptions of resources, their attributes, and dependencies, making it an integral part of Terraform's ease of use.

Terraform Files

Terraform files, typically ending in .tf, are the blueprints where this language is applied. These files contain all the necessary configurations to manage infrastructure. The structure of a .tf file is both logical and intuitive, consisting of blocks, arguments, and expressions. Blocks are containers for holding configurations related to a specific aspect of the infrastructure, such as a provider or resource.

Providers

Speaking of providers, they are a foundational concept in Terraform. A provider is a plugin that Terraform uses to interact with cloud providers, SaaS providers, and other APIs. Each provider offers a set of named resource types and each resource type manages a specific type of infrastructure, like a virtual machine, network interface, or DNS entry.

Resources

Resources are another critical concept. They represent infrastructure objects that Terraform can manage, ranging from lower-level components such as physical machines and VMs to higher-level components like DNS records and SaaS features.

Variables

Variables in Terraform allow for the customization of configurations without altering the core code. They can be predefined in the Terraform files or injected at runtime, providing flexibility and reusability of the code. Variables make Terraform configurations more dynamic and adaptable to different environments or scenarios.

Outputs

Outputs are a way to extract useful information from the Terraform-managed infrastructure. They can be used to display certain values on the console after Terraform runs or to pass information between modules or to other external resources.

Provisioning A Docker Container Locally with Terraform

Docker has revolutionized the way we think about deploying and managing applications. It's a platform that uses container technology to enable you to package an application with all its dependencies into a standardized unit for software development.

Containers are executable, lightweight, and standalone software packages that contain all the necessary components for the operation of an application, including code, runtime, system tools, system libraries, and settings. Docker provides an isolated environment for these containers, making them portable and consistent across various development, testing, and production environments.

First up we are going to use the code block below, the outcome of the below is that we would like a simple web app to be deployed into docker and to publish this so that it is available to our network. We will be using nginx and we will make this available externally on our laptop over localhost and port 8000. We are using a docker provider from the community and you can see the docker image we are using also stated in our configuration.

terraform {
  required_providers {
    # We recommend pinning to the specific version of the Docker Provider you're using
    # since new versions are released frequently
    docker = {
      source  = "kreuzwerker/docker"
      version = "3.0.2"
    }
  }
}

# Configure the docker provider
provider "docker" {
}

# Create a docker image resource
# -> docker pull nginx:latest
resource "docker_image" "nginx" {
  name         = "nginx:latest"
  keep_locally = true
}

# Create a docker container resource
# -> same as 'docker run --name nginx -p8080:80 -d nginx:latest'
resource "docker_container" "nginx" {
  name  = "nginx"
  image = docker_image.nginx.image_id

  ports {
    external = 8080
    internal = 80
  }
}

Then we can use terraform init command to download the provider to our local machine.

use terraform init command to download the provider
Use terraform init command to download the provider.

Now, we run terraform apply and waiting terraform provisioning for us the nginx container. To make sure the nginx container is created successfully, try to run docker ps command. If everything is good, we will see this screen.

run terraform apply and waiting terraform provisioning for us the nginx container
Run terraform apply and waiting terraform provisioning for us the nginx container.

Let try to open your browser and access to http://localhost:8000. You will see you have access to our nginx container.

you have access to our nginx container
You have access to our nginx container.

You can access to this link to find out more information for the Docker Provider: https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs/resources/container

We will provide another example to demonstrate that Terraform could be handle a little more complexity. We are going to take the docker-compose file for WordPress and MySQL and try to handle it by using Terraform.

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

provider "docker" {}

variable wordpress_port {
  default = "8080"
}

resource "docker_volume" "db_data" {
  name = "db_data"
}

resource "docker_network" "wordpress_net" {
  name = "wordpress_net"
}

resource "docker_container" "db" {
  name  = "db"
  image = "mysql:8.3.0"
  restart = "always"
  network_mode = "wordpress_net"
  env = [
     "MYSQL_ROOT_PASSWORD=wordpress",
     "MYSQL_PASSWORD=wordpress",
     "MYSQL_USER=wordpress",
     "MYSQL_DATABASE=wordpress"
  ]
  mounts {
    type = "volume"
    target = "/var/lib/mysql"
    source = "db_data"
    }
}

resource "docker_container" "wordpress" {
  name  = "wordpress"
  image = "wordpress:latest"
  restart = "always"
  network_mode = "wordpress_net"
  env = [
    "WORDPRESS_DB_HOST=db:3306",
    "WORDPRESS_DB_USER=wordpress",
    "WORDPRESS_DB_NAME=wordpress",
    "WORDPRESS_DB_PASSWORD=wordpress"
  ]
  ports {
    internal = "80"
    external = "${var.wordpress_port}"
  }
}

We still run the terraform init command to download 3rd libraries to our local machine.

run the terraform init command to download 3rd libraries
Run the terraform init command to download 3rd libraries.

Then run the terraform apply and waiting a few minutes before Terraform will help to provision the resource in docker.

Terraform will help provision the resource in docker
Terraform will help provision the resource in Docker.

We can run docker ps command to see the result as the images below:

run docker ps command
Run docker ps command.

We can also navigate to our WordPress frontend by access to http://localhost:8080/wp-admin/install.php. If you see the result as image below. Congratulation! You are completed this practices.

wordpress front end
Wordpress frontend.

Conclusion

As we conclude our guide on using Terraform for provisioning Docker containers, it's evident that the journey into the depths of Terraform and containerization is just beginning. Terraform's versatility in infrastructure management and Docker's efficiency in containerization open up a world of possibilities for optimizing and scaling environments.

For those keen to delve deeper, a wealth of resources awaits. The official Terraform documentation and Docker documentation are invaluable for detailed understanding and keeping up with new features.

In conclusion, your journey with Terraform and Docker is bound to be enriching and transformative. As you explore, experiment, and learn, you're not just building infrastructure or applications; you're building a future-ready skillset that's highly valued in the world of cloud computing and DevOps.

>>> Follow and Contact Relia Software for more information!