Enhanced backend in Terraform means a backend that can store state AND perform operations for configuration management.
Terraform has 2 enhanced backends that can store state and execute operations:
-
local
backend (default, stored locally) -
remote
backend (used in Terraform Cloud)
We worked with local
backend quite extensively throughout these series. This article will show how to use Terraform Cloud and remote
backend that will allow us to store backend remotely and execute commands like plan
and apply
with the output showing in the local terminal.
In this article we will setup our Terraform configuration to work with Terraform Cloud and a remote
backend.
Here is the plan for this tutorial:
- Create a workspace
- Setup
remote
backend in our configuration - Initialize our Terraform configuration
- Add AWS access tokens to the Terraform Cloud to allow remote execution of commands
The code for this tutorial can be found HERE
In a previous article I covered how to create a Terraform Cloud account and an organization.
In order to proceed you will need to login into your Terraform Cloud account and get the name of your organization:
We will also need a workspace for our. Click on "New workspace". Make sure that you have selected the correct organization.
Select the CLI-driven workflow
:
Enter the name (optionally add description) and press Create workspace
:
And our organization has a new workspace. Good job!
Now we will see how to use it in our configuration. First, let's create a remote backend and point Terraform to it. Make sure that you put the correct organization and workspace names:
# terraform.tf
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "terraform-blog"
workspaces {
name = "demo-app-on-aws"
}
}
}
It is assumed that you done terraform login
and added Terraform API token.
Since we changed the settings we need to reinitialize Terraform:
$ terraform init
# Output
Initializing modules...
Initializing the backend...
Successfully configured the backend "remote"! Terraform will automatically
use this backend unless the backend configuration changes.
If you get this error:
│ The "remote" backend encountered an unexpected error while reading the
│ organization settings: unauthorized
It means that your Terraform Cloud API token is not valid anymore. This problem can be fixed by running terraform login
and going the steps. You can also find a step-by-step guide in this article.
Let's see what happens when we try to execute a dry-run:
$ terraform plan
# Output
Running plan in the remote backend. Output will stream here. Pressing Ctrl-C
will stop streaming the logs, but will not stop the plan running remotely.
Preparing the remote plan...
To view this run in a browser, visit:
https://app.terraform.io/app/terraform-blog/demo-app-on-aws/runs/run-fACfrx3XtjhNh1zW
Waiting for the plan to start...
Terraform v1.2.4
on linux_amd64
Initializing plugins and modules...
╷
│ Error: error configuring Terraform AWS Provider: no valid credential sources for Terraform AWS Provider found.
│
│ Please see https://registry.terraform.io/providers/hashicorp/aws
│ for more information about providing credentials.
│
│ Error: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, request send failed, Get "http://169.254.169.254/latest/meta-data/iam/security-credentials/": dial tcp 169.254.169.254:80: i/o timeout
│
│
│ with provider["registry.terraform.io/hashicorp/aws"],
│ on main.tf line 3, in provider "aws":
│ 3: provider "aws" {
│
╵
Operation failed: failed running terraform plan (exit 1)
We are interested in the first part of the output indicating that plan is running remotely:
Running plan in the remote backend. Output will stream here. Pressing Ctrl-C
will stop streaming the logs, but will not stop the plan running remotely.
Preparing the remote plan...
To view this run in a browser, visit:
https://app.terraform.io/app/terraform-blog/demo-app-on-aws/
Waiting for the plan to start...
We also got an error stating that we did not provide valid credentials for the AWS provider.
Terraform Cloud allows us to add credentials as environment variables inside the workspace. Please note that you need your AWS_ACCESS_KEY
and AWS_SECRET_ACCESS_KEY
to complete the next step.
Select your workspace. You will see a Variable
tab at the top. Click that and you will arrive at the screen where you can add environment variables. That's where we will put our AWS credentials that will allow Terraform to deploy resources remotely.
Now it's time to add our AWS access tokens to the environment. Select Environment variable
radio button. AWS_SECRET_ACCESS_TOKEN
will need to have the "sensitive" checkbox selected. This is important. Value field is where the actual key will go. See the picture for details:
This how it is supposed to look like after you are done. Pay attention how AWS_ACCESS_KEY
is public, yet AWS_SECRET_ACCESS_KEY
is private.
Let's do another dry to verify that Terraform can use access to manage the infrastructure:
$ terraform plan
# output
Running plan in the remote backend. Output will stream here. Pressing Ctrl-C
will stop streaming the logs, but will not stop the plan running remotely.
Preparing the remote plan...
To view this run in a browser, visit:
https://app.terraform.io/app/terraform-blog/demo-app-on-aws/
Waiting for the plan to start...
# lots of output here with resources
Plan: 25 to add, 0 to change, 0 to destroy.
And let's apply the changes:
$ terraform apply
# lots of output but you should see this at the end
Apply complete! Resources: 25 added, 0 changed, 0 destroyed.
Verify that resources with the list command:
$ terraform state list
data.aws_ami.ubuntu
data.aws_availability_zones.available
data.aws_region.current
aws_eip.nat_gateway_eip
aws_internet_gateway.internet_gateway
aws_nat_gateway.nat_gateway
aws_route_table.private_route_table
aws_route_table.public_route_table
aws_route_table_association.private
aws_route_table_association.public
aws_security_group.private_sg
aws_security_group.public_sg
aws_security_group_rule.private_in
aws_security_group_rule.private_out
aws_security_group_rule.public_http_in
aws_security_group_rule.public_https_in
aws_security_group_rule.public_out
aws_security_group_rule.public_ssh_in
aws_subnet.private_subnet
aws_subnet.public_subnet
aws_vpc.vpc
module._server_from_local_module.data.aws_ami.ubuntu
module._server_from_local_module.aws_instance.web_server
module.another_server_from_a_module.data.aws_ami.ubuntu
module.another_server_from_a_module.aws_instance.web_server
module.autoscaling_from_github.data.aws_default_tags.current
module.autoscaling_from_github.data.aws_partition.current
module.autoscaling_from_github.aws_autoscaling_group.this[0]
module.autoscaling_from_github.aws_launch_template.this[0]
module.autoscaling_from_registry.data.aws_default_tags.current
module.autoscaling_from_registry.data.aws_partition.current
module.autoscaling_from_registry.aws_autoscaling_group.this[0]
module.autoscaling_from_registry.aws_launch_template.this[0]
module.my_server_module.data.aws_ami.ubuntu
module.my_server_module.aws_instance.web_server
Awesome! We have connected Terraform Cloud, added AWS API tokens in a secure manner. Now we can create, modify, and destroy resources using our local terminal with the state store remotely.
Finally, let's destroy the resources:
$ terraform destroy
# output
Apply complete! Resources: 0 added, 0 changed, 25 destroyed.
You can also view the history of commands executed by this backend by clicking on Runs
tab within your organization:
This wraps up this tutorial. Thank you for reading! See you in the next article.
Top comments (0)