Interacting with Docker
In this section, we will be covering some broad basics on how to use Terraform, creating resources, and planning builds. This is by no means comprehensive but aims to give you a general idea on Terraform and how to write HCL code.
First Steps
Terraform works by interacting with a provider such as docker or other supported applications (available in the Terraform registry). To use a provider, we can copy the code block that they provide and paste it in our main.tf file - we will go over how to structure our project later on.
Now that we have a provider specified, we can start adding containers to the mix. In the Terraform Registry, we can see a couple of resources which we can utilise in our code

Let's start with the container resource. Select the docker_container tab then view the example provided:
First, Terraform is going to look for the latest image of Ubuntu precise, which we will then reference the ID of when starting the container

To reference an item, we need to specify the resource type (docker_image) and name (ubuntu) then the item that we want to fetch (image_id).
Using this example, we can go to Docker Hub and pick out an application to deploy - below is an example using Nginx
To make the code cleaner, we can give the resource name a prefix to ensure that it is self documenting (container_ or image_ etc.)
Now that we have our basic Terraform script ready, we can initialise and apply our code by running the following in our terminal:

If successful, we should be able to see the following output and verify by running docker ps


We will notice however that if we try to visit the nginx proxy at http://<docker_instance_ip>, we will receive an error. This is because we are not exposing any container ports which are accessible. To do this, we can revisit the Docker Registry to see the required schema:

Let us update our main.tf file to reflect the changes needed
We can now run terraform apply -auto-approve to update our container. Note that you do not need to run destroy as Terraform will review the plan and change anything that has been updated.

Now try to visit the web page at the external port you've specified

Success! If you have followed all the steps so far, you should have a working Terraform automation script. Let's tear down our infrastructure by running terraform destroy -auto-approve and look into how we can structure our project.
Structuring Terraform Projects
It is good practice to separate our main.tf file into multiple specialised files so it is easier to read and document. It will also come in handy when we want to modularise our project into a dev and prod version for example. The general files that are needed are:
main.tf
provider.tf
network.tf
resource.tf
You do not need to follow the same naming scheme, though it does help to have some form of consistency. Let us create these files, then separate our functions into them.
Make sure to test that your changes worked by running terraform plan.
We can also create a variables file to make it easier to switch out certain parts of our code such as the name of our container or the image version.
Update main and resource with the new variables and ensure that your codebase is clean by running terraform fmt
Great! However, the Nginx container variable might not make much sense - instead of specifying the container and its version, we can instead specify the version and change it inline
Running terraform plan should show you the version number alongside the container you picked
Shortening our Variable
We can use maps instead of having separate variable names to modify the same container to save on space and keep our code even cleaner - let us examine the required variables on our container
One issue with this is that we specified the map object to be of type string, but we included numbers inside of it. In this case, we can nest an object inside of our map, then specify the data type for each key. Note that you may not run into an issue for this when deploying but it's good for documentation.
Now we can go to our other files and modify their attributes by using var.nginx_container.x
You can make this as complex or as simple as you'd like. If you want more info on how to use variables, check out this blog.
Deploying Multiple Containers
It's cool and good that we have a functional codebase, but it's practically useless right now. So, let us examine how we can use Terraform to deploy a web application using Nginx as the reverse proxy, and Apache Tomcat as the web server.
We can copy the nginx_container variable and re-use it for our Tomcat container
Next, we'll add Tomcat to our resource and main.tf files
Run terraform apply and check that your containers have deployed before moving the the next step.



Outputs
Finally, we have outputs. You can specify important data to display to the end user such as IP addresses, hosts, or passwords which they might need to use in order to access the resources that have been deployed by creating an outputs.tf file then referencing the Read-Only data generated by your resources.
If we run terraform apply -auto-approve now, we should get the output in our terminal window. If you clear this by accident, you can run terraform output to view the outputs. We will see better examples of this later on when we work with cloud resources.
Scripting Builds
This is not a lesson per-se, but some quality of life scripts to make deployment easier and faster.
PowerShell/BASH
Makefile
Last updated
Was this helpful?
