Managing Applications and Infrastructure with Terraform-Deploying Infrastructure with Terraform-(1)Terraform Basics and a Docker Deployment-(2)Your First Script
Managing Applications and Infrastructure with Terraform-Deploying Infrastructure with Terraform
1. Terraform Basics and a Docker Deployment
2. Your First Script
Terraform is used to create, manage, and update infrastructure resources such as physical machines, VMs, network switches, containers, and more. Almost any infrastructure type can be represented as a resource in Terraform.
A provider is responsible for understanding API interactions and exposing resources. Most providers configure a specific infrastructure platform (either cloud or self-hosted). Providers can also offer local utilities for tasks like generating random numbers for unique resource names.
Providers
https://www.terraform.io/docs/providers/index.html
See the main list of historical providers below.
Alicloud
https://www.terraform.io/docs/providers/alicloud/index.html
AWS
https://www.terraform.io/docs/providers/aws/index.html
Google Cloud
https://www.terraform.io/docs/providers/google/index.html
Docker
https://www.terraform.io/docs/providers/docker/index.html
/home/ubuntu# mkdir docker && cd docker
Resources are the most important element in the Terraform language. Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.
/home/ubuntu/docker# vim main.tf
# Download the latest Ghost image resource "docker_image" "image_id" { name = "ghost:latest" }
ATTN
On Terraform version 0.13, only above main.tf is not enough to execute the "terraform init" command successfully. It is expected to get below error:
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/docker... Error: Failed to install providers Could not find required providers, but found possible alternatives: hashicorp/docker -> terraform-providers/docker If these suggestions look correct, upgrade your configuration with the following command: terraform 0.13upgrade .For the root cause explanation, refer to Check Terraform 0.13 Compatibility #118.
Modify the main.tf to add another block.
~/docker# vim main.tf
terraform { required_providers { aws = { source = "hashicorp/aws" } docker = { source = "terraform-providers/docker" } } required_version = ">= 0.13" } # Download the latest Ghost image resource "docker_image" "image_id" { name = "ghost:latest"
Initialize a working directory containing Terraform configuration files.
~/docker# terraform init
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Finding latest version of terraform-providers/docker... - Installing hashicorp/aws v3.9.0... - Installed hashicorp/aws v3.9.0 (signed by HashiCorp) - Installing terraform-providers/docker v2.7.2... - Installed terraform-providers/docker v2.7.2 (signed by HashiCorp) The following providers do not have any version constraints in configuration, so the latest version was installed. To prevent automatic upgrades to new major versions that may contain breaking changes, we recommend adding version constraints in a required_providers block in your configuration, with the constraint strings suggested below. * hashicorp/aws: version = "~> 3.9.0" * terraform-providers/docker: version = "~> 2.7.2" Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.
provider.docker has been downloaded
providers stored in the terraform folder
~/docker# ll
total 16 drwxr-xr-x 3 root root 4096 Oct 7 11:28 ./ drwx------ 6 root root 4096 Oct 7 11:28 ../ drwxr-xr-x 3 root root 4096 Oct 7 11:16 .terraform/ -rw-r--r-- 1 root root 284 Oct 7 11:23 main.tf
~/docker# ls .terraform/plugins/
registry.terraform.io selections.json
root@ip-10-0-0-70:~/docker# tree .terraform/plugins/registry.terraform.io/
.terraform/plugins/registry.terraform.io/ ├── hashicorp │ └── aws │ └── 3.9.0 │ └── linux_amd64 │ └── terraform-provider-aws_v3.9.0_x5 └── terraform-providers └── docker └── 2.7.2 └── linux_amd64 └── terraform-provider-docker_v2.7.2_x4 8 directories, 2 files
ATTN
~/docker# ls .terraform/plugins/
linux_amd64
/home/ubuntu/docker# ls .terraform/plugins/linux_amd64/
lock.json terraform-provider-docker_v1.0.2_x4
root@ip-172-31-18-169:/home/ubuntu/docker# ls
main.tf
Create an execution plan. Terraform performs a refresh, unless explicitly disabled, and then determines what actions are necessary to achieve the desired state specified in the configuration files.
~/docker# terraform plan
Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # docker_image.image_id will be created + resource "docker_image" "image_id" { + id = (known after apply) + latest = (known after apply) + name = "ghost:latest" } Plan: 1 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
Apply the changes required to reach the desired state of the configuration, or the pre-determined set of actions generated by a terraform plan execution plan.
~/docker# terraform apply
An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # docker_image.image_id will be created + resource "docker_image" "image_id" { + id = (known after apply) + latest = (known after apply) + name = "ghost:latest" } Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes docker_image.image_id: Creating... docker_image.image_id: Still creating... [10s elapsed] docker_image.image_id: Still creating... [21s elapsed] docker_image.image_id: Creation complete after 25s [id=sha256:98c65d66926b2da9fbb696d43aadfaf3fee847b7185e132e199532bc549aeba5ghost:latest] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Provide human-readable output from a state or plan file.
~/docker# terraform show
docker_image.image_id: id = sha256:5d42eda6891259afd89cab3a0f005c18735a17628a74d9bf3f85d17756928c73ghost:latest latest = sha256:5d42eda6891259afd89cab3a0f005c18735a17628a74d9bf3f85d17756928c73 name = ghost:latest
~/docker# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE ghost latest 98c65d66926b 13 hours ago 438MB
In this post, we used a very simple main.tf to build a Docker image. We saw there is a different of diretory structure between Terraform version 0.13 and 0.11. By the end of this demonstration, we verified that a new Docker image has been successfully built using Terraform.
References
Resources
Terraform Commands (CLI)
Command: init
Command: plan
Command: apply
Command: show