Sempre que vamos criar alguma infraestrutura por meio de IaC (Terraform, Bicep, Pulumi, etc ...) é de extrema importância mantermos os segredos (ex: strings de conexões) seguras. Inspirado nisso, resolvi escrever esse post com a intenção de mostrar como podemos guardar os segredos das nossas soluções no Azure Key Vault e utilizá-los dentro do nosso código do Terraform.

Vamos precisar que você tenha o Terraform instalado na sua máquina local!

Para iniciar o nosso código, devemos criar definir o provider que será utilizado. (Azure!)

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~>3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

Após isso, já podermos criar o arquivo variables.tf que contém as variáveis que serão utilizadas ao longo do nosso código Terraform.

Observe que a variável "my-secret" está sendo definida de uma forma bem simples. Em casos reais de produção, esse segredo deve ser inserido no código de forma segura!

variable "default_location" {
  type        = string
  default     = "eastus"
  description = "Default location"
}

variable "resource_group_name_prefix" {
  type        = string
  default     = "rg"
  description = "Prefix of the resource groups"
}

variable "key_vault_name_prefix" {
  type        = string
  default     = "kv"
  description = "Prefix of the azure key vault"
}

variable "web_app_name_prefix" {
  type        = string
  default     = "app"
  description = "Prefix of azure web app"
}

variable "app_service_plan_name_prefix" {
  type        = string
  default     = "apps"
  description = "Prefix of azure app service plan"
}

variable "default_environment" {
  type        = string
  default     = "prod"
  description = "Default environment"
}


variable "my-secret" {
  type        = string
  default     = "my-secret-value"
  description = "Default environment"
}

Já podemos criar os arquivo main.tf. Vamos por partes!

Inicialmente vamos definir os seguintes itens:

data "azurerm_client_config" "current" {}

locals {
  current_user_id = data.azurerm_client_config.current.object_id
}

Para delimitar logicamente os recursos de nuvem, devemos criar um resource group.


resource "azurerm_resource_group" "rg" {
  location = var.default_location
  name     = "${var.resource_group_name_prefix}-app-${var.default_environment}-${var.default_location}"
}

O padrão de nomenclatura utilizado nesse post será o seguinte:

<prefix>-<feature>-<envrironment>-<location>

Por exemplo, para o grupo de recursos:

rg-app-prod-eastus

Com o resource group criado, podemos criar o Azure Key Vault.


resource "azurerm_key_vault" "vault" {
  name                       = "${var.key_vault_name_prefix}-app-${var.default_environment}-${var.default_location}"
  location                   = azurerm_resource_group.rg.location
  resource_group_name        = azurerm_resource_group.rg.name
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  sku_name                   = "standard"
  soft_delete_retention_days = 7

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = local.current_user_id
    secret_permissions =  ["Get", "List", "Set", "Delete"]
  }
}

Observe que adicionamos access policies para o local.current_user_id (usuário logado no terminal. Ex: az login). Desse forma, quando as chaves forem criadas, teremos a permissões necessárias para acessá-las.

Vamos criar um secret dentro do Azure Key Vault definido anteriormente.


resource "azurerm_key_vault_secret" "secret" {
name         = "my-secret"
value        = var.my-secret
key_vault_id = azurerm_key_vault.vault.id
}

Nesse ponto, nossa infraestrutura como código já possui um segredo definido dentro do Azure Key Vault. Podemos criar outro recurso de nuvem que utilizará esse segredo, sem nunca expor seu valor!

Nesse caso, vamos criar um Azure App Service Plan e um App Service, colocando o segredo como uma configuração no aplicativo web, chamado "MY_SECRET"


resource "azurerm_service_plan" "appserviceplan" {
  name                = "${var.app_service_plan_name_prefix}-app-${var.default_environment}-${var.default_location}"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  os_type             = "Linux"
  sku_name            = "B1"
}

resource "azurerm_linux_web_app" "webapp" {
  name                  = "${var.web_app_name_prefix}-app-${var.default_environment}-${var.default_location}"
  location              = azurerm_resource_group.rg.location
  resource_group_name   = azurerm_resource_group.rg.name
  service_plan_id       = azurerm_service_plan.appserviceplan.id
  https_only            = true
  site_config {
    minimum_tls_version = "1.2"
  }
  app_settings = {
    "MY_SECRET" = azurerm_key_vault_secret.secret.value
  }
}

Com os arquivos prontos, podemos inicializar o projeto Terraform por meio do comando init.

terraform init

Vamos executar o comando plan, com a intenção de mapear todas as modificações que serão feitas no Azure. No nosso caso, como não temos nada previamente criado, serão provisionados os 5 recursos definidos anteriormente.

terraform plan -out main.tfplan

Vamos criar nossa infraestrutura por meio do comando apply.

 terraform apply "main.tfplan"

Após a execução, podemos ver que tudo foi criado de forma correta!

É fechamos aqui o post! Só não vamos esquecer de deletar tudo o que foi criado.

 terraform apply -destroy

Você já pode baixar o projeto por esse link, e não esquece de me seguir no LinkedIn!

GitHub - TallesValiatti/TerraformAzureKeyVault
Contribute to TallesValiatti/TerraformAzureKeyVault development by creating an account on GitHub.

Até a próxima, abraços!

💡
Podemos te ajudar com uma revisão 100% gratuita do seu ambiente cloud.
Share this post