Terraform¶
Our first stop is the Infrastructure As Code (IAC) that we wrote in Terraform. We're going to manually deploy this code from our local machines and review the results.
Prerequisites¶
Before we can get started we're going to have to set up a few environment variables so that Terraform can do two things:
- Authenticate against the GitLab API and fetch/store/lock the remote state file
- And authenticate against the AWS API so it can actually manage our infrastructure for us
Without setting up the credentials needed to make this work we're not going to be able to get much done.
To help you get started, here is a quick snippet of shell code you can copy/paste, update and then apply to your local environment:
1 2 3 4 5 |
|
Save this file as ~/.infrastructure.secrets
.
You'll need to supply the values for each of the variables.
GitLab¶
We're going to need access to the GitLab API. Without this access we cannot us our remote Terraform state storage inside of GitLab. Let's resolve this:
1 2 |
|
Note
I recommend you do not use your literal GitLab password here. Instead create an access token, which we discussed here.
AWS¶
We need to ensure we've got a few environment variables set up for our AWS credentials:
1 2 3 |
|
These are the values you will have set up and copied from the AWS console when you first created your account and then your first IAM user.
Update the Environment¶
Once this file has been created and set up, you can save is to disk and then apply it to your local (Linux/macOS) shell environment:
1 |
|
Then use export
to see a list of environment variable currently configured for your current shell/session. You should see your new infrastructure variables.
Now let's review the steps we're going to take to get Terraform to build out infrastructure.
Steps¶
So let's step through what we're going to be doing now that we've written all of our code:
- We're going to
terraform init
- We're going to
terraform plan -out latest.plan
- We will review the plan and discuss it
- Finally we will execute
terraform apply latest.plan
Once we've deployed all of our Terraform code, we will move onto the application and then, finally, Ansible.
Terraform Flow¶
When we use terraform plan
, this is what's happening behind the scenes (in a simplified manner):
graph LR
a[Plan] --> b[GitLab API]
b[Fetch Terraform State] --> c[AWS API]
c --> d[Fetch Remote State]
d --> e[Compare States]
e --> f[Output Plan File]
The plan file that is output (latest.plan
) contains everything Terraform knows about our current state, the remote state in AWS, the differences between the two and how-to align what exists remotely with what we want, as engineers, based on our code.
In short: Terraform is comparing your code (the .tf
files) to your state (terraform.tfstate
from the GitLab storage), then comparing the state to what you have remotely (in AWS) and calculating what has to happen. This is what a terraform plan
is doing for you.This is also true of terraform apply
when you don't provide it with a plan file.
When we eventually execute terraform apply latest.plan
we get this (simplified) flow:
graph LR
a[Read Plan] --> b[AWS API]
b --> c[Update State]
c --> d[Push State to Remote Storage]
So the apply
subcommand is actually implementing the plan, which results in changes to the remote AWS infrastructure, which are then saved to the state file that is then, finally, uploaded to GitLab and the Terraform remote state storage mechanism.
We're going to talk more about Terraform state files next. It's important you understand how critical this file is, how it's used, stored and how it should be managed.
Next¶
Now we're going to initialise our local Terraform configuration based on our code.