image

Acesse bootcamps ilimitados e +650 cursos pra sempre

60
%OFF
Article image
EVERTON LUCAS
EVERTON LUCAS14/06/2025 10:57
Compartilhe
WEX - End to End EngineeringRecomendados para vocêWEX - End to End Engineering

Simplificando a Implantação de Projetos no Azure com JSON e ARM Templates

    A administração de ambientes Azure envolve frequentemente a criação e configuração de recursos. Para otimizar e padronizar essas operações, os Azure Resource Manager (ARM) templates, escritos em JSON, são ferramentas indispensáveis. Eles permitem que você defina a infraestrutura como código, garantindo consistência, repetibilidade e minimizando erros manuais.

    Neste artigo, exploraremos um JSON modelo que simplifica a implantação de um novo projeto no Azure, criando um Grupo de Recursos, uma Rede Virtual (VNet) e uma Máquina Virtual (VM) Linux básica. O objetivo é fornecer um template flexível que possa ser facilmente adaptado por outros administradores, alterando apenas alguns parâmetros-chave.



    JSON 1: Implantação de um Novo Projeto no Azure (Grupo de Recursos, VNet e VM)

    Este template é projetado para criar o ambiente básico para um novo projeto no Azure. Ele engloba a criação de um grupo de recursos para organizar seus recursos, uma rede virtual para isolamento de rede e uma máquina virtual Linux para hospedar suas aplicações.

    Objetivo: Automatizar a criação de um ambiente de projeto inicial no Azure, incluindo:

    • Um novo Grupo de Recursos.
    • Uma Rede Virtual (VNet) com uma sub-rede.
    • Uma Máquina Virtual (VM) Linux com IP público e regras de NSG para SSH.

    Serviços do Azure Envolvidos: Azure Resource Manager, Azure Virtual Networks, Azure Virtual Machines, Azure Network Security Groups.

    O JSON Modelo:

    JSON

    {

       "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",

       "contentVersion": "1.0.0.0",

       "parameters": {

           "resourceGroupName": {

               "type": "string",

               "metadata": {

                   "description": "Nome do novo Grupo de Recursos para o projeto."

               }

           },

           "location": {

               "type": "string",

               "defaultValue": "[resourceGroup().location]",

               "metadata": {

                   "description": "Localização (região do Azure) para os recursos."

               }

           },

           "vnetName": {

               "type": "string",

               "defaultValue": "[concat('vnet-', parameters('resourceGroupName'))]",

               "metadata": {

                   "description": "Nome da Rede Virtual."

               }

           },

           "subnetName": {

               "type": "string",

               "defaultValue": "default",

               "metadata": {

                   "description": "Nome da Sub-rede dentro da Rede Virtual."

               }

           },

           "vnetAddressPrefix": {

               "type": "string",

               "defaultValue": "10.0.0.0/16",

               "metadata": {

                   "description": "Prefixo de endereço para a VNet."

               }

           },

           "subnetAddressPrefix": {

               "type": "string",

               "defaultValue": "10.0.0.0/24",

               "metadata": {

                   "description": "Prefixo de endereço para a Sub-rede."

               }

           },

           "vmName": {

               "type": "string",

               "defaultValue": "[concat('vm-', parameters('resourceGroupName'))]",

               "metadata": {

                   "description": "Nome da Máquina Virtual."

               }

           },

           "vmSize": {

               "type": "string",

               "defaultValue": "Standard_DS1_v2",

               "metadata": {

                   "description": "Tamanho da Máquina Virtual (ex: Standard_DS1_v2, Standard_B2s)."

               }

           },

           "adminUsername": {

               "type": "string",

               "metadata": {

                   "description": "Nome de usuário administrador para a VM Linux."

               }

           },

           "adminPassword": {

               "type": "securestring",

               "metadata": {

                   "description": "Senha administrador para a VM Linux. Use senhas fortes!"

               }

           },

           "ubuntuOSVersion": {

               "type": "string",

               "defaultValue": "latest",

               "allowedValues": [

                   "18.04-LTS",

                   "20.04-LTS",

                   "22.04-LTS",

                   "latest"

               ],

               "metadata": {

                   "description": "Versão do Ubuntu Server para a VM."

               }

           },

           "sshPortNumber": {

               "type": "int",

               "defaultValue": 22,

               "metadata": {

                   "description": "Número da porta para SSH. Mude se não for 22."

               }

           }

       },

       "variables": {

           "publicIpAddressName": "[concat(parameters('vmName'), '-ip')]",

           "networkSecurityGroupName": "[concat(parameters('vmName'), '-nsg')]",

           "networkInterfaceName": "[concat(parameters('vmName'), '-nic')]"

       },

       "resources": [

           {

               "type": "Microsoft.Resources/resourceGroups",

               "apiVersion": "2021-04-01",

               "name": "[parameters('resourceGroupName')]",

               "location": "[parameters('location')]",

               "properties": {}

           },

           {

               "type": "Microsoft.Network/virtualNetworks",

               "apiVersion": "2023-09-01",

               "name": "[parameters('vnetName')]",

               "location": "[parameters('location')]",

               "dependsOn": [

                   "[resourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]"

               ],

               "properties": {

                   "addressSpace": {

                       "addressPrefixes": [

                           "[parameters('vnetAddressPrefix')]"

                       ]

                   },

                   "subnets": [

                       {

                           "name": "[parameters('subnetName')]",

                           "properties": {

                               "addressPrefix": "[parameters('subnetAddressPrefix')]"

                           }

                       }

                   ]

               }

           },

           {

               "type": "Microsoft.Network/networkSecurityGroups",

               "apiVersion": "2023-09-01",

               "name": "[variables('networkSecurityGroupName')]",

               "location": "[parameters('location')]",

               "dependsOn": [

                   "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"

               ],

               "properties": {

                   "securityRules": [

                       {

                           "name": "AllowSSH",

                           "properties": {

                               "description": "Allow SSH access",

                               "protocol": "Tcp",

                               "sourcePortRange": "*",

                               "destinationPortRange": "[parameters('sshPortNumber')]",

                               "sourceAddressPrefix": "Internet",

                               "destinationAddressPrefix": "*",

                               "access": "Allow",

                               "priority": 100,

                               "direction": "Inbound"

                           }

                       }

                   ]

               }

           },

           {

               "type": "Microsoft.Network/publicIPAddresses",

               "apiVersion": "2023-09-01",

               "name": "[variables('publicIpAddressName')]",

               "location": "[parameters('location')]",

               "dependsOn": [

                   "[resourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]"

               ],

               "properties": {

                   "publicIPAllocationMethod": "Dynamic",

                   "dnsSettings": {

                       "domainNameLabel": "[concat(parameters('vmName'), '-', uniqueString(resourceGroup().id))]"

                   }

               }

           },

           {

               "type": "Microsoft.Network/networkInterfaces",

               "apiVersion": "2023-09-01",

               "name": "[variables('networkInterfaceName')]",

               "location": "[parameters('location')]",

               "dependsOn": [

                   "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpAddressName'))]",

                   "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]",

                   "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"

               ],

               "properties": {

                   "ipConfigurations": [

                       {

                           "name": "ipconfig1",

                           "properties": {

                               "privateIPAllocationMethod": "Dynamic",

                               "publicIPAddress": {

                                   "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpAddressName'))]"

                               },

                               "subnet": {

                                   "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]"

                               }

                           }

                       }

                   ],

                   "networkSecurityGroup": {

                       "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"

                   }

               }

           },

           {

               "type": "Microsoft.Compute/virtualMachines",

               "apiVersion": "2023-09-01",

               "name": "[parameters('vmName')]",

               "location": "[parameters('location')]",

               "dependsOn": [

                   "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"

               ],

               "properties": {

                   "hardwareProfile": {

                       "vmSize": "[parameters('vmSize')]"

                   },

                   "osProfile": {

                       "computerName": "[parameters('vmName')]",

                       "adminUsername": "[parameters('adminUsername')]",

                       "adminPassword": "[parameters('adminPassword')]"

                   },

                   "storageProfile": {

                       "imageReference": {

                           "publisher": "Canonical",

                           "offer": "0001-com-ubuntu-server-jammy",

                           "sku": "[parameters('ubuntuOSVersion') == '18.04-LTS' ? '18_04-lts-gen2' : parameters('ubuntuOSVersion') == '20.04-LTS' ? '20_04-lts-gen2' : '22_04-lts-gen2']",

                           "version": "latest"

                       },

                       "osDisk": {

                           "createOption": "FromImage",

                           "managedDisk": {

                               "storageAccountType": "Standard_LRS"

                           }

                       }

                   },

                   "networkProfile": {

                       "networkInterfaces": [

                           {

                               "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"

                           }

                       ]

                   }

               }

           }

       ],

       "outputs": {

           "resourceGroupNameOutput": {

               "type": "string",

               "value": "[parameters('resourceGroupName')]",

               "metadata": {

                   "description": "Nome do Grupo de Recursos criado."

               }

           },

           "publicIpAddress": {

               "type": "string",

               "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpAddressName'))).ipAddress]",

               "metadata": {

                   "description": "Endereço IP público da VM."

               }

           },

           "sshCommand": {

               "type": "string",

               "value": "[concat('ssh ', parameters('adminUsername'), '@', reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpAddressName'))).ipAddress)]",

               "metadata": {

                   "description": "Comando SSH para conectar à VM."

               }

           }

       }

    }

    Explicação Detalhada do JSON:

    • $schema e contentVersion: Define o tipo de documento e a versão do template ARM.
    • parameters: Seção crucial para a flexibilidade. Aqui você define as entradas que os administradores podem personalizar.
    • resourceGroupName, location, vnetName, vmName, adminUsername, adminPassword, vmSize: Parâmetros essenciais que garantem a unicidade e configurabilidade do projeto.
    • defaultValue: Muitos parâmetros têm valores padrão, facilitando o uso rápido sem necessidade de especificar todos eles.
    • allowedValues: Restringe as opções para alguns parâmetros (ex: ubuntuOSVersion), evitando erros de digitação.
    • securestring: Para senhas, garante que o valor não seja logado abertamente.
    • variables: Define valores que são computados durante a implantação, geralmente para construir nomes de recursos derivados dos parâmetros. Isso mantém os nomes consistentes.
    • resources: A parte principal onde cada recurso do Azure é definido. Cada recurso tem:
    • type: O tipo de recurso (ex: Microsoft.Network/virtualNetworks).
    • apiVersion: A versão da API do Azure Resource Provider para o recurso.
    • name: O nome do recurso.
    • location: A região do Azure onde o recurso será implantado.
    • dependsOn: Garante a ordem correta de implantação. Por exemplo, a VM depende da NIC, que depende da Public IP e da NSG, que dependem da VNet.
    • properties: As configurações específicas do recurso (endereços IP, tamanho da VM, nome de usuário, etc.).
    • outputs: Retorna informações úteis após a implantação, como o nome do Grupo de Recursos, o IP público da VM e até mesmo um comando SSH formatado para acesso rápido.

    Demonstração com Azure CLI:

    Para usar este template, salve-o em um arquivo chamado deploy_project.json.

    1. Prepare o arquivo de parâmetros (opcional, mas recomendado para reutilização): Crie um arquivo chamado parameters.json para definir os valores dos parâmetros. Isso é ideal para que outros administradores apenas alterem este arquivo.

    JSON

    {

       "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",

       "contentVersion": "1.0.0.0",

       "parameters": {

           "resourceGroupName": {

               "value": "meuNovoProjetoRG" // Substitua pelo nome do seu Grupo de Recursos

           },

           "location": {

               "value": "eastus" // Substitua pela região desejada

           },

           "vmName": {

               "value": "meuServidorWeb" // Substitua pelo nome da sua VM

           },

           "vmSize": {

               "value": "Standard_B2s" // Opcional: mude o tamanho da VM

           },

           "adminUsername": {

               "value": "azureuser" // Seu nome de usuário admin

           },

           "adminPassword": {

               "value": "SuaSenhaMuitoSegura123!" // Sua senha forte

           },

           "sshPortNumber": {

               "value": 22 // Opcional: Mude a porta SSH se necessário

           }

       }

    }

    Importante: Nunca armazene senhas em texto puro em arquivos de controle de versão. Para ambientes de produção, use o Azure Key Vault para armazenar segredos e referencie-os nos templates.

    1. Execute a implantação via Azure CLI:

    Abra seu terminal ou Azure Cloud Shell e execute o seguinte comando:

    Bash

    az deployment group create \

     --name "ProjetoNovoDeploy" \

     --template-file deploy_project.json \

     --parameters @parameters.json

    • --name "ProjetoNovoDeploy": Um nome para sua implantação.
    • --template-file deploy_project.json: O caminho para o arquivo JSON do seu template.
    • --parameters @parameters.json: O caminho para o arquivo JSON com os valores dos parâmetros. O @ indica que é um arquivo.

    Alternativamente, você pode passar os parâmetros diretamente na linha de comando, sem um arquivo de parâmetros:

    Bash

    az deployment group create \

     --name "ProjetoNovoDeploy" \

     --template-file deploy_project.json \

     --parameters resourceGroupName=meuNovoProjetoRG location=eastus vmName=meuServidorWeb adminUsername=azureuser adminPassword="SuaSenhaMuitoSegura123!"

    Cuidado: Ao passar senhas diretamente na linha de comando, elas podem aparecer no histórico do seu shell. O uso de um arquivo de parâmetros ou Key Vault é mais seguro.

    Particularidades e Dicas Importantes:

    • Reutilização: Este template é um ponto de partida excelente. Você pode estendê-lo para incluir outros recursos como contas de armazenamento, bancos de dados, App Services, etc.
    • Parâmetros: Utilize os parâmetros para tornar seu template dinâmico e reutilizável. Evite "hard-coding" valores dentro da seção resources.
    • dependsOn: Essencial para garantir que os recursos sejam criados na ordem correta. O Azure não tentará criar uma NIC antes que a VNet exista, por exemplo.
    • Versões da API (apiVersion): Sempre use as versões mais recentes das APIs para os tipos de recurso que você está implantando. Consulte a documentação do Azure para as versões mais atuais.
    • Saídas (outputs): Use as saídas para recuperar informações importantes sobre os recursos implantados, como IPs públicos ou URLs, que podem ser úteis para scripts subsequentes ou para o usuário final.
    • Validação: Antes de implantar, você pode validar o template usando az deployment group validate --resource-group <nome-do-grupo> --template-file deploy_project.json --parameters @parameters.json. Isso verifica a sintaxe e a lógica sem realmente criar recursos.
    • What-if: Use az deployment group what-if --resource-group <nome-do-grupo> --template-file deploy_project.json --parameters @parameters.json para ver as mudanças que a implantação faria no seu ambiente sem aplicá-las.



    Integrando o Azure Key Vault para Segurança de Credenciais

    Conforme mencionado, armazenar senhas diretamente nos arquivos de parâmetros não é uma prática segura. O Azure Key Vault é o serviço ideal para gerenciar e proteger chaves criptográficas, certificados e, crucialmente, segredos (como senhas).

    Para utilizar senhas armazenadas no Key Vault em seu ARM template, você precisará de algumas etapas:

    1. Criar e configurar um Azure Key Vault: O Key Vault deve existir antes da implantação do template. Você pode criá-lo via portal, CLI ou até mesmo outro ARM template. Certifique-se de que a identidade que realiza a implantação (usuário, Service Principal ou Managed Identity) tenha permissões de Get para os segredos no Key Vault.

    Exemplo de criação de Key Vault via CLI:

    Bash

    # Crie um grupo de recursos para o Key Vault (se ainda não tiver um)

    az group create --name "myKeyVaultRG" --location "eastus"

    # Crie o Key Vault

    az keyvault create \

     --name "mySecureKeyVault123" \

     --resource-group "myKeyVaultRG" \

     --location "eastus" \

     --sku "Standard"

    # Adicione um segredo (a senha da VM)

    az keyvault secret set \

     --vault-name "mySecureKeyVault123" \

     --name "vmAdminPassword" \

     --value "SuaSenhaUltraSecretaParaVM!"

    Importante: Conceda permissões de acesso ao Key Vault para a entidade que fará a implantação. Por exemplo, se for você com sua conta de usuário:

    Bash

    az keyvault set-policy \

     --name "mySecureKeyVault123" \

     --resource-group "myKeyVaultRG" \

     --object-id $(az ad signed-in-user show --query id -o tsv) \

     --secret-permissions get list

    (Substitua $(az ad signed-in-user show --query id -o tsv) pelo Object ID da Service Principal ou Managed Identity, se aplicável).

    1. Modificar o parâmetro da senha no ARM Template: No seu arquivo deploy_project.json, você manterá o parâmetro adminPassword como securestring. Não há alteração neste arquivo.
    2. Modificar o arquivo de parâmetros para referenciar o Key Vault: Esta é a mudança chave. Em vez de fornecer a senha diretamente, você referencia o segredo no Key Vault. Crie ou modifique seu parameters.json da seguinte forma:

    JSON

    {

       "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",

       "contentVersion": "1.0.0.0",

       "parameters": {

           "resourceGroupName": {

               "value": "meuNovoProjetoRG"

           },

           "location": {

               "value": "eastus"

           },

           "vmName": {

               "value": "meuServidorWeb"

           },

           "vmSize": {

               "value": "Standard_B2s"

           },

           "adminUsername": {

               "value": "azureuser"

           },

           "adminPassword": {

               "reference": {

                   "keyVault": {

                       "id": "/subscriptions/<SUA_SUBSCRIPTION_ID>/resourceGroups/myKeyVaultRG/providers/Microsoft.KeyVault/vaults/mySecureKeyVault123"

                   },

                   "secretName": "vmAdminPassword"

                   // "secretVersion": "OptionalVersion" // Opcional: use uma versão específica do segredo

               }

           },

           "sshPortNumber": {

               "value": 22

           }

       }

    }

    Lembre-se de substituir <SUA_SUBSCRIPTION_ID> pelo ID da sua assinatura do Azure. Você pode obter seu ID de assinatura com az account show --query id -o tsv.

    Como Funciona:

    Quando você executa a implantação do ARM template com este arquivo de parâmetros, o Azure Resource Manager faz uma chamada segura ao Key Vault para recuperar o segredo (vmAdminPassword) antes de provisionar a VM. Dessa forma, a senha nunca é exposta em texto simples no template, nos arquivos de parâmetros ou nos logs de implantação.

    Demonstração de Implantação com Key Vault:

    A execução do comando no Azure CLI permanece a mesma:

    Bash

    az deployment group create \

     --name "ProjetoNovoDeployComKV" \

     --template-file deploy_project.json \

     --parameters @parameters.json

    Com esta abordagem, você eleva significativamente a segurança de suas implantações no Azure, gerenciando credenciais de forma centralizada e segura com o Key Vault.



    Este template oferece uma base sólida para a automação de novas implantações de projetos no Azure. Ao dominá-lo, os administradores podem garantir que os ambientes sejam configurados de forma padronizada e eficiente, liberando tempo para tarefas mais estratégicas.

    Compartilhe
    Recomendados para você
    NTT DATA - Java e IA para Iniciantes
    TONNIE - Java and AI in Europe
    Microsoft - Azure Administrator Certification (AZ-104)
    Comentários (0)
    Recomendados para vocêWEX - End to End Engineering