# terraform

![Azure loves Terraform](/files/JILVpqzSVBdIp2Emq65t)

## ARM and terraform - Side by Side

| [ARM Templates](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/)                    | Terraform                                                               |
| ------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
| JSON w/ comments                                                                                             | HCL                                                                     |
| [Parameters](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-parameters)    | Variables                                                               |
| [Variables](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-variables)      | Local variables                                                         |
| Resources                                                                                                    | Resources                                                               |
| [Functions](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions)      | [Functions](https://www.terraform.io/docs/configuration/functions.html) |
| [Nested templates](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/linked-templates) | Modules                                                                 |
| Explicit                                                                                                     | Automatic                                                               |
| Refer by reference or resourceId                                                                             | Refer by resource or data source                                        |

## Providers

* Azure (i.e. Azure *Resource* Manager)
* ~~the 'old' Azure *Service* Management (ASM) provider~~
* Azure Active Directory (AAD)
* Azure Stack (on-premises)

## Authentication

<https://www.terraform.io/docs/providers/azurerm/index.html#authenticating-to-azure>

* AZ CLI - if environment has `az` CLI installed, re-use existing session
* Azure Managed Identity (on Azure compute resource)
* Azure Service Principals (with client secrets or X.509 certs)

## The [`"azurerm"`](https://www.terraform.io/docs/providers/azurerm/index.html) Provider (Azure Resource Manager)

* <https://www.terraform.io/docs/providers/azurerm/>
* <http://aka.ms/terraform>

```
provider "azurerm" {
  version         = "~> 1.40"
  alias           = "networking"
  subscription_id = var.subscription_id
  client_id = var.client_id
  client_secret = var.client_secret
}
```

## The [`"azure_ad"`](https://www.terraform.io/docs/providers/azurerm/index.html) Provider (Azure Resource Manager)

<https://www.terraform.io/docs/providers/azuread/index.html>

```
provider "azure_rm" {
  version         = "~> 0.7"
  subscription_id = var.subscription_id
  client_id       = var.client_id
  client_secret   = var.client_secret
}
```

### Azure-specific environment variables

* `ARM_ENVIRONMENT` - `public`, `usgovernment`, `german`, `china`
* `ARM_SUBSCRIPTION_ID` - Azure subscription ID
* `ARM_TENANT_ID` - Azure AD tenant ID for service principal
* `ARM_USE_MSI` - Use Managed Service Identity
* `ARM_CLIENT_ID` - Service principal ID
* `ARM_CLIENT_SECRET` - Service principal secret

## Remote state: the [`"azurerm"`](https://www.terraform.io/docs/backends/types/azurerm.html) backend

Stores state in a blob, in a container, in an Azure storage account.

```
terraform {
  backend "azurerm" {
    resource_group_name  = "longterm"
    storage_account_name = "chgeuer"
    container_name       = "terraformstate"
    key                  = "demo2.tfstate"
  }
}
```

### Authenticating to remote state backend

* Inherit authN info from outer environment, such as `az` CLI or service principal
* `use_msi`: Managed identity within Azure Compute
* `access_key`: The storage account's access key
* `sas_token`: A 'shared access signature' token

```bash
terraform init –backend-config="sas_token=gh67il=="`
```

Alternatively, Azure CosmosDB provides an etcd protocol head.

## Data Sources

Many data sources, including

* `azurerm`
  * [`"azurerm_subscriptions"`](https://www.terraform.io/docs/providers/azurerm/d/subscriptions.html): information about all the Subscriptions currently available
  * [`"azurerm_subscription"`](https://www.terraform.io/docs/providers/azurerm/d/subscription.html): information about an existing Subscription.
  * [`"azurerm_resource_group"`](https://www.terraform.io/docs/providers/azurerm/d/resource_group.html)
  * KeyVault, Networking, API Management, Compute, ...
* `azuread`
  * [`"azuread_application"`](https://www.terraform.io/docs/providers/azuread/r/application.html)
  * [`"azuread_service_principal"`](https://www.terraform.io/docs/providers/azuread/r/service_principal.html)
  * Users, Groups, Roles, ...

## Azure Modules in the Terraform Registry

<http://aka.ms/tfmodules>

![Screenshot from aka.ms/tfmodules](/files/PW08dBGCadZW8OkrAMTW)

## ARM / Terraform Interoperability

### [`"azurerm_template_deployment"`](https://www.terraform.io/docs/providers/azurerm/r/template_deployment.html): use ARM templates within Terraform

Example: <https://github.com/chgeuer/azure-snippets/blob/master/logic-app-reading-xml/terraform/modules/logicapp/main.tf>

```
resource "azurerm_template_deployment" "logicapp" {
  name                   = "deployment-${formatdate("YYYY-MM-DD--hh-mm-ss", timestamp())}"
  resource_group_name    = var.resource_group_name
  deployment_mode        = "Incremental"
  template_body          = file(local.arm_template_file)
  parameters = {
    "logicAppName"       = var.logic_app_name
    "logicAppDefinition" = var.logic_app_definition
  }
}
```

### Terraform Resource Provider (RP) in Azure ARM

* Private preview supporting three providers: Kubernetes, Cloudflare and Datadog
* <https://azure.microsoft.com/en-us/blog/introducing-the-azure-terraform-resource-provider/>

![](/files/dYzDSMdwaaPDyy8AJOUG)

## Available environments

* TF [installed](https://docs.microsoft.com/en-us/azure/terraform/terraform-cloud-shell) in the Azure Cloud Shell [shell.azure.com](https://shell.azure.com)
* [Marketplace VM images w/ terraform and MSI](http://aka.ms/aztfmkt)
* [VS Code Plugin for terraform](https://docs.microsoft.com/en-us/azure/terraform/terraform-vscode-extension)

![Screenshot from the Terraform VM marketplace image](/files/XZL1qdeW0tpPUlB9lYST)

## Learning resources for terraform on Azure

* [aka.ms/tfhub -- docs.microsoft.com](https://docs.microsoft.com/en-us/azure/terraform/)
* [Hashicorp Azure learning track](https://learn.hashicorp.com/terraform?track=azure#azure)
* [chrismatteson/hashicorp\_azure\_training](https://github.com/chrismatteson/hashicorp_azure_training) and the [slides](https://chrismatteson.github.io/hashicorp_azure_training/#55)
* [CardinalNow/TerraformWorkshop](https://github.com/CardinalNow/TerraformWorkshop)
* [Source Code aka.ms/tfgit](http://aka.ms/tfgit)
* [Using Azure DevOps pipelines to deploy via Terraform](https://www.azuredevopslabs.com/labs/vstsextend/terraform/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cookbook.geuer-pollmann.de/azure/terraform.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
