Difference between revisions of "Azure/Terraform"

From Ever changing code
Jump to navigation Jump to search
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Note|Content created pre Terraform version 0.12 }}
= Store Terraform state in Azure Storage =
= Store Terraform state in Azure Storage =
== Create blob storage ==
== Create blob storage ==
Line 28: Line 29:
echo "access_key: $ACCOUNT_KEY"
echo "access_key: $ACCOUNT_KEY"
</source>
</source>
= azurerm backend config =
<source lang=json>
terraform {
  required_version = "= 0.11.11"
# backend "local"  {}
  backend "azurerm" {
#                          tfstate<Subscription8chars>
    storage_account_name = "tfstate01234567" #only lowercase letters nad numbers unique across Azure
    container_name      = "infrarg"        #only lowercase letters and numbers
    key                  = "tfstate"        #state file name, when delimited with '/' will create a folder aka prefix in AWS
#  key                  = "stack/tfstate"
#  access_key          = "ARM_ACCESS_KEY"  #optional access_key in plain text it's advised to export variable
  }
}
</source>
Configure azurerm backend via <code>terraform init</code>. When you auth via:
* key - it's storage account token, nothing else is required
* Service Principal - you need to pass a resource group name provide ARM_client_id and ARM_client_secret credentials by explicitly in <code>backend {}</code> block or export them as environment variable.
<source lang=json>
terraform init -input=false \                                                                     
              -backend=true \                                                                     
              -backend-config="resource_group_name=${LOCATION_STATE_STORAGE_RESOURCE_GROUP_NAME}" \
              -backend-config="storage_account_name=${LOCATION_STATE_STORAGE_ACCOUNT}" \         
              -backend-config="container_name=${LOCATION_STATE_STORAGE_CONTAINER}" \             
              -backend-config="key=${LOCATION_STATE_KEY}"                                         
</source>
Using the <code>key</code> argument like in s3 backend you can store state files in hierarchy structure. Eg:
<source>
# High Level View
# https://<storage_account>.blob.core.windows.net/<container>/<key/tfstate>
# https://infrarg.blob.core.windows.net/tfstate/tfstate(state_file)
# https://infrarg.blob.core.windows.net/tfstate/stack  (folder)/terraform.tfstate(state_file)
# https://infrarg.blob.core.windows.net/tfstate/storage(folder)/terraform.tfstate(state_file)
</source>
Example changing state from <code>local</code> to <code>azurerm</code>. Note ''Previous'' and ''New'' temporarly saved state files.
<source>
Initializing the backend...
Backend configuration changed!
Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.
Terraform detected that the backend type changed from "local" to "azurerm".
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "local" backend to the
  newly configured "azurerm" backend. An existing non-empty state already exists in
  the new backend. The two states have been saved to temporary files that will be
  removed after responding to this query.
  Previous (type "local"): /tmp/terraform962571048/1-local.tfstate
  New      (type "azurerm"): /tmp/terraform962571048/2-azurerm.tfstate
  Do you want to overwrite the state in the new backend with the previous state?
  Enter "yes" to copy and "no" to start with the existing state in the newly
  configured "azurerm" backend.
  Enter a value: yes
Releasing state lock. This may take a few moments...
Successfully configured the backend "azurerm"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
Terraform has been successfully initialized!
</source>
Key notes:
* you must create resource_group and storage_account before migrating backend
* both container and full prefixed path aka folders will be created when needed
* when moving backend temporarly remove <code>-input=false</code> from <terraform init</code> command


