Skip to content

The main.tf File

Filename Location Group Project/Repository
main.tf ./main.tf infrastructure terraform

Why?

The purpose of the main.tf file is to store meta information and configuration that doesn't directly effect a remote provider, like AWS, Azure, etc. It's very useful for storing terraform {}, provider {} and other "meta" configuration blocks.

The name main is inherited from the common pattern in C/C++/Go programming in which the main() {} function is stored in a file called main.c, main.cpp, main.go, etc.

Breakdown

GitLab can store our state file for us. It can also lock it whilst we're working on it, which means others know we're manipulating the infrastructure. This prevents race conditions and is a very good idea.

When using GitLab CI the Terraform back end would configured automatically for us and our Terraform code would be simple versus what we have below. However because we want to be able to run this locally we have to do a bit of extra work locally to get this to work.

The first thing we have to do, whether we're using GitLab CI or running Terraform locally, is tell Terraform we're using a remote state storage mechanism:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# main.tf 

terraform {
  backend "http" {
      address           = "https://gitlab.com/api/v4/projects/26667064/terraform/state/production"
      lock_address      = "https://gitlab.com/api/v4/projects/26667064/terraform/state/production/lock"
      unlock_address    = "https://gitlab.com/api/v4/projects/26667064/terraform/state/production/lock"
      lock_method       = "POST"
      unlock_method     = "DELETE"
      retry_wait_min    = 5
  }

We've got to change a few values in the configuration as it will not work as is for you. That's because the project ID I have in my version of the code won't match your project ID. You'll need to update this.

The project ID is highlighted bold here gitlab.com/api/v4/projects/26667064/. It's present in all the gitlab.com URLs in the code, so make sure you update it to match the project ID for the terraform/infrastructure GitLab project.

The only other that's left to configure, which we haven't configured above, is the username and password used for authenticating. We don't want to hard code them into this configuration for somewhat obvious reasons:

  1. They'll be visible in the code and can be used by others do to nasty things
  2. They'll be present inside the Terraform state file

These two settings should be set as environment variables as per the documentation:

  • TF_HTTP_USERNAME
  • TF_HTTP_PASSWORD

The TF_HTTP_USERNAME environment variable is your GitLab username. That should be simple enough. The TF_HTTP_PASSWORD variable is the personal access token you created previously, in the GitLab account section of this book. Once these two environment variables have been set, you'll be ready to use Terraform locally.

The AWS Provider

We'll be building everything in Amazon Web Services. This means we'll need to use the AWS provider within Terraform, which in turn means we'll have to configure it with credentials.

Our provider configuration will look like this:

1
2
3
4
provider "aws" {
  region     = var.aws_region
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key

We'll be passing in the values the provider needs using Terraform (input) variables. In turn we'll actually be using environment variables to set these values.

The Solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# main.tf 

terraform {
  backend "http" {
      address           = "https://gitlab.com/api/v4/projects/26667064/terraform/state/production"
      lock_address      = "https://gitlab.com/api/v4/projects/26667064/terraform/state/production/lock"
      unlock_address    = "https://gitlab.com/api/v4/projects/26667064/terraform/state/production/lock"
      lock_method       = "POST"
      unlock_method     = "DELETE"
      retry_wait_min    = 5
  }
}

provider "aws" {
  region     = var.aws_region
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
}

Terraform Documentation

Type Documentation
terraform Terraform AWS Provider

Committing the Code

  1. Set your working directory to the infrastructure/terraform repository
  2. Save the file as main.tf and use git add main.tf to add it to the Git staging area
  3. Use git commit -am 'configuring terraform and our aws provider' to commit the file to our repository
  4. Push the code to GitLab.com: git push

Last update: August 29, 2021