Provisionar uma máquina virtual Linux usando o Terraform
O Terraform implementa e controla uma infraestrutura de destino usando arquivos de configuração que descrevem o estado desejado de seus componentes. O formato básico dos arquivos e a sintaxe geral deles, expressa na HCL (Linguagem de Configuração Hashicorp) , são os mesmos, independentemente da escolha da nuvem. No entanto, as descrições de componentes individuais dependem da nuvem, conforme determinado pelo provedor Terraform correspondente.
Embora haja vários provedores do Terraform que dão suporte ao gerenciamento de infraestrutura do Azure, o AzureRM é de particular relevância. O provedor do AzureRM facilita o provisionamento e a configuração de recursos comuns de IaaS do Azure, como máquinas virtuais, contas de armazenamento e interfaces de rede. Também há provedores adicionais não específicos da nuvem que talvez você queira incorporar em suas implantações. Isso inclui o provedor aleatório, que ajuda a evitar conflitos de nomenclatura de recursos gerando cadeias de caracteres pseudo-aleatórias; e o provedor de TLS, que simplifica o gerenciamento de chaves assimétricas para proteger a autenticação do Linux.
O Terraform está disponível como um único binário que você pode baixar no site da Hashicorp. Esse binário implementa a CLI (interface de linha de comando) do Terraform, que você pode invocar de uma sessão de shell para inicializar o Terraform e processar arquivos de configuração. Você pode usar a CLI do Terraform de qualquer um dos shells que dão suporte à CLI do Azure.
Observação
Ao usar o Azure Cloud Shell, execute a versão atual do Terraform seguindo as instruções fornecidas em Configurar o Terraform no Azure Cloud Shell com o Bash.
Implantar uma VM Linux usando o Terraform
O Terraform permite definir, visualizar e implantar recursos em uma infraestrutura de nuvem específica do provedor. O processo de provisionamento começa com a criação de arquivos de configuração que usam a sintaxe HCL, que permite designar o ambiente de nuvem de destino, como o Azure, e os recursos que compõem sua infraestrutura de nuvem. Depois que todos os arquivos de configuração relevantes estiverem em vigor (normalmente no mesmo local do sistema de arquivos), você poderá gerar um plano de execução que permite visualizar as alterações de infraestrutura resultantes antes da implantação real. Isso exige que você inicialize o Terraform para baixar os módulos de provedor necessários para implementar recursos de nuvem. Depois de validar as alterações, você pode aplicar o plano de execução para implantar a infraestrutura.
Observação
Gerar um plano de execução é opcional, mas recomendamos que você faça isso porque ele permite identificar qualquer impacto da implantação planejada sem afetar o ambiente de destino. Quando você implanta recursos do Azure interativamente, o Terraform dá suporte à autenticação da CLI do Azure de maneira transparente reutilizando suas credenciais para acessar a assinatura do Azure de destino.
O processo de provisionamento de uma VM do Azure que executa o Linux usando o Terraform normalmente envolve a seguinte sequência de etapas de alto nível:
- Identifique a imagem de VM adequada.
- Identifique o tamanho de VM adequado.
- Crie arquivos de configuração que definem o recurso de VM do Azure com as dependências dele.
- Inicialize o Terraform.
- Gere um plano de execução do Terraform.
- Inicie uma implantação do Terraform.
Para identificar a imagem e o tamanho adequados da VM, siga as etapas descritas na Unidade 4 deste módulo. Esta unidade se concentra em tarefas específicas do Terraform.
Criar arquivos de configuração
Observação
Os nomes de arquivo escolhidos para seus arquivos do Terraform são arbitrários, embora seja uma boa prática escolher um nome que reflita o conteúdo ou a finalidade do arquivo. Você deve usar ".tf" para a extensão de arquivo.
Para implantar uma VM do Linux usando o Terraform, comece criando um diretório para hospedar arquivos de configuração. Em seguida, crie um arquivo chamado providers.tf que imponha a versão do Terraform e designe os provedores nos quais você dependerá ao definir os recursos incluídos em sua implantação. Esse arquivo deve ter o conteúdo exibido no seguinte snippet de código:
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
random = {
source = "hashicorp/random"
version = "~>3.0"
}
tls = {
source = "hashicorp/tls"
version = "~>4.0"
}
}
}
provider "azurerm" {
features {}
}
No mesmo diretório, crie um arquivo chamado main.tf usando o seguinte código, que define a configuração da VM do Azure e as dependências dele:
resource "random_pet" "rg_name" {
prefix = var.resource_group_name_prefix
}
resource "azurerm_resource_group" "rg" {
location = var.resource_group_location
name = random_pet.rg_name.id
}
# Create virtual network
resource "azurerm_virtual_network" "terraform_network" {
name = "lnx-tf-vnet"
address_space = ["10.1.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
# Create subnet
resource "azurerm_subnet" "terraform_subnet" {
name = "subnet0"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.terraform_network.name
address_prefixes = ["10.1.0.0/24"]
}
# Create public IPs
resource "azurerm_public_ip" "terraform_public_ip" {
name = "lnx-tf-pip"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Dynamic"
}
# Create Network Security Group and rule
resource "azurerm_network_security_group" "terraform_nsg" {
name = "lnx-tf-nsg"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "ssh"
priority = 300
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
# Create network interface
resource "azurerm_network_interface" "terraform_nic" {
name = "lnx-tf-nic"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "nic_configuration"
subnet_id = azurerm_subnet.terraform_subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.terraform_public_ip.id
}
}
# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "lnx-tf-nic-nsg" {
network_interface_id = azurerm_network_interface.terraform_nic.id
network_security_group_id = azurerm_network_security_group.terraform_nsg.id
}
# Generate random text for a unique storage account name
resource "random_id" "random_id" {
keepers = {
# Generate a new ID only when a new resource group is defined
resource_group = azurerm_resource_group.rg.name
}
byte_length = 8
}
# Create storage account for boot diagnostics
resource "azurerm_storage_account" "storage_account" {
name = "diag${random_id.random_id.hex}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
account_tier = "Standard"
account_replication_type = "LRS"
}
# Create (and display) an SSH key
resource "tls_private_key" "lnx-tf-ssh" {
algorithm = "RSA"
rsa_bits = 4096
}
# Create virtual machine
resource "azurerm_linux_virtual_machine" "lnx-tf-vm" {
name = "lnx-tf-vm"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.terraform_nic.id]
size = "Standard_F4s"
os_disk {
name = "lnx-tf-vm-osdisk"
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts-gen2"
version = "latest"
}
computer_name = "lnx-tf-vm"
admin_username = "azureuser"
disable_password_authentication = true
admin_ssh_key {
username = "azureuser"
public_key = tls_private_key.lnx-tf-ssh.public_key_openssh
}
boot_diagnostics {
storage_account_uri = azurerm_storage_account.storage_account.primary_blob_endpoint
}
}
No mesmo diretório, crie outro arquivo chamado variables.tf usando o código a seguir, que atribui o valor às variáveis que aparecem no arquivo main.tf:
variable "resource_group_location" {
default = "eastus"
description = "Location of the resource group"
}
variable "resource_group_name_prefix" {
default = "rg"
description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription"
}
Por fim, crie um arquivo chamado outputs.tf usando o seguinte código, que determina a saída exibida após uma implantação bem-sucedida:
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
output "public_ip_address" {
value = azurerm_linux_virtual_machine.lnx-tf-vm.public_ip_address
}
output "tls_private_key" {
value = tls_private_key.lnx-tf-ssh.private_key_pem
sensitive = true
}
Inicializar Terraform
Para inicializar a implantação do Terraform, execute o seguinte comando no prompt do shell:
terraform init
Esse comando baixa os módulos do Azure necessários para provisionar e gerenciar recursos do Azure.
Gerar um plano de execução
Após a inicialização, crie um plano de execução executando terraform plan. O comando cria um plano de execução, mas não o executa. Em vez disso, ele determina quais ações são necessárias para criar os recursos definidos em seus arquivos de configuração. O parâmetro opcional -out
permite que você especifique um arquivo de saída para o plano, que pode ser referenciado durante a implantação real. O uso desse arquivo garante que o plano revisado corresponda ao resultado exato da implantação. Use o seguinte comando para gerar um plano de execução:
terraform plan -out <terraform_plan>.tfplan
Iniciar uma implantação
Quando estiver pronto para aplicar o plano de execução ao seu ambiente do Azure, execute terraform apply
, incluindo o nome do arquivo gerado na etapa anterior. Você terá outra chance de examinar o resultado esperado. O Terraform solicita que a confirmação prossiga, embora você possa eliminar o prompt adicionando a opção -auto-approve
. Use o seguinte comando para iniciar a implantação:
terraform apply <terraform_plan>.tfplan
A VM do Azure começará a ser executada em breve, normalmente dentro de alguns minutos. A saída do comando terraform apply
inclui a lista de saídas, mas o Terraform substituirá o valor tls_private_key
pelo rótulo <confidencial>:
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
Saídas:
public_ip_address = "74.235.10.136"
resource_group_name = "rg-flexible-shark"
tls_private_key = <sensitive>
Para usar a chave privada gerada automaticamente para autenticar sua conexão SSH, armazene-a em um arquivo e defina as permissões do arquivo para garantir que ele não esteja acessível por outras pessoas. Para fazer isso, execute os seguintes comandos:
terraform output -raw tls_private_key > id_rsa
chmod 600 id_rsa
Neste ponto, você poderá se conectar à VM do Azure executando o seguinte comando (depois de substituir o espaço reservado <public_ip_address> pelo endereço IP identificado na saída terraform apply-generated):
ssh -i id_rsa azureuser@<public_ip_address>