The hungovercoders template.azure.terraform repo is now an absolute beast and a template I frequently use as a starting point for any codebases that will deploy infrastructure to Azure. However, I wanted to know if there was a way to fast-track anyone who doesn’t want to convert their ARM or bicep from first principles into terraform… The answer is yes and it is aztfexport! Lets crack open a can and automate those terraform files!

Prerequisites

You can either:

OR you will need to install:

Note: For the last three tools I used homebrew to install as part of the docker container for the cloud developer environment that the template produces, see here for details. If you have brew available on your local machine this might be an easier option.

I certainly prefer option (1) as its all done for me. The methods and screenshots below will be based on the template cloud developer environment, but it will still all be relevant to if you perform the tasks locally.

Import the Resources

First ensure you have an empty directory and navigate to that directory by running the following in a terminal:

mkdir tfexport
cd tfexport

You’ll then want to select a resource group that you have permissions on with the account your authenticated with. If you’re using the template repo this will be the account that you have setup with. If you want to do this locally or if you want to change to your individual account for the import, execute the following to change the context to you and the appropriate subscription the resource group resides in, otherwise carry on to the next step.

az login --use-device-code
az account set --subscription "your_subcription_name"
az account show

The resource group I have chose contains:

  • A hello world container app
  • A key vault
  • A serverless cosmos database

Resource Group Original

Run the following command from that directory with the rg parameter taking in the resource group you want to import. The below imports a resource group called “lrn-containerapp-rg-hngc” from the subscription we have authenticated against in the previous setup steps.

aztfexport rg lrn-containerapp-rg-hngc

You should see “initializing” in the terminal.

Aztfexport Initializing

Sometimes there are a load of “skips” you might see as it does not have the ability to import absolutely everything, but this hasn’t been a problem for me so far as they are usually “behind the scenes” type resources. There are a number of options present though and so for now I choose “w” which is just the import all option.

Aztfexport Options

You’ll then see “importing” if it has kicked off correctly.

Aztfexport Importing

After a period you should see the appropriate terraform files in the directory that you can use as a starting point.

Aztfexport Imported

Validate Terraform Resources with Plan

You can then run a terraform plan from the tfexport directory to validate the infrastructure is as you expect with “no changes” in the output.

terraform plan

Terraform Plan

Add a New Resource

You can quickly make changes to this infrastructure if you wanted. for example if we added the following storage account terraform in the main.tf file:

resource "azurerm_storage_account" "storage" {
  name                     = "lrnhelloworldsaeunhngc"
  resource_group_name      = "${var.environment_shortcode}-containerapp-rg-hngc"
  location                 = "northeurope"
  account_tier             = "Standard"
  account_replication_type = "LRS"
  account_kind             = "StorageV2"
   tags = {
    team = "hungovercoders"
  }
}

Then run terraform plan you can see we immediately have our new infrastructure in code and part of the state ready to add.

Terraform Plan Add

Apply to a New Resource Group

We’ll keep this simple and pretend we’re going to take this resource group from learning environment (lrn) to the production environment. To do this we’re going to create an environment variable and allow us to pass that in to change anything referencing “lrn” to “prd”.

We’ll first need to delete the terraform files and migrate the state so that the local state knows that we are going to start referencing brand new resources in a different environment.

Delete the following files and directories:

  • import.tf
  • .terraform.locl.hcl
  • .terraform directory

Then migrate the state:

terraform init -migrate-state

Terraform Migrate

Then amend the main.tf file to take in the variable and amend all the resources to reference this:

e.g.

variable "environment_shortcode" {
  type        = string
  description = "The is the environment shortcode for resources"
  validation {
    condition     = contains(["lrn", "dev", "prd"], var.environment)
    error_message = "The environment shortcode is not valid, it should be lrn, dev or prd."
  }
}

resource "azurerm_resource_group" "res-0" {
  location = "northeurope"
  name     = "${var.environment_shortcode}-containerapp-rg-hngc"
  tags = {
    team = "hungovercoders"
  }
}

##repeat for all resources referencing "lrn"

We now run terraform plan and we can see that resources are going to be added.

terraform plan

Terraform Plan New

Run terraform apply and watch the new resource group get created identical to the learning environment but in “production”.

terraform apply

Terraform Apply New

In this example the resource group at the end looks like the below which is identical but in a “prd” environment instead.

Resource Group New

Use the Template

If you’re using the template you can move the imported code into the terraform folder and start tweaking it to meet your needs. This becomes a really quick start to import azure resources into terraform, utilise a cloud developer environment with all the tooling ready and a github actions pipeline ready for you to deploy. Now that is a happy new year!