Terraform + Azure + Pipelines (Azure Devops): Provisioning on Windows 11 with Bastion configured in Virtual network
Terraform + Azure + Pipelines (Azure Devops) : Provisionando no Windows 11 com Bastion configurado no Virtual network
This article aims to demonstrate the provisioning code for a Windows 11 VM with the bastion configured in the Virtual Network. With this model you can change the information in the source_image_reference field and enter the type of VM you want.
Esse artigo tem como objetivo demonstrar o código de provisionamento de uma vm Windows 11 com o bastion configurado no Virtual Network.
Com esse modelo você pode trocar as informações do campo source_image_reference e informar o tipo de VM que você deseja.
Crie os arquivos abaixo:
Create files below:
main.tf
terraform {
backend "azurerm" {
resource_group_name = "name_resource_group"
storage_account_name = "name_storage_account"
container_name = "name_container"
key = "key_storage_account"
}
}
provider "azurerm" {
# Configuration options
features {
}
}
rg.tf
resource "azurerm_resource_group" "rg" {
name = lower("rg-${var.nameresourcegroup}")
location = var.location
}
variables.tf
variable "my_virtual_machine_password" {
default = "your_password"
description = "Password of the Virtual Machine"
}
variable "my_virtual_machine_size" {
default = "Standard_D2_v4"
description = "Size of the Virtual Machine"
}
variable "location" {
default = "eastus"
description = "Location of the resource group."
}
variable "name" {
default = "Jordan"
description = "Name of the resource."
}
variable "nameresourcegroup" {
default = "labs"
description = "Name of RG"
}
vnet.tf
resource "azurerm_virtual_network" "vnet" {
name = "Vnet-${var.name}"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_subnet" "subnet" {
name = "subnet-1"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.2.0/24"]
}
bastion.tf
resource "azurerm_subnet" "mybastionsubnet" {
name = "AzureBastionSubnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.10.0/27"]
}
resource "azurerm_public_ip" "mypipbastion" {
name = "Bastionpip"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_bastion_host" "myhost" {
name = "Mybastion"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "configuration_ip_bastion"
subnet_id = azurerm_subnet.mybastionsubnet.id
public_ip_address_id = azurerm_public_ip.mypipbastion.id
}
}
vm_win10.tf
resource "azurerm_public_ip" "my-public-ip" {
name = "Public-ip-${var.name}"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
allocation_method = "Dynamic"
tags = {
environment = "Testing"
}
}
resource "azurerm_network_interface" "mynetworkinterface" {
name = "network-interface-${var.name}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "internal-${var.name}"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.my-public-ip.id
}
}
# Windows 11 Virtual Machine
resource "azurerm_windows_virtual_machine" "myvirtualmachine" {
name = "win11-${var.name}"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
size = var.my_virtual_machine_size
admin_username = "chicano"
admin_password = var.my_virtual_machine_password
network_interface_ids = [
azurerm_network_interface.mynetworkinterface.id,
]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsDesktop"
offer = "windows-10"
sku = "win10-22h2-pro"
version = "latest"
}
}
# Security Group - allowing RDP Connection
resource "azurerm_network_security_group" "sg-rdp-connection" {
name = "allowrdpconnection-${var.name}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "rdpport"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "*"
destination_address_prefix = "*"
}
tags = {
environment = "Testing"
}
}
# Associate security group with network interface
resource "azurerm_network_interface_security_group_association" "my_association" {
network_interface_id = azurerm_network_interface.mynetworkinterface.id
network_security_group_id = azurerm_network_security_group.sg-rdp-connection.id
}
Pipelines
azure-pipelines_apply.yml
trigger:
- your_branch
pool:
vmImage: ubuntu-latest
variables:
bkresourcegroups: 'name_resource_group'
bkstorageaccount: 'name_storage_account'
bkcontainer: 'name_container'
bkkey: 'key_storage_account'
stages:
- stage:
jobs:
- job: validate
continueOnError: false
steps:
- task: TerraformInstaller@1
displayName: Instalar o Terraform
inputs:
terraformVersion: 'latest'
- task: TerraformTaskV4@4
displayName: Iniciar o Terraform
inputs:
provider: 'azurerm'
command: 'init'
backendServiceArm: 'TerraFormDevConnection'
backendAzureRmResourceGroupName: '$(bkresourcegroups)'
backendAzureRmStorageAccountName: '$(bkstorageaccount)'
backendAzureRmContainerName: '$(bkcontainer)'
backendAzureRmKey: '$(bkkey)'
- task: TerraformTaskV4@4
displayName: Planejar a codificação no Terraform
inputs:
provider: 'azurerm'
command: 'plan'
environmentServiceNameAzureRM: 'TerraFormDevConnection'
- task: TerraformTaskV4@4
displayName: Applicar a codificação no Terraform
inputs:
provider: 'azurerm'
command: 'apply'
commandOptions: '-auto-approve'
environmentServiceNameAzureRM: 'TerraFormDevConnection'