= References =
= References =
*[https://docs.microsoft.com/en-us/azure/terraform/terraform-backend Store Terraform state in Azure Storage] official Ms docs
*[https://docs.microsoft.com/en-us/azure/terraform/terraform-backend Store Terraform state in Azure Storage] official Ms docs
*[https://www.terraform.io/docs/backends/types/azurerm.html azurerm Terraform backend] official Terraform doc
*[https://www.terraform.io/docs/backends/types/azurerm.html azurerm Terraform backend] official Terraform doc

Latest revision as of 17:32, 23 February 2020

Note: Content created pre Terraform version 0.12

Store Terraform state in Azure Storage

Create blob storage

export ARM_SUBSCRIPTION=aabbccdd-1122-11aa22bb3-11aa22bb33cc

#!/bin/bash

RESOURCE_GROUP_NAME=tfstate
STORAGE_ACCOUNT_NAME=tfstate${ARM_SUBSCRIPTION::8}
CONTAINER_NAME=tfstate
REGION=eastus

# Create resource group
az group create --name $RESOURCE_GROUP_NAME --location $REGION

# Create storage account
az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME \
                         --sku Standard_LRS --encryption-services blob

# Get storage account key
ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query [0].value -o tsv)

# Create blob container
az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME --account-key $ACCOUNT_KEY

echo "storage_account_name: $STORAGE_ACCOUNT_NAME"
echo "container_name: $CONTAINER_NAME"
echo "access_key: $ACCOUNT_KEY"

azurerm backend config

terraform {
  required_version = "= 0.11.11"
# backend "local"   {}
  backend "azurerm" {
#                           tfstate<Subscription8chars>
    storage_account_name = "tfstate01234567" #only lowercase letters nad numbers unique across Azure
    container_name       = "infrarg"         #only lowercase letters and numbers
    key                  = "tfstate"         #state file name, when delimited with '/' will create a folder aka prefix in AWS
#   key                  = "stack/tfstate"
#   access_key           = "ARM_ACCESS_KEY"  #optional access_key in plain text it's advised to export variable
  }
}


Configure azurerm backend via terraform init. When you auth via:

  • key - it's storage account token, nothing else is required
  • Service Principal - you need to pass a resource group name provide ARM_client_id and ARM_client_secret credentials by explicitly in backend {} block or export them as environment variable.
terraform init -input=false \                                                                       
               -backend=true \                                                                      
               -backend-config="resource_group_name=${LOCATION_STATE_STORAGE_RESOURCE_GROUP_NAME}" \
               -backend-config="storage_account_name=${LOCATION_STATE_STORAGE_ACCOUNT}" \           
               -backend-config="container_name=${LOCATION_STATE_STORAGE_CONTAINER}" \               
               -backend-config="key=${LOCATION_STATE_KEY}"


Using the key argument like in s3 backend you can store state files in hierarchy structure. Eg:

# High Level View
# https://<storage_account>.blob.core.windows.net/<container>/<key/tfstate>
# https://infrarg.blob.core.windows.net/tfstate/tfstate(state_file)
# https://infrarg.blob.core.windows.net/tfstate/stack  (folder)/terraform.tfstate(state_file)
# https://infrarg.blob.core.windows.net/tfstate/storage(folder)/terraform.tfstate(state_file)


Example changing state from local to azurerm. Note Previous and New temporarly saved state files.

Initializing the backend...
Backend configuration changed!

Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.

Terraform detected that the backend type changed from "local" to "azurerm".
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "local" backend to the
  newly configured "azurerm" backend. An existing non-empty state already exists in
  the new backend. The two states have been saved to temporary files that will be
  removed after responding to this query.

  Previous (type "local"): /tmp/terraform962571048/1-local.tfstate
  New      (type "azurerm"): /tmp/terraform962571048/2-azurerm.tfstate

  Do you want to overwrite the state in the new backend with the previous state?
  Enter "yes" to copy and "no" to start with the existing state in the newly
  configured "azurerm" backend.

  Enter a value: yes

Releasing state lock. This may take a few moments...

Successfully configured the backend "azurerm"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...

Terraform has been successfully initialized!


Key notes:

  • you must create resource_group and storage_account before migrating backend
  • both container and full prefixed path aka folders will be created when needed
  • when moving backend temporarly remove -input=false from <terraform init command

References