« Previous 1 2
Infrastructure as Code with Terraform
Blueprint
Accessibility
Admins can deploy the Provisioner [9] on resources. Terraform either runs this locally or – with the corresponding connection data – remotely by SSH or WinRM. For example, if you have created a VM, you can store the public IP in a local file on your own workstation or, as in this example, pass remote-exec
to the Provisioner, which then runs a command on the droplet you created, thus launching a Docker container.
Before Terraform creates the Cloudflare configuration, you need to test the configuration up to this point. To do this, you first need to start an initialization process with terraform init
(Figure 1) that searches all .tf
files for providers, checks to see whether the corresponding provider definitions already exist, and downloads them if necessary. You always need to run the command when new providers are used in Terraform configurations.
The command to check the extent to which the infrastructure described in the previous configurations has already been provisioned is
terraform plan -out digitalocean-plan
as shown in Listing 4. Because no infrastructure is in place as yet, Terraform generates all configured resources.
Listing 4
Testing Infrastructure
01 $ terraform plan -out digitalocean-plan 02 Refreshing Terraform state in-memory before plan... 03 [...] 04 An execution plan has been generated and is shown below. 05 Resource actions are indicated with the following symbols: 06 + create 07 Terraform will perform the following actions: 08 + digitalocean_droplet.mywebapp 09 id: <computed> 10 image: "docker-16-04" 11 [...] 12 + digitalocean_ssh_key.jondoe 13 id: <computed> 14 name: "Jon's key" 15 [...] 16 Plan: 2 to add, 0 to change, 0 to destroy.
The -out
parameter generates a plan that guarantees that Terraform does exactly what the output is currently displaying. This is especially important in production environments, because something can change between the input of the terraform plan
command and the actual implementation of the infrastructure or configuration. For example, Terraform ensures you approve a certain plan as part of a change process and that the software really only implements the changes stored there.
A simple
terraform apply digitalocean-plan
(Figure 2) then tells Terraform to implement the configuration recorded in the digitalocean-plan
plan. The step creates or implements the components described above. The last line shows the previously configured IP address of the droplet (not shown) and checks in the browser whether the outside world can reach the web server in the container.
Once the Docker droplet has been created, Terraform also creates a new subdomain for the web application on Cloudflare and adds to it the IP address of the droplet. Terraform needs the cloudflare.tf
file (Listing 5) for this, which loads the Cloudflare provider. You can then use the cloudflare_record
resource (line 6), which then implements the changes for Cloudflare on the DNS server. Here again, Terraform wants to access a variable that does not exist until after the software has generated the droplet at DigitalOcean.
Listing 5
cloudflare.tf
01 provider "cloudflare" { 02 email = "${var.cloudflare_email}" 03 token = "${var.cloudflare_token}" 04 } 05 06 resource "cloudflare_record" "mywebapp" { 07 domain = "${var.cloudflare_domain}" 08 name = "terraform" 12 proxied = true 11 ttl = 120 10 type = "A" 09 value = "${digitalocean_droplet.mywebapp.ipv4_address}" 13 provisioner "local-exec" { 14 command = "firefox ${cloudflare_record.mywebapp.hostname}" 15 } 16 } 17 18 output "Website:" { 19 value = "${cloudflare_record.mywebapp.hostname}" 20 }
To create a DNS entry, Terraform needs the public IP address that is in the digitalocean_droplet.mywebapp.ipv4_address
attribute of the droplet. Once the cloudflare_record
is created, the local-exec
provisioner launches Firefox and loads a page with the configured URL.
Thanks to this configuration, Terraform should display the IP addresses and domain names of the websites from which the users access the container. The name is provided by the value in cloudflare_record.mywebapp.hostname
.
Make sure Terraform finds all the dependencies for the new cloudflare
provider (Listing 5, line 1) by running terraform init
. To continue with the deployment,
terraform plan -out cloudflare-plan
creates a new plan describing what Terraform would do (Figure 3). As it turns out, it would only provide the Cloudflare resource here. The call does not change the other resources because they have already been provisioned.
The command in Figure 4,
terraform apply cloudflare-plan
adapts or extends the infrastructure by adding the Cloudflare component. Users can subsequently reach the website at the configured address, which is also in the command output. A quick check in the browser of the URL specified in terraform.tfvars
is sufficient to test whether the website exists.
Reset Application
To avoid the need to delete every single component manually, you can remove the provisioned infrastructure with:
terraform destroy
However, nothing happens without explicit confirmation by typing yes
in the dialog, which is a good thing, because you will not want the infrastructure to disappear as the result of an accidental destroy
command without due consideration.
Conclusions
The example shows how Terraform succeeds in providing infrastructure and expanding it dynamically. The plan
subcommand displays planned changes beforehand, allowing for a review. If you delete a DNS entry (e.g., Cloudflare's), Terraform identifies this change and corrects it with apply
. This confirmation does not affect other resources. Because many providers already exist, it is quite easy to enter the world of Infrastructure as Code, thanks to Terraform.
Infos
- Terraform: https://www.terraform.io
- Provider: https://www.terraform.io/docs/providers/index.html
- DigitalOcean: https://digitalocean.com
- Terraform download: https://www.terraform.io/downloads.html
- DigitalOcean API: https://www.digitalocean.com/community/tutorials/how-to-use-the-digitalocean-api-v2
- Installing Cloudflare API key: https://support.cloudflare.com/hc/en-us/articles/200167836-Where-do-I-find-my-Cloudflare-API-key-
- ssh_key: https://www.terraform.io/docs/providers/do/r/ssh_key.html
- Resolving dependencies: https://www.terraform.io/intro/getting-started/dependencies.html
- Provisioners: https://www.terraform.io/docs/provisioners/index.html
« Previous 1 2
Buy this article as PDF
(incl. VAT)