This section focuses on exam objectives and assumes a working knowledge of Terraform and its workflow. To review syntax and structure, see Hello, Terraform.
The following table outlines how the workflow changes based on the number of users. Infrastructure as Code enables GitOps for team management.
User | Write | Plan | Apply |
Individual | Create the Terraform files | Run terraform plan
|
Create the infrastructure |
Team | Create the Terraform files and checkout the latest code | Run terraform plan and raise a PR
|
Merge and create |
Terraform Cloud | Use Terraform Cloud as development environment (i.e. manage state files, variables, and secrets) | When a PR is raised, terraform plan is run
|
Before merging a second plan is run before approval to create resources
|
The terraform init
command initializes a working directory containing Terraform configuration files. The command only initializes and never deletes an existing configuration or state, therefore is safe to run the command multiple times. During init
, the root configuration directory is consulted for backend configuration and the selected backend is initialized using the defined configuration settings. The following are common flags used with the terraform init
command:
terraform init -upgrade
- upgrade modules and pluginsterraform init -backend=false
- skip backend initializationterraform init -get=false
- skip child module installationterraform init -get-plugins=false
- skip plugin installation
The terraform validate
command validates the configuration files in a directory. Any remote services (i.e. remote state, provider APIs) are not validated, only the configuration files themselves. Validate runs checks to verify whether a configuration is syntactically valid and internally consistent, regardless of any provided variables or existing state. This provides a general validation of the modules, including correctness of attribute names and value types.
Note: terraform validate requires an initialized working directory with any referenced plugins and modules installed.
The terraform plan
command creates an execution plan. Terraform performs a refresh, unless explicitly disabled, and then determines what actions are required to achieve the desired state defined in the configuration files. The following are common flags used with the terraform plan
command:
terraform plan -out=tfplan
- saves execution planterraform apply tfplan
- applies execution planterraform plan -detailed-exitcode
- returns a detailed exit code when the command exitsterraform plan -refresh=true
- update the state prior to plan
The terraform apply
command applies the changes required for reaching the desired state of the configuration, or the predetermined set of actions generated by a terraform plan
execution plan.
The terraform destroy
command is used to deprovision and destroy the Terraform-managed resources.
There are two types of dependencies managed by Terraform: implicit and explicit.
Implicit dependency is achieved through studying resource attributes used in interpolation expressions. Terraform can automatically determine when one resource is dependent upon another. This dependency information by Terraform to determine the correct order in which to provision the resources.
In the example below, the reference to aws_instance.example.id
creates an implicit dependency on the aws_instance
named example:
resource "aws_instance" "example" {
ami = "ami-b374d5a5"
instance_type = "t2.micro"
}
resource "aws_eip" "ip" {
vpc = true
instance = aws_instance.example.id
}
Implicit dependencies through interpolation expressions are the primary way to express these dependent relationships, and should be used when possible.
However, there are sometimes dependencies between resources that are not visible to Terraform. An explicit dependency can be used to declare this relationship:
resource "aws_instance" "example" {
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
depends_on = [aws_iam_role_policy.example]
}
The depends_on
argument is accepted by any resource and accepts a list of resources for which to create explicit dependencies.