Ansible and Terraform: Better Together

Published: Mar 27, 2023 by Isaac Johnson

We know that we can use Terraform to build out repeatable infrastructure with code. However, we often have to solve provisioning in a second pass. That can be using Packer or Ansible or other tools like Chef, Salt or Puppet. There are ways, however, to marry the provisioning tools we know, such as Ansible, into our Terraform for a full end-to-end solution.

Today we’ll build out local Terraform to create an Azure VM with networking and Public IP. We’ll add in steps to bootstrap Python, then launch a playbook with a local provisioner.

You can follow along with the code in my tfAnsibleAzure repo

Terraform Setup

Let’s get some basic local Terraform setup going for Azure

I’ll create a quick example that creates a Resource Group and VNet

$ cat main.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=3.0.0"
    }
  }
}

# Configure the Microsoft Azure Provider
provider "azurerm" {
  features {}
}

# Create a resource group
resource "azurerm_resource_group" "examplerg" {
  name     = "idj-east-rg"
  location = "East US"
}

# Create a virtual network within the resource group
resource "azurerm_virtual_network" "examplevnet" {
  name                = "example-network"
  resource_group_name = azurerm_resource_group.examplerg.name
  location            = azurerm_resource_group.examplerg.location
  address_space       = ["10.0.0.0/16"]
}

I need to login to my tenant

e$ az login --use-device-code --tenant 28c575f6-asdf-asdf-asdf-asdfasdfeb4a
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code FWMKH6XJV to authenticate.
[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "28c575f6-asdf-asdf-asdf-asdfasdfeb4a",
    "id": "d955c0ba-asdf-asdf-asdf-asdfasdfb22d",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Pay-As-You-Go",
    "state": "Enabled",
    "tenantId": "28c575f6-asdf-asdf-asdf-asdfasdfeb4a",
    "user": {
      "name": "isaac.johnson@gmail.com",
      "type": "user"
    }
  }
]
$ az account set --subscription "Pay-As-You-Go"

TFEnv for Multiple Terraform Versions

If you don’t have TFenv, you can add with

$ brew install tfenv

We can then see our options

$ tfenv
tfenv 3.0.0
Usage: tfenv <command> [<options>]

Commands:
   install       Install a specific version of Terraform
   use           Switch a version to use
   uninstall     Uninstall a specific version of Terraform
   list          List all installed versions
   list-remote   List all installable versions
   version-name  Print current version
   init          Update environment to use tfenv correctly.
   pin           Write the current active version to ./.terraform-version

The remote list is rather large

$ tfenv list-remote
1.4.2
1.4.1
1.4.0
1.4.0-rc1
1.4.0-beta2
1.4.0-beta1
1.4.0-alpha20221207
1.4.0-alpha20221109
1.3.9
1.3.8
... snip ...
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0

I’ll install the latest

$ tfenv install 1.4.2
Installing Terraform v1.4.2
Downloading release tarball from https://releases.hashicorp.com/terraform/1.4.2/terraform_1.4.2_linux_amd64.zip
################################################################################################################# 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.4.2/terraform_1.4.2_SHA256SUMS
Not instructed to use Local PGP (/home/linuxbrew/.linuxbrew/Cellar/tfenv/3.0.0/use-{gpgv,gnupg}) & No keybase install found, skipping OpenPGP signature verification
Archive:  /tmp/tfenv_download.v1niT1/terraform_1.4.2_linux_amd64.zip
  inflating: /home/linuxbrew/.linuxbrew/Cellar/tfenv/3.0.0/versions/1.4.2/terraform
Installation of terraform v1.4.2 successful. To make this your default version, run 'tfenv use 1.4.2'

$ tfenv use 1.4.2
Switching default version to v1.4.2
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.4.2

Local usage

Let’s do an init then plan

builder@DESKTOP-72D2D9T:~/Workspaces/tfAnsibleAzure$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/azurerm versions matching "3.0.0"...
- Installing hashicorp/azurerm v3.0.0...
- Installed hashicorp/azurerm v3.0.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.


I got stuck for a while here as the ‘3.0.0’ provider for AzureRM is rather dated. I moved to ‘3.48.0’, latest as of writing then did an init -upgrade

$ terraform init -upgrade

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/azurerm versions matching "3.48.0"...
- Installing hashicorp/azurerm v3.48.0...
- Installed hashicorp/azurerm v3.48.0 (signed by HashiCorp)

Terraform has made some changes to the provider dependency selections recorded
in the .terraform.lock.hcl file. Review those changes and commit them to your
version control system if they represent changes you intended to make.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

I also packed my Azure Subscription and Tenant into the code just to be sure it wasn’t picking up other subscriptions I may be logged into

$ cat main.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=3.48.0"
    }
  }
}

# Configure the Microsoft Azure Provider
provider "azurerm" {
  features {}

  tenant_id       = "28c575f6-asdf-asdf-asdf-asdfasdfeb4a"
  subscription_id = "d955c0ba-asdf-asdf-asdf-asdfasdfb22d"
}

# Create a resource group
resource "azurerm_resource_group" "examplerg" {
  name     = "idj-east-rg"
  location = "East US"
}

# Create a virtual network within the resource group
resource "azurerm_virtual_network" "examplevnet" {
  name                = "example-network"
  resource_group_name = azurerm_resource_group.examplerg.name
  location            = azurerm_resource_group.examplerg.location
  address_space       = ["10.0.0.0/16"]
}

Now the plan works

$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.examplerg will be created
  + resource "azurerm_resource_group" "examplerg" {
      + id       = (known after apply)
      + location = "eastus"
      + name     = "idj-east-rg"
    }

  # azurerm_virtual_network.examplevnet will be created
  + resource "azurerm_virtual_network" "examplevnet" {
      + address_space       = [
          + "10.0.0.0/16",
        ]
      + dns_servers         = (known after apply)
      + guid                = (known after apply)
      + id                  = (known after apply)
      + location            = "eastus"
      + name                = "example-network"
      + resource_group_name = "idj-east-rg"
      + subnet              = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.

I can run terraform apply to now create the Resource Group and VNet

$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.examplerg will be created
  + resource "azurerm_resource_group" "examplerg" {
      + id       = (known after apply)
      + location = "eastus"
      + name     = "idj-east-rg"
    }

  # azurerm_virtual_network.examplevnet will be created
  + resource "azurerm_virtual_network" "examplevnet" {
      + address_space       = [
          + "10.0.0.0/16",
        ]
      + dns_servers         = (known after apply)
      + guid                = (known after apply)
      + id                  = (known after apply)
      + location            = "eastus"
      + name                = "example-network"
      + resource_group_name = "idj-east-rg"
      + subnet              = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_resource_group.examplerg: Creating...
azurerm_resource_group.examplerg: Creation complete after 3s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg]
azurerm_virtual_network.examplevnet: Creating...
azurerm_virtual_network.examplevnet: Creation complete after 5s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

And I can see it reflected in the Portal

/content/images/2023/03/tfazurermansible-01.png

So far, we’ve basically followed the standard Microsoft getting started. Now I’ll make it a bit more complicated.

I’ll move the providers into a providers.tf

terraform {
  required_version = ">=0.12"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=3.48.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~>3.0"
    }
    tls = {
      source = "hashicorp/tls"
      version = "~>4.0"
    }
  }
}

provider "azurerm" {
  features {}
  
  tenant_id       = "28c575f6-asdf-asdf-asdf-asdfasdfeb4a"
  subscription_id = "d955c0ba-asdf-asdf-asdf-asdfasdfb22d"
}

Add VM, Public, IP and Subnet to the main.tf

# Create a resource group
resource "azurerm_resource_group" "rg" {
  name     = "idj-east-rg"
  location = "East US"
}

# Create a virtual network within the resource group
resource "azurerm_virtual_network" "examplevnet" {
  name                = "example-network"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  address_space       = ["10.0.0.0/16"]
}

# Create subnet
resource "azurerm_subnet" "my_terraform_subnet" {
  name                 = "mySubnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.examplevnet.name
  address_prefixes     = ["10.0.1.0/24"]
}

# Create public IPs
resource "azurerm_public_ip" "my_terraform_public_ip" {
  name                = "myPublicIP"
  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" "my_terraform_nsg" {
  name                = "myNetworkSecurityGroup"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  security_rule {
    name                       = "SSH"
    priority                   = 1001
    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" "my_terraform_nic" {
  name                = "myNIC"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  ip_configuration {
    name                          = "my_nic_configuration"
    subnet_id                     = azurerm_subnet.my_terraform_subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.my_terraform_public_ip.id
  }
}

# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
  network_interface_id      = azurerm_network_interface.my_terraform_nic.id
  network_security_group_id = azurerm_network_security_group.my_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" "my_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" "example_ssh" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

# Create virtual machine
resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
  name                  = "myVM"
  location              = azurerm_resource_group.rg.location
  resource_group_name   = azurerm_resource_group.rg.name
  network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
  size                  = "Standard_DS1_v2"

  os_disk {
    name                 = "myOsDisk"
    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                   = "myvm"
  admin_username                  = "azureuser"
  disable_password_authentication = true

  admin_ssh_key {
    username   = "azureuser"
    public_key = tls_private_key.example_ssh.public_key_openssh
  }

  boot_diagnostics {
    storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint
  }
}

Lastly, an outputs.tf so i can fetch the SSH key

output "resource_group_name" {
  value = azurerm_resource_group.rg.name
}

output "public_ip_address" {
  value = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address
}

output "tls_private_key" {
  value     = tls_private_key.example_ssh.private_key_pem
  sensitive = true
}

Then I need to do a terraform init -upgrade

$ terraform init -upgrade

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/tls versions matching "~> 4.0"...
- Finding hashicorp/azurerm versions matching "3.48.0"...
- Finding hashicorp/random versions matching "~> 3.0"...
- Installing hashicorp/tls v4.0.4...
- Installed hashicorp/tls v4.0.4 (signed by HashiCorp)
- Using previously-installed hashicorp/azurerm v3.48.0
- Installing hashicorp/random v3.4.3...
- Installed hashicorp/random v3.4.3 (signed by HashiCorp)

Terraform has made some changes to the provider dependency selections recorded
in the .terraform.lock.hcl file. Review those changes and commit them to your
version control system if they represent changes you intended to make.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Now a plan shows quite a lot will be done

$ terraform plan
azurerm_resource_group.examplerg: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg]
azurerm_virtual_network.examplevnet: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  # azurerm_linux_virtual_machine.my_terraform_vm will be created
  + resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
      + admin_username                  = "azureuser"
      + allow_extension_operations      = true
      + computer_name                   = "myvm"
      + disable_password_authentication = true
      + extensions_time_budget          = "PT1H30M"
      + id                              = (known after apply)
      + location                        = "eastus"
      + max_bid_price                   = -1
      + name                            = "myVM"
      + network_interface_ids           = (known after apply)
      + patch_assessment_mode           = "ImageDefault"
      + patch_mode                      = "ImageDefault"
      + platform_fault_domain           = -1
      + priority                        = "Regular"
      + private_ip_address              = (known after apply)
      + private_ip_addresses            = (known after apply)
      + provision_vm_agent              = true
      + public_ip_address               = (known after apply)
      + public_ip_addresses             = (known after apply)
      + resource_group_name             = "idj-east-rg"
      + size                            = "Standard_DS1_v2"
      + virtual_machine_id              = (known after apply)

      + admin_ssh_key {
          + public_key = (known after apply)
          + username   = "azureuser"
        }

      + boot_diagnostics {
          + storage_account_uri = (known after apply)
        }

      + os_disk {
          + caching                   = "ReadWrite"
          + disk_size_gb              = (known after apply)
          + name                      = "myOsDisk"
          + storage_account_type      = "Premium_LRS"
          + write_accelerator_enabled = false
        }

      + source_image_reference {
          + offer     = "0001-com-ubuntu-server-jammy"
          + publisher = "Canonical"
          + sku       = "22_04-lts-gen2"
          + version   = "latest"
        }
    }

  # azurerm_network_interface.my_terraform_nic will be created
  + resource "azurerm_network_interface" "my_terraform_nic" {
      + applied_dns_servers           = (known after apply)
      + dns_servers                   = (known after apply)
      + enable_accelerated_networking = false
      + enable_ip_forwarding          = false
      + id                            = (known after apply)
      + internal_dns_name_label       = (known after apply)
      + internal_domain_name_suffix   = (known after apply)
      + location                      = "eastus"
      + mac_address                   = (known after apply)
      + name                          = "myNIC"
      + private_ip_address            = (known after apply)
      + private_ip_addresses          = (known after apply)
      + resource_group_name           = "idj-east-rg"
      + virtual_machine_id            = (known after apply)

      + ip_configuration {
          + gateway_load_balancer_frontend_ip_configuration_id = (known after apply)
          + name                                               = "my_nic_configuration"
          + primary                                            = (known after apply)
          + private_ip_address                                 = (known after apply)
          + private_ip_address_allocation                      = "Dynamic"
          + private_ip_address_version                         = "IPv4"
          + public_ip_address_id                               = (known after apply)
          + subnet_id                                          = (known after apply)
        }
    }

  # azurerm_network_interface_security_group_association.example will be created
  + resource "azurerm_network_interface_security_group_association" "example" {
      + id                        = (known after apply)
      + network_interface_id      = (known after apply)
      + network_security_group_id = (known after apply)
    }

  # azurerm_network_security_group.my_terraform_nsg will be created
  + resource "azurerm_network_security_group" "my_terraform_nsg" {
      + id                  = (known after apply)
      + location            = "eastus"
      + name                = "myNetworkSecurityGroup"
      + resource_group_name = "idj-east-rg"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = ""
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "22"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "SSH"
              + priority                                   = 1001
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
    }

  # azurerm_public_ip.my_terraform_public_ip will be created
  + resource "azurerm_public_ip" "my_terraform_public_ip" {
      + allocation_method       = "Dynamic"
      + ddos_protection_mode    = "VirtualNetworkInherited"
      + fqdn                    = (known after apply)
      + id                      = (known after apply)
      + idle_timeout_in_minutes = 4
      + ip_address              = (known after apply)
      + ip_version              = "IPv4"
      + location                = "eastus"
      + name                    = "myPublicIP"
      + resource_group_name     = "idj-east-rg"
      + sku                     = "Basic"
      + sku_tier                = "Regional"
    }

  # azurerm_resource_group.examplerg will be destroyed
  # (because azurerm_resource_group.examplerg is not in configuration)
  - resource "azurerm_resource_group" "examplerg" {
      - id       = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg" -> null
      - location = "eastus" -> null
      - name     = "idj-east-rg" -> null
      - tags     = {} -> null
    }

  # azurerm_resource_group.rg will be created
  + resource "azurerm_resource_group" "rg" {
      + id       = (known after apply)
      + location = "eastus"
      + name     = "idj-east-rg"
    }

  # azurerm_storage_account.my_storage_account will be created
  + resource "azurerm_storage_account" "my_storage_account" {
      + access_tier                       = (known after apply)
      + account_kind                      = "StorageV2"
      + account_replication_type          = "LRS"
      + account_tier                      = "Standard"
      + allow_nested_items_to_be_public   = true
      + cross_tenant_replication_enabled  = true
      + default_to_oauth_authentication   = false
      + enable_https_traffic_only         = true
      + id                                = (known after apply)
      + infrastructure_encryption_enabled = false
      + is_hns_enabled                    = false
      + large_file_share_enabled          = (known after apply)
      + location                          = "eastus"
      + min_tls_version                   = "TLS1_2"
      + name                              = (known after apply)
      + nfsv3_enabled                     = false
      + primary_access_key                = (sensitive value)
      + primary_blob_connection_string    = (sensitive value)
      + primary_blob_endpoint             = (known after apply)
      + primary_blob_host                 = (known after apply)
      + primary_connection_string         = (sensitive value)
      + primary_dfs_endpoint              = (known after apply)
      + primary_dfs_host                  = (known after apply)
      + primary_file_endpoint             = (known after apply)
      + primary_file_host                 = (known after apply)
      + primary_location                  = (known after apply)
      + primary_queue_endpoint            = (known after apply)
      + primary_queue_host                = (known after apply)
      + primary_table_endpoint            = (known after apply)
      + primary_table_host                = (known after apply)
      + primary_web_endpoint              = (known after apply)
      + primary_web_host                  = (known after apply)
      + public_network_access_enabled     = true
      + queue_encryption_key_type         = "Service"
      + resource_group_name               = "idj-east-rg"
      + secondary_access_key              = (sensitive value)
      + secondary_blob_connection_string  = (sensitive value)
      + secondary_blob_endpoint           = (known after apply)
      + secondary_blob_host               = (known after apply)
      + secondary_connection_string       = (sensitive value)
      + secondary_dfs_endpoint            = (known after apply)
      + secondary_dfs_host                = (known after apply)
      + secondary_file_endpoint           = (known after apply)
      + secondary_file_host               = (known after apply)
      + secondary_location                = (known after apply)
      + secondary_queue_endpoint          = (known after apply)
      + secondary_queue_host              = (known after apply)
      + secondary_table_endpoint          = (known after apply)
      + secondary_table_host              = (known after apply)
      + secondary_web_endpoint            = (known after apply)
      + secondary_web_host                = (known after apply)
      + sftp_enabled                      = false
      + shared_access_key_enabled         = true
      + table_encryption_key_type         = "Service"
    }

  # azurerm_subnet.my_terraform_subnet will be created
  + resource "azurerm_subnet" "my_terraform_subnet" {
      + address_prefixes                               = [
          + "10.0.1.0/24",
        ]
      + enforce_private_link_endpoint_network_policies = (known after apply)
      + enforce_private_link_service_network_policies  = (known after apply)
      + id                                             = (known after apply)
      + name                                           = "mySubnet"
      + private_endpoint_network_policies_enabled      = (known after apply)
      + private_link_service_network_policies_enabled  = (known after apply)
      + resource_group_name                            = "idj-east-rg"
      + virtual_network_name                           = "example-network"
    }

  # random_id.random_id will be created
  + resource "random_id" "random_id" {
      + b64_std     = (known after apply)
      + b64_url     = (known after apply)
      + byte_length = 8
      + dec         = (known after apply)
      + hex         = (known after apply)
      + id          = (known after apply)
      + keepers     = {
          + "resource_group" = "idj-east-rg"
        }
    }

  # tls_private_key.example_ssh will be created
  + resource "tls_private_key" "example_ssh" {
      + algorithm                     = "RSA"
      + ecdsa_curve                   = "P224"
      + id                            = (known after apply)
      + private_key_openssh           = (sensitive value)
      + private_key_pem               = (sensitive value)
      + private_key_pem_pkcs8         = (sensitive value)
      + public_key_fingerprint_md5    = (known after apply)
      + public_key_fingerprint_sha256 = (known after apply)
      + public_key_openssh            = (known after apply)
      + public_key_pem                = (known after apply)
      + rsa_bits                      = 4096
    }

Plan: 10 to add, 0 to change, 1 to destroy.

Changes to Outputs:
  + public_ip_address   = (known after apply)
  + resource_group_name = "idj-east-rg"
  + tls_private_key     = (sensitive value)

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.

Remote Exec Provisioner

Let’s add a simple provisioner next that can setup Python inline

  provisioner "remote-exec" {
    inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"]

    connection {
      host        = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address
      type        = "ssh"
      user        = "azureuser"
      private_key = tls_private_key.example_ssh.private_key_pem
    }
  }

This makes our TF for the VM look like this


resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
  name                  = "myVM"
  location              = azurerm_resource_group.rg.location
  resource_group_name   = azurerm_resource_group.rg.name
  network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
  size                  = "Standard_DS1_v2"

  os_disk {
    name                 = "myOsDisk"
    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                   = "myvm"
  admin_username                  = "azureuser"
  disable_password_authentication = true

  admin_ssh_key {
    username   = "azureuser"
    public_key = tls_private_key.example_ssh.public_key_openssh
  }

  boot_diagnostics {
    storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint
  }

  provisioner "remote-exec" {
    inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"]

    connection {
      host        = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address
      type        = "ssh"
      user        = "azureuser"
      private_key = tls_private_key.example_ssh.private_key_pem
    }
  }

I’ll plan

$ terraform plan
tls_private_key.example_ssh: Refreshing state... [id=0e0824a94233b37283362ab9dfc50edde05231c3]
azurerm_resource_group.examplerg: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg]
azurerm_virtual_network.examplevnet: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply" which may have
affected this plan:

  # azurerm_virtual_network.examplevnet has been deleted
  - resource "azurerm_virtual_network" "examplevnet" {
        id                      = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network"
      - name                    = "example-network" -> null
        tags                    = {}
        # (7 unchanged attributes hidden)
    }


Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes,
the following plan may include actions to undo or respond to these changes.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_linux_virtual_machine.my_terraform_vm will be created
  + resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
      + admin_username                  = "azureuser"
      + allow_extension_operations      = true
      + computer_name                   = "myvm"
      + disable_password_authentication = true
      + extensions_time_budget          = "PT1H30M"
      + id                              = (known after apply)
      + location                        = "eastus"
      + max_bid_price                   = -1
      + name                            = "myVM"
      + network_interface_ids           = (known after apply)
      + patch_assessment_mode           = "ImageDefault"
      + patch_mode                      = "ImageDefault"
      + platform_fault_domain           = -1
      + priority                        = "Regular"
      + private_ip_address              = (known after apply)
      + private_ip_addresses            = (known after apply)
      + provision_vm_agent              = true
      + public_ip_address               = (known after apply)
      + public_ip_addresses             = (known after apply)
      + resource_group_name             = "idj-east-rg"
      + size                            = "Standard_DS1_v2"
      + virtual_machine_id              = (known after apply)

      + admin_ssh_key {
          + public_key = <<-EOT
                ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCgLUmizuehl+PE4j3jBBRqDkqOf0fCIbM1pobvBiXPfjDLXgaCC4h6jasw0KF8kNaZqJKxrGFTMma2c7nROKGqBTvLcxjyud2+Apx3NjcvH9q9ozXlwu3elrI0pzFB2rpH7b86iMHVuuhdMw4Xzv3OJt9PCytAmZhIRhdWp8niJMYpm+IM/PXLN2ksG6AGSw3QAROLeTfrmmaiHgj6hoNv9lKdWBIeYw4U2odvZG5QsQNaYzDb+UWh+b0un118Be6kTk1/QnSglfZ42HBChVtU+ZBSHFFeWDIK+ELi+7JfwqC2ckylmQRxfRV7VNnYe225LvtEqaJr+I2vfXNhnfPeJjoxcCpO0+upx5NJmqXYdqqINw0F+O2jnv6R62NFMLoPF+dUOe6+uh04gIA2AB8jyGHKgk/a+Ukqmfmo+6+Z9tB0mVMPKrXh646N+DjJrttFZuU3F33VYUGXI8zBvsp8PrwKWFIS27loV8Cmn7H6698+Hu19KzPEZ8J5MYcQZWGyphxVg8a/k9mP+uqSvOebTT652im0E6Vxmvi/s5rC1jkRaKPAYJcjeMWO9vPN7DUx+YlUNZNfF/yncMy+ZotWpr1TeGA+LVDM7gGdusB892vAJppucYos+D3NJfyq1yun6YVs4J8Rij0c2eQg89/Dq9ZliL1F8K28b2/1sDcnWw==
            EOT
          + username   = "azureuser"
        }

      + boot_diagnostics {
          + storage_account_uri = (known after apply)
        }

      + os_disk {
          + caching                   = "ReadWrite"
          + disk_size_gb              = (known after apply)
          + name                      = "myOsDisk"
          + storage_account_type      = "Premium_LRS"
          + write_accelerator_enabled = false
        }

      + source_image_reference {
          + offer     = "0001-com-ubuntu-server-jammy"
          + publisher = "Canonical"
          + sku       = "22_04-lts-gen2"
          + version   = "latest"
        }
    }

  # azurerm_network_interface.my_terraform_nic will be created
  + resource "azurerm_network_interface" "my_terraform_nic" {
      + applied_dns_servers           = (known after apply)
      + dns_servers                   = (known after apply)
      + enable_accelerated_networking = false
      + enable_ip_forwarding          = false
      + id                            = (known after apply)
      + internal_dns_name_label       = (known after apply)
      + internal_domain_name_suffix   = (known after apply)
      + location                      = "eastus"
      + mac_address                   = (known after apply)
      + name                          = "myNIC"
      + private_ip_address            = (known after apply)
      + private_ip_addresses          = (known after apply)
      + resource_group_name           = "idj-east-rg"
      + virtual_machine_id            = (known after apply)

      + ip_configuration {
          + gateway_load_balancer_frontend_ip_configuration_id = (known after apply)
          + name                                               = "my_nic_configuration"
          + primary                                            = (known after apply)
          + private_ip_address                                 = (known after apply)
          + private_ip_address_allocation                      = "Dynamic"
          + private_ip_address_version                         = "IPv4"
          + public_ip_address_id                               = (known after apply)
          + subnet_id                                          = (known after apply)
        }
    }

  # azurerm_network_interface_security_group_association.example will be created
  + resource "azurerm_network_interface_security_group_association" "example" {
      + id                        = (known after apply)
      + network_interface_id      = (known after apply)
      + network_security_group_id = (known after apply)
    }

  # azurerm_network_security_group.my_terraform_nsg will be created
  + resource "azurerm_network_security_group" "my_terraform_nsg" {
      + id                  = (known after apply)
      + location            = "eastus"
      + name                = "myNetworkSecurityGroup"
      + resource_group_name = "idj-east-rg"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = ""
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "22"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "SSH"
              + priority                                   = 1001
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
    }

  # azurerm_public_ip.my_terraform_public_ip will be created
  + resource "azurerm_public_ip" "my_terraform_public_ip" {
      + allocation_method       = "Dynamic"
      + ddos_protection_mode    = "VirtualNetworkInherited"
      + fqdn                    = (known after apply)
      + id                      = (known after apply)
      + idle_timeout_in_minutes = 4
      + ip_address              = (known after apply)
      + ip_version              = "IPv4"
      + location                = "eastus"
      + name                    = "myPublicIP"
      + resource_group_name     = "idj-east-rg"
      + sku                     = "Basic"
      + sku_tier                = "Regional"
    }

  # azurerm_resource_group.rg will be created
  + resource "azurerm_resource_group" "rg" {
      + id       = (known after apply)
      + location = "eastus"
      + name     = "idj-east-rg"
    }

  # azurerm_storage_account.my_storage_account will be created
  + resource "azurerm_storage_account" "my_storage_account" {
      + access_tier                       = (known after apply)
      + account_kind                      = "StorageV2"
      + account_replication_type          = "LRS"
      + account_tier                      = "Standard"
      + allow_nested_items_to_be_public   = true
      + cross_tenant_replication_enabled  = true
      + default_to_oauth_authentication   = false
      + enable_https_traffic_only         = true
      + id                                = (known after apply)
      + infrastructure_encryption_enabled = false
      + is_hns_enabled                    = false
      + large_file_share_enabled          = (known after apply)
      + location                          = "eastus"
      + min_tls_version                   = "TLS1_2"
      + name                              = (known after apply)
      + nfsv3_enabled                     = false
      + primary_access_key                = (sensitive value)
      + primary_blob_connection_string    = (sensitive value)
      + primary_blob_endpoint             = (known after apply)
      + primary_blob_host                 = (known after apply)
      + primary_connection_string         = (sensitive value)
      + primary_dfs_endpoint              = (known after apply)
      + primary_dfs_host                  = (known after apply)
      + primary_file_endpoint             = (known after apply)
      + primary_file_host                 = (known after apply)
      + primary_location                  = (known after apply)
      + primary_queue_endpoint            = (known after apply)
      + primary_queue_host                = (known after apply)
      + primary_table_endpoint            = (known after apply)
      + primary_table_host                = (known after apply)
      + primary_web_endpoint              = (known after apply)
      + primary_web_host                  = (known after apply)
      + public_network_access_enabled     = true
      + queue_encryption_key_type         = "Service"
      + resource_group_name               = "idj-east-rg"
      + secondary_access_key              = (sensitive value)
      + secondary_blob_connection_string  = (sensitive value)
      + secondary_blob_endpoint           = (known after apply)
      + secondary_blob_host               = (known after apply)
      + secondary_connection_string       = (sensitive value)
      + secondary_dfs_endpoint            = (known after apply)
      + secondary_dfs_host                = (known after apply)
      + secondary_file_endpoint           = (known after apply)
      + secondary_file_host               = (known after apply)
      + secondary_location                = (known after apply)
      + secondary_queue_endpoint          = (known after apply)
      + secondary_queue_host              = (known after apply)
      + secondary_table_endpoint          = (known after apply)
      + secondary_table_host              = (known after apply)
      + secondary_web_endpoint            = (known after apply)
      + secondary_web_host                = (known after apply)
      + sftp_enabled                      = false
      + shared_access_key_enabled         = true
      + table_encryption_key_type         = "Service"
    }

  # azurerm_subnet.my_terraform_subnet will be created
  + resource "azurerm_subnet" "my_terraform_subnet" {
      + address_prefixes                               = [
          + "10.0.1.0/24",
        ]
      + enforce_private_link_endpoint_network_policies = (known after apply)
      + enforce_private_link_service_network_policies  = (known after apply)
      + id                                             = (known after apply)
      + name                                           = "mySubnet"
      + private_endpoint_network_policies_enabled      = (known after apply)
      + private_link_service_network_policies_enabled  = (known after apply)
      + resource_group_name                            = "idj-east-rg"
      + virtual_network_name                           = "example-network"
    }

  # azurerm_virtual_network.examplevnet will be created
  + resource "azurerm_virtual_network" "examplevnet" {
      + address_space       = [
          + "10.0.0.0/16",
        ]
      + dns_servers         = (known after apply)
      + guid                = (known after apply)
      + id                  = (known after apply)
      + location            = "eastus"
      + name                = "example-network"
      + resource_group_name = "idj-east-rg"
      + subnet              = (known after apply)
    }

  # random_id.random_id will be created
  + resource "random_id" "random_id" {
      + b64_std     = (known after apply)
      + b64_url     = (known after apply)
      + byte_length = 8
      + dec         = (known after apply)
      + hex         = (known after apply)
      + id          = (known after apply)
      + keepers     = {
          + "resource_group" = "idj-east-rg"
        }
    }

Plan: 10 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + public_ip_address   = (known after apply)

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.
builder@DESKTOP-72D2D9T:~/Workspaces/tfAnsibleAzure$

I should note I made a mess for myself by renaming the resource group variable. Terraform tried to delete and re-add and just got itself hung up. Since there was nothing of import there, I just deleted the old resource group (with vnet) to make it clean)

Applying the changes

$ terraform apply
tls_private_key.example_ssh: Refreshing state... [id=0e0824a94233b37283362ab9dfc50edde05231c3]
azurerm_resource_group.examplerg: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg]
azurerm_virtual_network.examplevnet: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply" which may have
affected this plan:

  # azurerm_virtual_network.examplevnet has been deleted
  - resource "azurerm_virtual_network" "examplevnet" {
        id                      = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network"
      - name                    = "example-network" -> null
        tags                    = {}
        # (7 unchanged attributes hidden)
    }


Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes,
the following plan may include actions to undo or respond to these changes.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_linux_virtual_machine.my_terraform_vm will be created
  + resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
      + admin_username                  = "azureuser"
      + allow_extension_operations      = true
      + computer_name                   = "myvm"
      + disable_password_authentication = true
      + extensions_time_budget          = "PT1H30M"
      + id                              = (known after apply)
      + location                        = "eastus"
      + max_bid_price                   = -1
      + name                            = "myVM"
      + network_interface_ids           = (known after apply)
      + patch_assessment_mode           = "ImageDefault"
      + patch_mode                      = "ImageDefault"
      + platform_fault_domain           = -1
      + priority                        = "Regular"
      + private_ip_address              = (known after apply)
      + private_ip_addresses            = (known after apply)
      + provision_vm_agent              = true
      + public_ip_address               = (known after apply)
      + public_ip_addresses             = (known after apply)
      + resource_group_name             = "idj-east-rg"
      + size                            = "Standard_DS1_v2"
      + virtual_machine_id              = (known after apply)

      + admin_ssh_key {
          + public_key = <<-EOT
                ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCgLUmizuehl+PE4j3jBBRqDkqOf0fCIbM1pobvBiXPfjDLXgaCC4h6jasw0KF8kNaZqJKxrGFTMma2c7nROKGqBTvLcxjyud2+Apx3NjcvH9q9ozXlwu3elrI0pzFB2rpH7b86iMHVuuhdMw4Xzv3OJt9PCytAmZhIRhdWp8niJMYpm+IM/PXLN2ksG6AGSw3QAROLeTfrmmaiHgj6hoNv9lKdWBIeYw4U2odvZG5QsQNaYzDb+UWh+b0un118Be6kTk1/QnSglfZ42HBChVtU+ZBSHFFeWDIK+ELi+7JfwqC2ckylmQRxfRV7VNnYe225LvtEqaJr+I2vfXNhnfPeJjoxcCpO0+upx5NJmqXYdqqINw0F+O2jnv6R62NFMLoPF+dUOe6+uh04gIA2AB8jyGHKgk/a+Ukqmfmo+6+Z9tB0mVMPKrXh646N+DjJrttFZuU3F33VYUGXI8zBvsp8PrwKWFIS27loV8Cmn7H6698+Hu19KzPEZ8J5MYcQZWGyphxVg8a/k9mP+uqSvOebTT652im0E6Vxmvi/s5rC1jkRaKPAYJcjeMWO9vPN7DUx+YlUNZNfF/yncMy+ZotWpr1TeGA+LVDM7gGdusB892vAJppucYos+D3NJfyq1yun6YVs4J8Rij0c2eQg89/Dq9ZliL1F8K28b2/1sDcnWw==
            EOT
          + username   = "azureuser"
        }

      + boot_diagnostics {
          + storage_account_uri = (known after apply)
        }

      + os_disk {
          + caching                   = "ReadWrite"
          + disk_size_gb              = (known after apply)
          + name                      = "myOsDisk"
          + storage_account_type      = "Premium_LRS"
          + write_accelerator_enabled = false
        }

      + source_image_reference {
          + offer     = "0001-com-ubuntu-server-jammy"
          + publisher = "Canonical"
          + sku       = "22_04-lts-gen2"
          + version   = "latest"
        }
    }

  # azurerm_network_interface.my_terraform_nic will be created
  + resource "azurerm_network_interface" "my_terraform_nic" {
      + applied_dns_servers           = (known after apply)
      + dns_servers                   = (known after apply)
      + enable_accelerated_networking = false
      + enable_ip_forwarding          = false
      + id                            = (known after apply)
      + internal_dns_name_label       = (known after apply)
      + internal_domain_name_suffix   = (known after apply)
      + location                      = "eastus"
      + mac_address                   = (known after apply)
      + name                          = "myNIC"
      + private_ip_address            = (known after apply)
      + private_ip_addresses          = (known after apply)
      + resource_group_name           = "idj-east-rg"
      + virtual_machine_id            = (known after apply)

      + ip_configuration {
          + gateway_load_balancer_frontend_ip_configuration_id = (known after apply)
          + name                                               = "my_nic_configuration"
          + primary                                            = (known after apply)
          + private_ip_address                                 = (known after apply)
          + private_ip_address_allocation                      = "Dynamic"
          + private_ip_address_version                         = "IPv4"
          + public_ip_address_id                               = (known after apply)
          + subnet_id                                          = (known after apply)
        }
    }

  # azurerm_network_interface_security_group_association.example will be created
  + resource "azurerm_network_interface_security_group_association" "example" {
      + id                        = (known after apply)
      + network_interface_id      = (known after apply)
      + network_security_group_id = (known after apply)
    }

  # azurerm_network_security_group.my_terraform_nsg will be created
  + resource "azurerm_network_security_group" "my_terraform_nsg" {
      + id                  = (known after apply)
      + location            = "eastus"
      + name                = "myNetworkSecurityGroup"
      + resource_group_name = "idj-east-rg"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = ""
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "22"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "SSH"
              + priority                                   = 1001
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
    }

  # azurerm_public_ip.my_terraform_public_ip will be created
  + resource "azurerm_public_ip" "my_terraform_public_ip" {
      + allocation_method       = "Dynamic"
      + ddos_protection_mode    = "VirtualNetworkInherited"
      + fqdn                    = (known after apply)
      + id                      = (known after apply)
      + idle_timeout_in_minutes = 4
      + ip_address              = (known after apply)
      + ip_version              = "IPv4"
      + location                = "eastus"
      + name                    = "myPublicIP"
      + resource_group_name     = "idj-east-rg"
      + sku                     = "Basic"
      + sku_tier                = "Regional"
    }

  # azurerm_resource_group.rg will be created
  + resource "azurerm_resource_group" "rg" {
      + id       = (known after apply)
      + location = "eastus"
      + name     = "idj-east-rg"
    }

  # azurerm_storage_account.my_storage_account will be created
  + resource "azurerm_storage_account" "my_storage_account" {
      + access_tier                       = (known after apply)
      + account_kind                      = "StorageV2"
      + account_replication_type          = "LRS"
      + account_tier                      = "Standard"
      + allow_nested_items_to_be_public   = true
      + cross_tenant_replication_enabled  = true
      + default_to_oauth_authentication   = false
      + enable_https_traffic_only         = true
      + id                                = (known after apply)
      + infrastructure_encryption_enabled = false
      + is_hns_enabled                    = false
      + large_file_share_enabled          = (known after apply)
      + location                          = "eastus"
      + min_tls_version                   = "TLS1_2"
      + name                              = (known after apply)
      + nfsv3_enabled                     = false
      + primary_access_key                = (sensitive value)
      + primary_blob_connection_string    = (sensitive value)
      + primary_blob_endpoint             = (known after apply)
      + primary_blob_host                 = (known after apply)
      + primary_connection_string         = (sensitive value)
      + primary_dfs_endpoint              = (known after apply)
      + primary_dfs_host                  = (known after apply)
      + primary_file_endpoint             = (known after apply)
      + primary_file_host                 = (known after apply)
      + primary_location                  = (known after apply)
      + primary_queue_endpoint            = (known after apply)
      + primary_queue_host                = (known after apply)
      + primary_table_endpoint            = (known after apply)
      + primary_table_host                = (known after apply)
      + primary_web_endpoint              = (known after apply)
      + primary_web_host                  = (known after apply)
      + public_network_access_enabled     = true
      + queue_encryption_key_type         = "Service"
      + resource_group_name               = "idj-east-rg"
      + secondary_access_key              = (sensitive value)
      + secondary_blob_connection_string  = (sensitive value)
      + secondary_blob_endpoint           = (known after apply)
      + secondary_blob_host               = (known after apply)
      + secondary_connection_string       = (sensitive value)
      + secondary_dfs_endpoint            = (known after apply)
      + secondary_dfs_host                = (known after apply)
      + secondary_file_endpoint           = (known after apply)
      + secondary_file_host               = (known after apply)
      + secondary_location                = (known after apply)
      + secondary_queue_endpoint          = (known after apply)
      + secondary_queue_host              = (known after apply)
      + secondary_table_endpoint          = (known after apply)
      + secondary_table_host              = (known after apply)
      + secondary_web_endpoint            = (known after apply)
      + secondary_web_host                = (known after apply)
      + sftp_enabled                      = false
      + shared_access_key_enabled         = true
      + table_encryption_key_type         = "Service"
    }

  # azurerm_subnet.my_terraform_subnet will be created
  + resource "azurerm_subnet" "my_terraform_subnet" {
      + address_prefixes                               = [
          + "10.0.1.0/24",
        ]
      + enforce_private_link_endpoint_network_policies = (known after apply)
      + enforce_private_link_service_network_policies  = (known after apply)
      + id                                             = (known after apply)
      + name                                           = "mySubnet"
      + private_endpoint_network_policies_enabled      = (known after apply)
      + private_link_service_network_policies_enabled  = (known after apply)
      + resource_group_name                            = "idj-east-rg"
      + virtual_network_name                           = "example-network"
    }

  # azurerm_virtual_network.examplevnet will be created
  + resource "azurerm_virtual_network" "examplevnet" {
      + address_space       = [
          + "10.0.0.0/16",
        ]
      + dns_servers         = (known after apply)
      + guid                = (known after apply)
      + id                  = (known after apply)
      + location            = "eastus"
      + name                = "example-network"
      + resource_group_name = "idj-east-rg"
      + subnet              = (known after apply)
    }

  # random_id.random_id will be created
  + resource "random_id" "random_id" {
      + b64_std     = (known after apply)
      + b64_url     = (known after apply)
      + byte_length = 8
      + dec         = (known after apply)
      + hex         = (known after apply)
      + id          = (known after apply)
      + keepers     = {
          + "resource_group" = "idj-east-rg"
        }
    }

Plan: 10 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + public_ip_address   = (known after apply)

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_resource_group.rg: Creating...
azurerm_resource_group.rg: Creation complete after 1s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg]
azurerm_virtual_network.examplevnet: Creating...
azurerm_public_ip.my_terraform_public_ip: Creating...
azurerm_network_security_group.my_terraform_nsg: Creating...
random_id.random_id: Creating...
random_id.random_id: Creation complete after 0s [id=9-XSBWLaVIk]
azurerm_storage_account.my_storage_account: Creating...
azurerm_public_ip.my_terraform_public_ip: Creation complete after 3s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/publicIPAddresses/myPublicIP]
azurerm_virtual_network.examplevnet: Creation complete after 5s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network]
azurerm_subnet.my_terraform_subnet: Creating...
azurerm_network_security_group.my_terraform_nsg: Creation complete after 5s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_storage_account.my_storage_account: Still creating... [10s elapsed]
azurerm_subnet.my_terraform_subnet: Creation complete after 5s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network/subnets/mySubnet]
azurerm_network_interface.my_terraform_nic: Creating...
azurerm_network_interface.my_terraform_nic: Creation complete after 1s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC]
azurerm_network_interface_security_group_association.example: Creating...
azurerm_network_interface_security_group_association.example: Creation complete after 2s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC|/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_storage_account.my_storage_account: Still creating... [20s elapsed]
azurerm_storage_account.my_storage_account: Creation complete after 26s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Storage/storageAccounts/diagf7e5d20562da5489]
azurerm_linux_virtual_machine.my_terraform_vm: Creating...
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [10s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [20s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [30s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [40s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Provisioning with 'remote-exec'...
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Connecting to remote host via SSH...
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Host: 20.25.72.182
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   User: azureuser
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Password: false
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Private key: true
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Certificate: false
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   SSH Agent: false
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Checking Host Key: false
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Target Platform: unix
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Connected!
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [50s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Hit:1 http://azure.archive.ubuntu.com/ubuntu jammy InRelease
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Waiting for headers]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:2 http://azure.archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:3 http://azure.archive.ubuntu.com/ubuntu jammy-backports InRelease [107 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:4 http://azure.archive.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:5 http://azure.archive.ubuntu.com/ubuntu jammy/universe amd64 Packages [14.1 MB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages 295 kB/14.1 MB 2%]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:6 http://azure.archive.ubuntu.com/ubuntu jammy/universe Translation-en [5652 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [6 Translation-en 318 kB/5652 kB 6%]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [6 Translatio
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:7 http://azure.archive.ubuntu.com/ubuntu jammy/universe amd64 c-n-f Metadata [286 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [7 Commands-a
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:8 http://azure.archive.ubuntu.com/ubuntu jammy/multiverse amd64 Packages [217 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [8 Packages 0
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:9 http://azure.archive.ubuntu.com/ubuntu jammy/multiverse Translation-en [112 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [9 Translatio
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:10 http://azure.archive.ubuntu.com/ubuntu jammy/multiverse amd64 c-n-f Metadata [8372 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [10 Commands-
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:11 http://azure.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [949 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [11 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:12 http://azure.archive.ubuntu.com/ubuntu jammy-updates/main Translation-en [205 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [12 Translati
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:13 http://azure.archive.ubuntu.com/ubuntu jammy-updates/main amd64 c-n-f Metadata [13.8 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [13 Commands-
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:14 http://azure.archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [684 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [14 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:15 http://azure.archive.ubuntu.com/ubuntu jammy-updates/restricted Translation-en [107 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [15 Translati
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:16 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [895 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [16 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:17 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe Translation-en [179 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [17 Translati
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:18 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 c-n-f Metadata [18.4 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [18 Commands-
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:19 http://azure.archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 Packages [24.1 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [19 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:20 http://azure.archive.ubuntu.com/ubuntu jammy-updates/multiverse Translation-en [6312 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [20 Translati
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:21 http://azure.archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 c-n-f Metadata [444 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [21 Commands-
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:22 http://azure.archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages [40.7 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:23 http://azure.archive.ubuntu.com/ubuntu jammy-backports/main Translation-en [9800 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:24 http://azure.archive.ubuntu.com/ubuntu jammy-backports/main amd64 c-n-f Metadata [392 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:25 http://azure.archive.ubuntu.com/ubuntu jammy-backports/restricted amd64 c-n-f Metadata [116 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [Waiting for
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:26 http://azure.archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages [19.5 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:27 http://azure.archive.ubuntu.com/ubuntu jammy-backports/universe Translation-en [14.0 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [Waiting for
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:28 http://azure.archive.ubuntu.com/ubuntu jammy-backports/universe amd64 c-n-f Metadata [392 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [Waiting for
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:29 http://azure.archive.ubuntu.com/ubuntu jammy-backports/multiverse amd64 c-n-f Metadata [116 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 84% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:30 http://azure.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages [693 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B] [30 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:31 http://azure.archive.ubuntu.com/ubuntu jammy-security/main Translation-en [143 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:32 http://azure.archive.ubuntu.com/ubuntu jammy-security/main amd64 c-n-f Metadata [9016 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B] [Waiting for
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:33 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [645 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B] [33 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 88% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:34 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted Translation-en [100 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 88% [5 Packages store 0 B] [34 Translat
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 89% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:35 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted amd64 c-n-f Metadata [588 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 89% [5 Packages store 0 B] [35 Commands
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 89% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:36 http://azure.archive.ubuntu.com/ubuntu jammy-security/universe amd64 Packages [714 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 89% [5 Packages store 0 B] [36 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:37 http://azure.archive.ubuntu.com/ubuntu jammy-security/universe Translation-en [118 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [37 Translat
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:38 http://azure.archive.ubuntu.com/ubuntu jammy-security/universe amd64 c-n-f Metadata [14.1 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [38 Commands
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:39 http://azure.archive.ubuntu.com/ubuntu jammy-security/multiverse amd64 Packages [19.4 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [39 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:40 http://azure.archive.ubuntu.com/ubuntu jammy-security/multiverse Translation-en [4068 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [40 Translat
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:41 http://azure.archive.ubuntu.com/ubuntu jammy-security/multiverse amd64 c-n-f Metadata [228 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [41 Commands
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [6 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [6 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [7 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [8 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [9 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [10 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [11 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [12 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [13 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [14 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [15 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [16 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [17 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [18 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [19 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [20 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [21 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [22 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [23 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [24 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [25 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [26 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [27 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [28 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [29 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [30 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [31 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [32 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [33 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [34 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [35 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [36 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [37 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [38 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [39 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [40 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [41 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Fetched 26.3 MB in 4s (5941 kB/s)
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [1m0s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 4%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 4%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 6%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 6%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 7%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 7%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 7%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 7%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 71%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 71%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 71%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 71%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 72%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 72%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 75%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 75%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 77%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 77%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 80%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 80%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 81%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 81%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 85%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 85%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 89%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 89%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 91%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 91%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 94%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 94%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 95%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 95%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 98%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 98%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 21 packages can be upgraded. Run 'apt list --upgradable' to see them.
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 100%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): python3 is already the newest version (3.10.6-1~22.04).
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): python3 set to manually installed.
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0 upgraded, 0 newly installed, 0 to remove and 21 not upgraded.
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Done!
azurerm_linux_virtual_machine.my_terraform_vm: Creation complete after 1m5s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Compute/virtualMachines/myVM]

Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

Outputs:

public_ip_address = "20.25.72.182"
resource_group_name = "idj-east-rg"
tls_private_key = <sensitive>

I’ll need that key to login;

$ terraform output -raw tls_private_key > id_rsa
$ chmod 600 id_rsa
$ ssh -i id_rsa azureuser@`terraform output -raw public_ip_address`
The authenticity of host '20.25.72.182 (20.25.72.182)' can't be established.
ECDSA key fingerprint is SHA256:PVVSQEOgT99asx476noAtO4v+ovuCjwpMgDeTtopW+I.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '20.25.72.182' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-1034-azure x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun Mar 26 13:49:17 UTC 2023

  System load:  0.013671875       Processes:             102
  Usage of /:   5.7% of 28.89GB   Users logged in:       0
  Memory usage: 8%                IPv4 address for eth0: 10.0.1.4
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

21 updates can be applied immediately.
13 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


Last login: Sun Mar 26 13:45:16 2023 from 73.242.50.46
azureuser@myvm:~$

The part I’m most keen to verify is the provisioner block

  provisioner "remote-exec" {
    inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"]

    connection {
      host        = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address
      type        = "ssh"
      user        = "azureuser"
      private_key = tls_private_key.example_ssh.private_key_pem
    }
  }

Let’s check for which python is there.

azureuser@myvm:~$ ls -lra /usr/bin/  | grep python
-rwxr-xr-x  1 root root     5921160 Nov 14 16:10 python3.10
lrwxrwxrwx  1 root root          10 Aug 18  2022 python3 -> python3.10
-rwxr-xr-x  1 root root         953 May  1  2021 pybabel-python3
lrwxrwxrwx  1 root root          31 Aug 18  2022 py3versions -> ../share/python3/py3versions.py
lrwxrwxrwx  1 root root          24 Nov 14 16:10 pdb3.10 -> ../lib/python3.10/pdb.py
azureuser@myvm:~$

Adding in Ansible with Local Exec Provisioner

Now let’s add in a basic Apache2 playbook

$ cat apache-install.yhml
- become: yes
  hosts: all
  name: apache-install
  tasks:
    - name: Add the user 'stuart' and add it to 'sudo'
      user:
        name: stuart
        group: sudo
        
    - name: Add SSH key to 'stuart'
      authorized_key:
        user: stuart
        state: present
        key: "{{ lookup('file', pub_key) }}"
        
    - name: Wait for apt to unlock
      become: yes
      shell:  while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 5; done;
      
    - name: Install apache2
      apt:
        name: apache2
        update_cache: yes
        state: latest
      
    - name: Enable mod_rewrite
      apache2_module:
        name: rewrite 
        state: present
      notify:
        - Restart apache2

  handlers:
    - name: Restart apache2
      service:
        name: apache2
        state: restarted

And I’ll make reference at the end of main.tf to use the ‘local’ provisioner to run the Ansible

  ...snip...
  provisioner "remote-exec" {
    inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"]

    connection {
      host        = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address
      type        = "ssh"
      user        = "azureuser"
      private_key = tls_private_key.example_ssh.private_key_pem
    }
  }

  provisioner "local-exec" {
    command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u azureuser -i '${azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address},' --private-key ${tls_private_key.example_ssh.private_key_pem} -e 'pub_key=${tls_private_key.example_ssh.public_key_openssh}' apache-install.yml"
  }
}

I couldn’t get the local-exec to fire on an existing VM. A suggestion of adding “triggers” with a timestamp didn’t work.

So i commented out the whole VM (and IP output in outputs.tf) and applied

... snip ...

Plan: 0 to add, 0 to change, 1 to destroy.

Changes to Outputs:
  - public_ip_address   = "20.25.72.182" -> null

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.
builder@DESKTOP-72D2D9T:~/Workspaces/tfAnsibleAzure$ terraform apply
tls_private_key.example_ssh: Refreshing state... [id=0e0824a94233b37283362ab9dfc50edde05231c3]
... snip ...

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

Outputs:

resource_group_name = "idj-east-rg"
tls_private_key = <sensitive>

Before we can use local-exec, ensure you have Ansible installed locally (in order to invoke ansible-playbook)

$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt update && sudo apt install -y ansible
$ which ansible-playbook
/usr/bin/ansible-playbook

Then added back and applied

$ terraform apply
tls_private_key.example_ssh: Refreshing state... [id=0e0824a94233b37283362ab9dfc50edde05231c3]
local_file.idrsa: Refreshing state... [id=6e94572c465335f793b2cf9090a31e740d140685]
azurerm_resource_group.rg: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg]
azurerm_virtual_network.examplevnet: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network]
azurerm_public_ip.my_terraform_public_ip: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/publicIPAddresses/myPublicIP]
random_id.random_id: Refreshing state... [id=9-XSBWLaVIk]
azurerm_network_security_group.my_terraform_nsg: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_storage_account.my_storage_account: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Storage/storageAccounts/diagf7e5d20562da5489]
azurerm_subnet.my_terraform_subnet: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network/subnets/mySubnet]
azurerm_network_interface.my_terraform_nic: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC]
azurerm_network_interface_security_group_association.example: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC|/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_linux_virtual_machine.my_terraform_vm will be created
  + resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
      + admin_username                  = "azureuser"
      + allow_extension_operations      = true
      + computer_name                   = "myvm"
      + disable_password_authentication = true
      + extensions_time_budget          = "PT1H30M"
      + id                              = (known after apply)
      + location                        = "eastus"
      + max_bid_price                   = -1
      + name                            = "myVM"
      + network_interface_ids           = [
          + "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC",
        ]
      + patch_assessment_mode           = "ImageDefault"
      + patch_mode                      = "ImageDefault"
      + platform_fault_domain           = -1
      + priority                        = "Regular"
      + private_ip_address              = (known after apply)
      + private_ip_addresses            = (known after apply)
      + provision_vm_agent              = true
      + public_ip_address               = (known after apply)
      + public_ip_addresses             = (known after apply)
      + resource_group_name             = "idj-east-rg"
      + size                            = "Standard_DS1_v2"
      + virtual_machine_id              = (known after apply)

      + admin_ssh_key {
          + public_key = <<-EOT
                ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCgLUmizuehl+PE4j3jBBRqDkqOf0fCIbM1pobvBiXPfjDLXgaCC4h6jasw0KF8kNaZqJKxrGFTMma2c7nROKGqBTvLcxjyud2+Apx3NjcvH9q9ozXlwu3elrI0pzFB2rpH7b86iMHVuuhdMw4Xzv3OJt9PCytAmZhIRhdWp8niJMYpm+IM/PXLN2ksG6AGSw3QAROLeTfrmmaiHgj6hoNv9lKdWBIeYw4U2odvZG5QsQNaYzDb+UWh+b0un118Be6kTk1/QnSglfZ42HBChVtU+ZBSHFFeWDIK+ELi+7JfwqC2ckylmQRxfRV7VNnYe225LvtEqaJr+I2vfXNhnfPeJjoxcCpO0+upx5NJmqXYdqqINw0F+O2jnv6R62NFMLoPF+dUOe6+uh04gIA2AB8jyGHKgk/a+Ukqmfmo+6+Z9tB0mVMPKrXh646N+DjJrttFZuU3F33VYUGXI8zBvsp8PrwKWFIS27loV8Cmn7H6698+Hu19KzPEZ8J5MYcQZWGyphxVg8a/k9mP+uqSvOebTT652im0E6Vxmvi/s5rC1jkRaKPAYJcjeMWO9vPN7DUx+YlUNZNfF/yncMy+ZotWpr1TeGA+LVDM7gGdusB892vAJppucYos+D3NJfyq1yun6YVs4J8Rij0c2eQg89/Dq9ZliL1F8K28b2/1sDcnWw==
            EOT
          + username   = "azureuser"
        }

      + boot_diagnostics {
          + storage_account_uri = "https://diagf7e5d20562da5489.blob.core.windows.net/"
        }

      + os_disk {
          + caching                   = "ReadWrite"
          + disk_size_gb              = (known after apply)
          + name                      = "myOsDisk"
          + storage_account_type      = "Premium_LRS"
          + write_accelerator_enabled = false
        }

      + source_image_reference {
          + offer     = "0001-com-ubuntu-server-jammy"
          + publisher = "Canonical"
          + sku       = "22_04-lts-gen2"
          + version   = "latest"
        }
    }

  # local_file.idrsapub will be created
  + resource "local_file" "idrsapub" {
      + content              = <<-EOT
            ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCgLUmizuehl+PE4j3jBBRqDkqOf0fCIbM1pobvBiXPfjDLXgaCC4h6jasw0KF8kNaZqJKxrGFTMma2c7nROKGqBTvLcxjyud2+Apx3NjcvH9q9ozXlwu3elrI0pzFB2rpH7b86iMHVuuhdMw4Xzv3OJt9PCytAmZhIRhdWp8niJMYpm+IM/PXLN2ksG6AGSw3QAROLeTfrmmaiHgj6hoNv9lKdWBIeYw4U2odvZG5QsQNaYzDb+UWh+b0un118Be6kTk1/QnSglfZ42HBChVtU+ZBSHFFeWDIK+ELi+7JfwqC2ckylmQRxfRV7VNnYe225LvtEqaJr+I2vfXNhnfPeJjoxcCpO0+upx5NJmqXYdqqINw0F+O2jnv6R62NFMLoPF+dUOe6+uh04gIA2AB8jyGHKgk/a+Ukqmfmo+6+Z9tB0mVMPKrXh646N+DjJrttFZuU3F33VYUGXI8zBvsp8PrwKWFIS27loV8Cmn7H6698+Hu19KzPEZ8J5MYcQZWGyphxVg8a/k9mP+uqSvOebTT652im0E6Vxmvi/s5rC1jkRaKPAYJcjeMWO9vPN7DUx+YlUNZNfF/yncMy+ZotWpr1TeGA+LVDM7gGdusB892vAJppucYos+D3NJfyq1yun6YVs4J8Rij0c2eQg89/Dq9ZliL1F8K28b2/1sDcnWw==
        EOT
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0633"
      + filename             = "./id_rsa.pub"
      + id                   = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + public_ip_address   = (known after apply)

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

local_file.idrsapub: Creating...
local_file.idrsapub: Creation complete after 0s [id=b338a4a88b429fe02532cb17077592c28190188a]
azurerm_linux_virtual_machine.my_terraform_vm: Creating...
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [10s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [20s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [30s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [40s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Provisioning with 'remote-exec'...
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Connecting to remote host via SSH...
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Host: 20.127.1.163
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   User: azureuser
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Password: false
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Private key: true
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Certificate: false
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   SSH Agent: false
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Checking Host Key: false
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):   Target Platform: unix
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Connected!
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [50s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Hit:1 http://azure.archive.ubuntu.com/ubuntu jammy InRelease
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:2 http://azure.archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:3 http://azure.archive.ubuntu.com/ubuntu jammy-backports InRelease [107 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:4 http://azure.archive.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:5 http://azure.archive.ubuntu.com/ubuntu jammy/universe amd64 Packages [14.1 MB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages 253 kB/14.1 MB 2%]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [Waiting for
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:6 http://azure.archive.ubuntu.com/ubuntu jammy/universe Translation-en [5652 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [6 Translatio
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:7 http://azure.archive.ubuntu.com/ubuntu jammy/universe amd64 c-n-f Metadata [286 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [7 Commands-a
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:8 http://azure.archive.ubuntu.com/ubuntu jammy/multiverse amd64 Packages [217 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:9 http://azure.archive.ubuntu.com/ubuntu jammy/multiverse Translation-en [112 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [9 Translatio
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:10 http://azure.archive.ubuntu.com/ubuntu jammy/multiverse amd64 c-n-f Metadata [8372 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [10 Commands-
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:11 http://azure.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [949 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [11 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:12 http://azure.archive.ubuntu.com/ubuntu jammy-updates/main Translation-en [205 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [12 Translati
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:13 http://azure.archive.ubuntu.com/ubuntu jammy-updates/main amd64 c-n-f Metadata [13.8 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [13 Commands-
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:14 http://azure.archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [684 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [14 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:15 http://azure.archive.ubuntu.com/ubuntu jammy-updates/restricted Translation-en [107 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [15 Translati
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:16 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [895 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [16 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:17 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe Translation-en [179 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [17 Translati
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:18 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 c-n-f Metadata [18.4 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [18 Commands-
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:19 http://azure.archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 Packages [24.1 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [19 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:20 http://azure.archive.ubuntu.com/ubuntu jammy-updates/multiverse Translation-en [6312 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [20 Translati
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:21 http://azure.archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 c-n-f Metadata [444 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B] [21 Commands-
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:22 http://azure.archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages [40.7 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:23 http://azure.archive.ubuntu.com/ubuntu jammy-backports/main Translation-en [9800 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:24 http://azure.archive.ubuntu.com/ubuntu jammy-backports/main amd64 c-n-f Metadata [392 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:25 http://azure.archive.ubuntu.com/ubuntu jammy-backports/restricted amd64 c-n-f Metadata [116 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:26 http://azure.archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages [19.5 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:27 http://azure.archive.ubuntu.com/ubuntu jammy-backports/universe Translation-en [14.0 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:28 http://azure.archive.ubuntu.com/ubuntu jammy-backports/universe amd64 c-n-f Metadata [392 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:29 http://azure.archive.ubuntu.com/ubuntu jammy-backports/multiverse amd64 c-n-f Metadata [116 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 84% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:30 http://azure.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages [693 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B] [30 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:31 http://azure.archive.ubuntu.com/ubuntu jammy-security/main Translation-en [143 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B] [31 Translat
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:32 http://azure.archive.ubuntu.com/ubuntu jammy-security/main amd64 c-n-f Metadata [9016 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B] [32 Commands
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:33 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [645 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 86% [5 Packages store 0 B] [33 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 88% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:34 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted Translation-en [100 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 88% [5 Packages store 0 B] [34 Translat
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 89% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:35 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted amd64 c-n-f Metadata [588 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 89% [5 Packages store 0 B] [35 Commands
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 89% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:36 http://azure.archive.ubuntu.com/ubuntu jammy-security/universe amd64 Packages [714 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 89% [5 Packages store 0 B] [36 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:37 http://azure.archive.ubuntu.com/ubuntu jammy-security/universe Translation-en [118 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [37 Translat
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:38 http://azure.archive.ubuntu.com/ubuntu jammy-security/universe amd64 c-n-f Metadata [14.1 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [38 Commands
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:39 http://azure.archive.ubuntu.com/ubuntu jammy-security/multiverse amd64 Packages [19.4 kB]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [39 Packages
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:40 http://azure.archive.ubuntu.com/ubuntu jammy-security/multiverse Translation-en [4068 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [40 Translat
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Get:41 http://azure.archive.ubuntu.com/ubuntu jammy-security/multiverse amd64 c-n-f Metadata [228 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B] [41 Commands
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [5 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [6 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 91% [6 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [7 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [8 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [9 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 92% [10 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [11 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [12 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [13 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 93% [14 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [15 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [16 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [17 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 94% [18 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [19 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [20 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [21 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [22 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 95% [23 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [24 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [25 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [26 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 96% [27 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [28 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [29 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [30 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 97% [31 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [32 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [33 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [34 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 98% [35 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [36 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec):
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [37 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [38 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 99% [39 Packages store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [40 Translation-en store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [41 Commands-amd64 store 0 B]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 100% [Working]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Fetched 26.3 MB in 4s (5876 kB/s)
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [1m0s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 4%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 4%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 6%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 6%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 7%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 7%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 7%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 7%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 71%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 71%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 71%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 71%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 72%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 72%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 75%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 75%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 77%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 77%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 80%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 80%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 81%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 81%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 85%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 85%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 86%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 87%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 89%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 89%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 91%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 91%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 94%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 94%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 95%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 95%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 98%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 98%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 99%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 21 packages can be upgraded. Run 'apt list --upgradable' to see them.
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... 100%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading package lists... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... 50%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Building dependency tree... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... 0%
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Reading state information... Done
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): python3 is already the newest version (3.10.6-1~22.04).
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): python3 set to manually installed.
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): 0 upgraded, 0 newly installed, 0 to remove and 21 not upgraded.
azurerm_linux_virtual_machine.my_terraform_vm (remote-exec): Done!
azurerm_linux_virtual_machine.my_terraform_vm: Provisioning with 'local-exec'...
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): Executing: ["/bin/sh" "-c" "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u azureuser -i '20.127.1.163,' --private-key ./id_rsa -e 'pub_key=./id_rsa.pub' apache-install.yml"]

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): PLAY [apache-install] **********************************************************

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): TASK [Gathering Facts] *********************************************************
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [1m10s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): ok: [20.127.1.163]

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): TASK [Add the user 'stuart' and add it to 'sudo'] ******************************
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): changed: [20.127.1.163]

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): TASK [Add SSH key to 'stuart'] *************************************************
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): changed: [20.127.1.163]

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): TASK [Wait for apt to unlock] **************************************************
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): changed: [20.127.1.163]

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): TASK [Install apache2] *********************************************************
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [1m20s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [1m30s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm: Still creating... [1m40s elapsed]
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): changed: [20.127.1.163]

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): TASK [Enable mod_rewrite] ******************************************************
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): changed: [20.127.1.163]

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): RUNNING HANDLER [Restart apache2] **********************************************
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): changed: [20.127.1.163]

azurerm_linux_virtual_machine.my_terraform_vm (local-exec): PLAY RECAP *********************************************************************
azurerm_linux_virtual_machine.my_terraform_vm (local-exec): 20.127.1.163               : ok=7    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

azurerm_linux_virtual_machine.my_terraform_vm: Creation complete after 1m47s [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Compute/virtualMachines/myVM]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

public_ip_address = "20.127.1.163"
resource_group_name = "idj-east-rg"
tls_private_key = <sensitive>

Let’s look at the files (which I put into Github here).

Apache-install.yml

- become: yes
  hosts: all
  name: apache-install
  tasks:
    - name: Add the user 'stuart' and add it to 'sudo'
      user:
        name: stuart
        group: sudo
        
    - name: Add SSH key to 'stuart'
      authorized_key:
        user: stuart
        state: present
        key: "{{ lookup('file', pub_key) }}"
        
    - name: Wait for apt to unlock
      become: yes
      shell:  while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 5; done;
      
    - name: Install apache2
      apt:
        name: apache2
        update_cache: yes
        state: latest
      
    - name: Enable mod_rewrite
      apache2_module:
        name: rewrite 
        state: present
      notify:
        - Restart apache2

  handlers:
    - name: Restart apache2
      service:
        name: apache2
        state: restarted

The Terraform needed to be adjusted to write the Private and Pub keys to files

# Create a resource group
resource "azurerm_resource_group" "rg" {
  name     = "idj-east-rg"
  location = "East US"
}

# Create a virtual network within the resource group
resource "azurerm_virtual_network" "examplevnet" {
  name                = "example-network"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  address_space       = ["10.0.0.0/16"]
}

# Create subnet
resource "azurerm_subnet" "my_terraform_subnet" {
  name                 = "mySubnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.examplevnet.name
  address_prefixes     = ["10.0.1.0/24"]
}

# Create public IPs
resource "azurerm_public_ip" "my_terraform_public_ip" {
  name                = "myPublicIP"
  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" "my_terraform_nsg" {
  name                = "myNetworkSecurityGroup"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  security_rule {
    name                       = "SSH"
    priority                   = 1001
    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" "my_terraform_nic" {
  name                = "myNIC"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  ip_configuration {
    name                          = "my_nic_configuration"
    subnet_id                     = azurerm_subnet.my_terraform_subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.my_terraform_public_ip.id
  }
}

# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
  network_interface_id      = azurerm_network_interface.my_terraform_nic.id
  network_security_group_id = azurerm_network_security_group.my_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" "my_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" "example_ssh" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "local_file" "idrsa" {
  filename = "./id_rsa"
  file_permission = "0600"
  content  = <<-EOT
    ${tls_private_key.example_ssh.private_key_pem}
  EOT
}

resource "local_file" "idrsapub" {
  filename = "./id_rsa.pub"
  file_permission = "0633"
  content  = <<-EOT
    ${tls_private_key.example_ssh.public_key_openssh}
  EOT
}

# Create virtual machine

resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
  name                  = "myVM"
  location              = azurerm_resource_group.rg.location
  resource_group_name   = azurerm_resource_group.rg.name
  network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
  size                  = "Standard_DS1_v2"

  os_disk {
    name                 = "myOsDisk"
    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                   = "myvm"
  admin_username                  = "azureuser"
  disable_password_authentication = true

  admin_ssh_key {
    username   = "azureuser"
    public_key = tls_private_key.example_ssh.public_key_openssh
  }

  boot_diagnostics {
    storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint
  }

  provisioner "remote-exec" {
    inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"]

    connection {
      host        = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address
      type        = "ssh"
      user        = "azureuser"
      private_key = tls_private_key.example_ssh.private_key_pem
    }
  }

  provisioner "local-exec" {
    command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u azureuser -i '${azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address},' --private-key ${local_file.idrsa.filename} -e 'pub_key=${local_file.idrsapub.filename}' apache-install.yml"
    
  }
}

And we can login and check the host installed

builder@DESKTOP-72D2D9T:~/Workspaces/tfAnsibleAzure$ terraform output -raw tls_private_key > id_rsa
builder@DESKTOP-72D2D9T:~/Workspaces/tfAnsibleAzure$ chmod 600 ./id_rsa
builder@DESKTOP-72D2D9T:~/Workspaces/tfAnsibleAzure$ ssh -i id_rsa azureuser@`terraform output -raw public_ip_address`
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-1034-azure x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun Mar 26 22:08:09 UTC 2023

  System load:  0.0               Processes:             102
  Usage of /:   5.7% of 28.89GB   Users logged in:       0
  Memory usage: 9%                IPv4 address for eth0: 10.0.1.4
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

21 updates can be applied immediately.
13 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


Last login: Sun Mar 26 21:55:05 2023 from 73.242.50.46
azureuser@myvm:~$ which apache2
/usr/sbin/apache2

And I can see it running

azureuser@myvm:~$ sudo /etc/init.d/apache2 status
● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2023-03-26 21:55:05 UTC; 13min ago
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 3675 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
   Main PID: 3679 (apache2)
      Tasks: 55 (limit: 4095)
     Memory: 8.8M
        CPU: 62ms
     CGroup: /system.slice/apache2.service
             ├─3679 /usr/sbin/apache2 -k start
             ├─3680 /usr/sbin/apache2 -k start
             └─3681 /usr/sbin/apache2 -k start

Mar 26 21:55:05 myvm systemd[1]: apache2.service: Deactivated successfully.
Mar 26 21:55:05 myvm systemd[1]: Stopped The Apache HTTP Server.
Mar 26 21:55:05 myvm systemd[1]: Starting The Apache HTTP Server...
Mar 26 21:55:05 myvm systemd[1]: Started The Apache HTTP Server.

And we can see the Apache2 is running

azureuser@myvm:~$ wget http://localhost
--2023-03-26 22:09:17--  http://localhost/
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10671 (10K) [text/html]
Saving to: ‘index.html’

index.html                    100%[=================================================>]  10.42K  --.-KB/s    in 0s

2023-03-26 22:09:17 (318 MB/s) - ‘index.html’ saved [10671/10671]

azureuser@myvm:~$ cat index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <!--
    Modified from the Debian original for Ubuntu
    Last updated: 2022-03-22
    See: https://launchpad.net/bugs/1966004
  -->
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Apache2 Ubuntu Default Page: It works</title>
    <style type="text/css" media="screen">
  * {
    margin: 0px 0px 0px 0px;
    padding: 0px 0px 0px 0px;
  }

  body, html {
    padding: 3px 3px 3px 3px;

    background-color: #D8DBE2;

    font-family: Ubuntu, Verdana, sans-serif;
    font-size: 11pt;
    text-align: center;
  }

  div.main_page {
    position: relative;
    display: table;

    width: 800px;

    margin-bottom: 3px;
    margin-left: auto;
    margin-right: auto;
    padding: 0px 0px 0px 0px;

    border-width: 2px;
    border-color: #212738;
    border-style: solid;

    background-color: #FFFFFF;

    text-align: center;
  }

  div.page_header {
    height: 180px;
    width: 100%;

    background-color: #F5F6F7;
  }

  div.page_header span {
    margin: 15px 0px 0px 50px;

    font-size: 180%;
    font-weight: bold;
  }

  div.page_header img {
    margin: 3px 0px 0px 40px;

    border: 0px 0px 0px;
  }

  div.banner {
    padding: 9px 6px 9px 6px;
    background-color: #E9510E;
    color: #FFFFFF;
    font-weight: bold;
    font-size: 112%;
    text-align: center;
    position: absolute;
    left: 40%;
    bottom: 30px;
    width: 20%;
  }

  div.table_of_contents {
    clear: left;

    min-width: 200px;

    margin: 3px 3px 3px 3px;

    background-color: #FFFFFF;

    text-align: left;
  }

  div.table_of_contents_item {
    clear: left;

    width: 100%;

    margin: 4px 0px 0px 0px;

    background-color: #FFFFFF;

    color: #000000;
    text-align: left;
  }

  div.table_of_contents_item a {
    margin: 6px 0px 0px 6px;
  }

  div.content_section {
    margin: 3px 3px 3px 3px;

    background-color: #FFFFFF;

    text-align: left;
  }

  div.content_section_text {
    padding: 4px 8px 4px 8px;

    color: #000000;
    font-size: 100%;
  }

  div.content_section_text pre {
    margin: 8px 0px 8px 0px;
    padding: 8px 8px 8px 8px;

    border-width: 1px;
    border-style: dotted;
    border-color: #000000;

    background-color: #F5F6F7;

    font-style: italic;
  }

  div.content_section_text p {
    margin-bottom: 6px;
  }

  div.content_section_text ul, div.content_section_text li {
    padding: 4px 8px 4px 16px;
  }

  div.section_header {
    padding: 3px 6px 3px 6px;

    background-color: #8E9CB2;

    color: #FFFFFF;
    font-weight: bold;
    font-size: 112%;
    text-align: center;
  }

  div.section_header_grey {
    background-color: #9F9386;
  }

  .floating_element {
    position: relative;
    float: left;
  }

  div.table_of_contents_item a,
  div.content_section_text a {
    text-decoration: none;
    font-weight: bold;
  }

  div.table_of_contents_item a:link,
  div.table_of_contents_item a:visited,
  div.table_of_contents_item a:active {
    color: #000000;
  }

  div.table_of_contents_item a:hover {
    background-color: #000000;

    color: #FFFFFF;
  }

  div.content_section_text a:link,
  div.content_section_text a:visited,
   div.content_section_text a:active {
    background-color: #DCDFE6;

    color: #000000;
  }

  div.content_section_text a:hover {
    background-color: #000000;

    color: #DCDFE6;
  }

  div.validator {
  }
    </style>
  </head>
  <body>
    <div class="main_page">
      <div class="page_header floating_element">
        <img src="icons/ubuntu-logo.png" alt="Ubuntu Logo"
             style="width:184px;height:146px;" class="floating_element" />
        <div>
          <span style="margin-top: 1.5em;" class="floating_element">
            Apache2 Default Page
          </span>
        </div>
        <div class="banner">
          <div id="about"></div>
          It works!
        </div>

      </div>
      <div class="content_section floating_element">
        <div class="content_section_text">
          <p>
                This is the default welcome page used to test the correct
                operation of the Apache2 server after installation on Ubuntu systems.
                It is based on the equivalent page on Debian, from which the Ubuntu Apache
                packaging is derived.
                If you can read this page, it means that the Apache HTTP server installed at
                this site is working properly. You should <b>replace this file</b> (located at
                <tt>/var/www/html/index.html</tt>) before continuing to operate your HTTP server.
          </p>

          <p>
                If you are a normal user of this web site and don't know what this page is
                about, this probably means that the site is currently unavailable due to
                maintenance.
                If the problem persists, please contact the site's administrator.
          </p>

        </div>
        <div class="section_header">
          <div id="changes"></div>
                Configuration Overview
        </div>
        <div class="content_section_text">
          <p>
                Ubuntu's Apache2 default configuration is different from the
                upstream default configuration, and split into several files optimized for
                interaction with Ubuntu tools. The configuration system is
                <b>fully documented in
                /usr/share/doc/apache2/README.Debian.gz</b>. Refer to this for the full
                documentation. Documentation for the web server itself can be
                found by accessing the <a href="/manual">manual</a> if the <tt>apache2-doc</tt>
                package was installed on this server.
          </p>
          <p>
                The configuration layout for an Apache2 web server installation on Ubuntu systems is as follows:
          </p>
          <pre>
/etc/apache2/
|-- apache2.conf
|       `--  ports.conf
|-- mods-enabled
|       |-- *.load
|       `-- *.conf
|-- conf-enabled
|       `-- *.conf
|-- sites-enabled
|       `-- *.conf
          </pre>
          <ul>
                        <li>
                           <tt>apache2.conf</tt> is the main configuration
                           file. It puts the pieces together by including all remaining configuration
                           files when starting up the web server.
                        </li>

                        <li>
                           <tt>ports.conf</tt> is always included from the
                           main configuration file. It is used to determine the listening ports for
                           incoming connections, and this file can be customized anytime.
                        </li>

                        <li>
                           Configuration files in the <tt>mods-enabled/</tt>,
                           <tt>conf-enabled/</tt> and <tt>sites-enabled/</tt> directories contain
                           particular configuration snippets which manage modules, global configuration
                           fragments, or virtual host configurations, respectively.
                        </li>

                        <li>
                           They are activated by symlinking available
                           configuration files from their respective
                           *-available/ counterparts. These should be managed
                           by using our helpers
                           <tt>
                                a2enmod,
                                a2dismod,
                           </tt>
                           <tt>
                                a2ensite,
                                a2dissite,
                            </tt>
                                and
                           <tt>
                                a2enconf,
                                a2disconf
                           </tt>. See their respective man pages for detailed information.
                        </li>

                        <li>
                           The binary is called apache2 and is managed using systemd, so to
                           start/stop the service use <tt>systemctl start apache2</tt> and
                           <tt>systemctl stop apache2</tt>, and use <tt>systemctl status apache2</tt>
                           and <tt>journalctl -u apache2</tt> to check status.  <tt>system</tt>
                           and <tt>apache2ctl</tt> can also be used for service management if
                           desired.
                           <b>Calling <tt>/usr/bin/apache2</tt> directly will not work</b> with the
                           default configuration.
                        </li>
          </ul>
        </div>

        <div class="section_header">
            <div id="docroot"></div>
                Document Roots
        </div>

        <div class="content_section_text">
            <p>
                By default, Ubuntu does not allow access through the web browser to
                <em>any</em> file outside of those located in <tt>/var/www</tt>,
                <a href="http://httpd.apache.org/docs/2.4/mod/mod_userdir.html" rel="nofollow">public_html</a>
                directories (when enabled) and <tt>/usr/share</tt> (for web
                applications). If your site is using a web document root
                located elsewhere (such as in <tt>/srv</tt>) you may need to whitelist your
                document root directory in <tt>/etc/apache2/apache2.conf</tt>.
            </p>
            <p>
                The default Ubuntu document root is <tt>/var/www/html</tt>. You
                can make your own virtual hosts under /var/www.
            </p>
        </div>

        <div class="section_header">
          <div id="bugs"></div>
                Reporting Problems
        </div>
        <div class="content_section_text">
          <p>
                Please use the <tt>ubuntu-bug</tt> tool to report bugs in the
                Apache2 package with Ubuntu. However, check <a
                href="https://bugs.launchpad.net/ubuntu/+source/apache2"
                rel="nofollow">existing bug reports</a> before reporting a new bug.
          </p>
          <p>
                Please report bugs specific to modules (such as PHP and others)
                to their respective packages, not to the web server itself.
          </p>
        </div>

      </div>
    </div>
    <div class="validator">
    </div>
  </body>
</html>

Cleanup

We could remove the resource group. That would remove everything.

However, we can use Terraform to remove stuff with delete.

builder@DESKTOP-72D2D9T:~/Workspaces/tfAnsibleAzure$ terraform destroy
tls_private_key.example_ssh: Refreshing state... [id=0e0824a94233b37283362ab9dfc50edde05231c3]
local_file.idrsa: Refreshing state... [id=6e94572c465335f793b2cf9090a31e740d140685]
local_file.idrsapub: Refreshing state... [id=b338a4a88b429fe02532cb17077592c28190188a]
azurerm_resource_group.rg: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg]
random_id.random_id: Refreshing state... [id=9-XSBWLaVIk]
azurerm_virtual_network.examplevnet: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network]
azurerm_public_ip.my_terraform_public_ip: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/publicIPAddresses/myPublicIP]
azurerm_network_security_group.my_terraform_nsg: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_storage_account.my_storage_account: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Storage/storageAccounts/diagf7e5d20562da5489]
azurerm_subnet.my_terraform_subnet: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network/subnets/mySubnet]
azurerm_network_interface.my_terraform_nic: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC]
azurerm_network_interface_security_group_association.example: Refreshing state... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC|/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  - destroy

Terraform will perform the following actions:

  # azurerm_network_interface.my_terraform_nic will be destroyed
  - resource "azurerm_network_interface" "my_terraform_nic" {
      - applied_dns_servers           = [] -> null
      - dns_servers                   = [] -> null
      - enable_accelerated_networking = false -> null
      - enable_ip_forwarding          = false -> null
      - id                            = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC" -> null
      - location                      = "eastus" -> null
      - mac_address                   = "00-22-48-27-1A-07" -> null
      - name                          = "myNIC" -> null
      - private_ip_address            = "10.0.1.4" -> null
      - private_ip_addresses          = [
          - "10.0.1.4",
        ] -> null
      - resource_group_name           = "idj-east-rg" -> null
      - tags                          = {} -> null

      - ip_configuration {
          - name                          = "my_nic_configuration" -> null
          - primary                       = true -> null
          - private_ip_address            = "10.0.1.4" -> null
          - private_ip_address_allocation = "Dynamic" -> null
          - private_ip_address_version    = "IPv4" -> null
          - public_ip_address_id          = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/publicIPAddresses/myPublicIP" -> null
          - subnet_id                     = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network/subnets/mySubnet" -> null
        }
    }

  # azurerm_network_interface_security_group_association.example will be destroyed
  - resource "azurerm_network_interface_security_group_association" "example" {
      - id                        = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC|/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup" -> null
      - network_interface_id      = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC" -> null
      - network_security_group_id = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup" -> null
    }

  # azurerm_network_security_group.my_terraform_nsg will be destroyed
  - resource "azurerm_network_security_group" "my_terraform_nsg" {
      - id                  = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup" -> null
      - location            = "eastus" -> null
      - name                = "myNetworkSecurityGroup" -> null
      - resource_group_name = "idj-east-rg" -> null
      - security_rule       = [
          - {
              - access                                     = "Allow"
              - description                                = ""
              - destination_address_prefix                 = "*"
              - destination_address_prefixes               = []
              - destination_application_security_group_ids = []
              - destination_port_range                     = "22"
              - destination_port_ranges                    = []
              - direction                                  = "Inbound"
              - name                                       = "SSH"
              - priority                                   = 1001
              - protocol                                   = "Tcp"
              - source_address_prefix                      = "*"
              - source_address_prefixes                    = []
              - source_application_security_group_ids      = []
              - source_port_range                          = "*"
              - source_port_ranges                         = []
            },
        ] -> null
      - tags                = {} -> null
    }

  # azurerm_public_ip.my_terraform_public_ip will be destroyed
  - resource "azurerm_public_ip" "my_terraform_public_ip" {
      - allocation_method       = "Dynamic" -> null
      - ddos_protection_mode    = "VirtualNetworkInherited" -> null
      - id                      = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/publicIPAddresses/myPublicIP" -> null
      - idle_timeout_in_minutes = 4 -> null
      - ip_tags                 = {} -> null
      - ip_version              = "IPv4" -> null
      - location                = "eastus" -> null
      - name                    = "myPublicIP" -> null
      - resource_group_name     = "idj-east-rg" -> null
      - sku                     = "Basic" -> null
      - sku_tier                = "Regional" -> null
      - tags                    = {} -> null
      - zones                   = [] -> null
    }

  # azurerm_resource_group.rg will be destroyed
  - resource "azurerm_resource_group" "rg" {
      - id       = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg" -> null
      - location = "eastus" -> null
      - name     = "idj-east-rg" -> null
      - tags     = {} -> null
    }

  # azurerm_storage_account.my_storage_account will be destroyed
  - resource "azurerm_storage_account" "my_storage_account" {
      - access_tier                       = "Hot" -> null
      - account_kind                      = "StorageV2" -> null
      - account_replication_type          = "LRS" -> null
      - account_tier                      = "Standard" -> null
      - allow_nested_items_to_be_public   = true -> null
      - cross_tenant_replication_enabled  = true -> null
      - default_to_oauth_authentication   = false -> null
      - enable_https_traffic_only         = true -> null
      - id                                = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Storage/storageAccounts/diagf7e5d20562da5489" -> null
      - infrastructure_encryption_enabled = false -> null
      - is_hns_enabled                    = false -> null
      - location                          = "eastus" -> null
      - min_tls_version                   = "TLS1_2" -> null
      - name                              = "diagf7e5d20562da5489" -> null
      - nfsv3_enabled                     = false -> null
      - primary_access_key                = (sensitive value) -> null
      - primary_blob_connection_string    = (sensitive value) -> null
      - primary_blob_endpoint             = "https://diagf7e5d20562da5489.blob.core.windows.net/" -> null
      - primary_blob_host                 = "diagf7e5d20562da5489.blob.core.windows.net" -> null
      - primary_connection_string         = (sensitive value) -> null
      - primary_dfs_endpoint              = "https://diagf7e5d20562da5489.dfs.core.windows.net/" -> null
      - primary_dfs_host                  = "diagf7e5d20562da5489.dfs.core.windows.net" -> null
      - primary_file_endpoint             = "https://diagf7e5d20562da5489.file.core.windows.net/" -> null
      - primary_file_host                 = "diagf7e5d20562da5489.file.core.windows.net" -> null
      - primary_location                  = "eastus" -> null
      - primary_queue_endpoint            = "https://diagf7e5d20562da5489.queue.core.windows.net/" -> null
      - primary_queue_host                = "diagf7e5d20562da5489.queue.core.windows.net" -> null
      - primary_table_endpoint            = "https://diagf7e5d20562da5489.table.core.windows.net/" -> null
      - primary_table_host                = "diagf7e5d20562da5489.table.core.windows.net" -> null
      - primary_web_endpoint              = "https://diagf7e5d20562da5489.z13.web.core.windows.net/" -> null
      - primary_web_host                  = "diagf7e5d20562da5489.z13.web.core.windows.net" -> null
      - public_network_access_enabled     = true -> null
      - queue_encryption_key_type         = "Service" -> null
      - resource_group_name               = "idj-east-rg" -> null
      - secondary_access_key              = (sensitive value) -> null
      - secondary_connection_string       = (sensitive value) -> null
      - sftp_enabled                      = false -> null
      - shared_access_key_enabled         = true -> null
      - table_encryption_key_type         = "Service" -> null
      - tags                              = {} -> null

      - blob_properties {
          - change_feed_enabled           = false -> null
          - change_feed_retention_in_days = 0 -> null
          - last_access_time_enabled      = false -> null
          - versioning_enabled            = false -> null
        }

      - network_rules {
          - bypass                     = [
              - "AzureServices",
            ] -> null
          - default_action             = "Allow" -> null
          - ip_rules                   = [] -> null
          - virtual_network_subnet_ids = [] -> null
        }

      - queue_properties {
          - hour_metrics {
              - enabled               = true -> null
              - include_apis          = true -> null
              - retention_policy_days = 7 -> null
              - version               = "1.0" -> null
            }
          - logging {
              - delete                = false -> null
              - read                  = false -> null
              - retention_policy_days = 0 -> null
              - version               = "1.0" -> null
              - write                 = false -> null
            }
          - minute_metrics {
              - enabled               = false -> null
              - include_apis          = false -> null
              - retention_policy_days = 0 -> null
              - version               = "1.0" -> null
            }
        }

      - share_properties {
          - retention_policy {
              - days = 7 -> null
            }
        }
    }

  # azurerm_subnet.my_terraform_subnet will be destroyed
  - resource "azurerm_subnet" "my_terraform_subnet" {
      - address_prefixes                               = [
          - "10.0.1.0/24",
        ] -> null
      - enforce_private_link_endpoint_network_policies = false -> null
      - enforce_private_link_service_network_policies  = false -> null
      - id                                             = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network/subnets/mySubnet" -> null
      - name                                           = "mySubnet" -> null
      - private_endpoint_network_policies_enabled      = true -> null
      - private_link_service_network_policies_enabled  = true -> null
      - resource_group_name                            = "idj-east-rg" -> null
      - service_endpoint_policy_ids                    = [] -> null
      - service_endpoints                              = [] -> null
      - virtual_network_name                           = "example-network" -> null
    }

  # azurerm_virtual_network.examplevnet will be destroyed
  - resource "azurerm_virtual_network" "examplevnet" {
      - address_space           = [
          - "10.0.0.0/16",
        ] -> null
      - dns_servers             = [] -> null
      - flow_timeout_in_minutes = 0 -> null
      - guid                    = "094ef352-f841-45b5-84dc-e62fdb813980" -> null
      - id                      = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network" -> null
      - location                = "eastus" -> null
      - name                    = "example-network" -> null
      - resource_group_name     = "idj-east-rg" -> null
      - subnet                  = [
          - {
              - address_prefix = "10.0.1.0/24"
              - id             = "/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network/subnets/mySubnet"
              - name           = "mySubnet"
              - security_group = ""
            },
        ] -> null
      - tags                    = {} -> null
    }

  # local_file.idrsa will be destroyed
  - resource "local_file" "idrsa" {
      - content              = (sensitive value) -> null
      - content_base64sha256 = "E1WG7Q5aIwVW0txyt95PIwXQasjDA/xK1njpkYfwhL0=" -> null
      - content_base64sha512 = "zwFJGcW0gg0FcULRMr4cJTCNg0a1rGFqRB/GOb0EBY5Jq/CGv+Hd3wM4Qrz0XrbDe+sdSkz54WjM3L/ZRfLshA==" -> null
      - content_md5          = "b245a335031c702ef362b07d2e1ed2ff" -> null
      - content_sha1         = "6e94572c465335f793b2cf9090a31e740d140685" -> null
      - content_sha256       = "135586ed0e5a230556d2dc72b7de4f2305d06ac8c303fc4ad678e99187f084bd" -> null
      - content_sha512       = "cf014919c5b4820d057142d132be1c25308d8346b5ac616a441fc639bd04058e49abf086bfe1dddf033842bcf45eb6c37beb1d4a4cf9e168ccdcbfd945f2ec84" -> null
      - directory_permission = "0777" -> null
      - file_permission      = "0600" -> null
      - filename             = "./id_rsa" -> null
      - id                   = "6e94572c465335f793b2cf9090a31e740d140685" -> null
    }

  # local_file.idrsapub will be destroyed
  - resource "local_file" "idrsapub" {
      - content              = <<-EOT
            ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCgLUmizuehl+PE4j3jBBRqDkqOf0fCIbM1pobvBiXPfjDLXgaCC4h6jasw0KF8kNaZqJKxrGFTMma2c7nROKGqBTvLcxjyud2+Apx3NjcvH9q9ozXlwu3elrI0pzFB2rpH7b86iMHVuuhdMw4Xzv3OJt9PCytAmZhIRhdWp8niJMYpm+IM/PXLN2ksG6AGSw3QAROLeTfrmmaiHgj6hoNv9lKdWBIeYw4U2odvZG5QsQNaYzDb+UWh+b0un118Be6kTk1/QnSglfZ42HBChVtU+ZBSHFFeWDIK+ELi+7JfwqC2ckylmQRxfRV7VNnYe225LvtEqaJr+I2vfXNhnfPeJjoxcCpO0+upx5NJmqXYdqqINw0F+O2jnv6R62NFMLoPF+dUOe6+uh04gIA2AB8jyGHKgk/a+Ukqmfmo+6+Z9tB0mVMPKrXh646N+DjJrttFZuU3F33VYUGXI8zBvsp8PrwKWFIS27loV8Cmn7H6698+Hu19KzPEZ8J5MYcQZWGyphxVg8a/k9mP+uqSvOebTT652im0E6Vxmvi/s5rC1jkRaKPAYJcjeMWO9vPN7DUx+YlUNZNfF/yncMy+ZotWpr1TeGA+LVDM7gGdusB892vAJppucYos+D3NJfyq1yun6YVs4J8Rij0c2eQg89/Dq9ZliL1F8K28b2/1sDcnWw==
        EOT -> null
      - content_base64sha256 = "0q2XO39hH53zvg+KBv+6+ihjsBHL7byzqy8ruGafADc=" -> null
      - content_base64sha512 = "Ni+6pQvKaad6uBYhrNj76Z53Lip+nJinyPktHr8Fol0EdSKL6gpKvOe3Zw+rNYgG3ffZJ2I2kdGuoY0mRlWdBQ==" -> null
      - content_md5          = "f54a066bc0f6dd8ff59b6c71cf7cda8c" -> null
      - content_sha1         = "b338a4a88b429fe02532cb17077592c28190188a" -> null
      - content_sha256       = "d2ad973b7f611f9df3be0f8a06ffbafa2863b011cbedbcb3ab2f2bb8669f0037" -> null
      - content_sha512       = "362fbaa50bca69a77ab81621acd8fbe99e772e2a7e9c98a7c8f92d1ebf05a25d0475228bea0a4abce7b7670fab358806ddf7d927623691d1aea18d2646559d05" -> null
      - directory_permission = "0777" -> null
      - file_permission      = "0633" -> null
      - filename             = "./id_rsa.pub" -> null
      - id                   = "b338a4a88b429fe02532cb17077592c28190188a" -> null
    }

  # random_id.random_id will be destroyed
  - resource "random_id" "random_id" {
      - b64_std     = "9+XSBWLaVIk=" -> null
      - b64_url     = "9-XSBWLaVIk" -> null
      - byte_length = 8 -> null
      - dec         = "17862914417610085513" -> null
      - hex         = "f7e5d20562da5489" -> null
      - id          = "9-XSBWLaVIk" -> null
      - keepers     = {
          - "resource_group" = "idj-east-rg"
        } -> null
    }

  # tls_private_key.example_ssh will be destroyed
  - resource "tls_private_key" "example_ssh" {
      - algorithm                     = "RSA" -> null
      - ecdsa_curve                   = "P224" -> null
      - id                            = "0e0824a94233b37283362ab9dfc50edde05231c3" -> null
      - private_key_openssh           = (sensitive value) -> null
      - private_key_pem               = (sensitive value) -> null
      - private_key_pem_pkcs8         = (sensitive value) -> null
      - public_key_fingerprint_md5    = "66:65:31:b4:f2:9d:3e:db:a7:bc:7b:31:a2:97:9d:fa" -> null
      - public_key_fingerprint_sha256 = "SHA256:OLSGtSJec6nrilnOnUFiAPwb+SGWEzljCT3nlz4+jEI" -> null
      - public_key_openssh            = <<-EOT
            ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCgLUmizuehl+PE4j3jBBRqDkqOf0fCIbM1pobvBiXPfjDLXgaCC4h6jasw0KF8kNaZqJKxrGFTMma2c7nROKGqBTvLcxjyud2+Apx3NjcvH9q9ozXlwu3elrI0pzFB2rpH7b86iMHVuuhdMw4Xzv3OJt9PCytAmZhIRhdWp8niJMYpm+IM/PXLN2ksG6AGSw3QAROLeTfrmmaiHgj6hoNv9lKdWBIeYw4U2odvZG5QsQNaYzDb+UWh+b0un118Be6kTk1/QnSglfZ42HBChVtU+ZBSHFFeWDIK+ELi+7JfwqC2ckylmQRxfRV7VNnYe225LvtEqaJr+I2vfXNhnfPeJjoxcCpO0+upx5NJmqXYdqqINw0F+O2jnv6R62NFMLoPF+dUOe6+uh04gIA2AB8jyGHKgk/a+Ukqmfmo+6+Z9tB0mVMPKrXh646N+DjJrttFZuU3F33VYUGXI8zBvsp8PrwKWFIS27loV8Cmn7H6698+Hu19KzPEZ8J5MYcQZWGyphxVg8a/k9mP+uqSvOebTT652im0E6Vxmvi/s5rC1jkRaKPAYJcjeMWO9vPN7DUx+YlUNZNfF/yncMy+ZotWpr1TeGA+LVDM7gGdusB892vAJppucYos+D3NJfyq1yun6YVs4J8Rij0c2eQg89/Dq9ZliL1F8K28b2/1sDcnWw==
        EOT -> null
      - public_key_pem                = <<-EOT
            -----BEGIN PUBLIC KEY-----
            MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoC1Jos7noZfjxOI94wQU
            ag5Kjn9HwiGzNaaG7wYlz34wy14GgguIeo2rMNChfJDWmaiSsaxhUzJmtnO50Tih
            qgU7y3MY8rndvgKcdzY3Lx/avaM15cLt3payNKcxQdq6R+2/OojB1broXTMOF879
            zibfTwsrQJmYSEYXVqfJ4iTGKZviDPz1yzdpLBugBksN0AETi3k365pmoh4I+oaD
            b/ZSnVgSHmMOFNqHb2RuULEDWmMw2/lFofm9Lp9dfAXupE5Nf0J0oJX2eNhwQoVb
            VPmQUhxRXlgyCvhC4vuyX8KgtnJMpZkEcX0Ve1TZ2HttuS77RKmia/iNr31zYZ3z
            3iY6MXAqTtPrqceTSZql2HaqiDcNBfjto57+ketjRTC6DxfnVDnuvrodOICANgAf
            I8hhyoJP2vlJKpn5qPuvmfbQdJlTDyq14euOjfg4ya7bRWblNxd91WFBlyPMwb7K
            fD68ClhSEtu5aFfApp+x+uvfPh7tfSszxGfCeTGHEGVhsqYcVYPGv5PZj/rqkrzn
            m00+udoptBOlcZr4v7OawtY5EWijwGCXI3jFjvbzzew1MfmJVDWTXxf8p3DMvmaL
            Vqa9U3hgPi1QzO4BnbrAfPdrwCaabnGKLPg9zSX8qtcrp+mFbOCfEYo9HNnkIPPf
            w6vWZYi9RfCtvG9v9bA3J1sCAwEAAQ==
            -----END PUBLIC KEY-----
        EOT -> null
      - rsa_bits                      = 4096 -> null
    }

Plan: 0 to add, 0 to change, 12 to destroy.

Changes to Outputs:
  - resource_group_name = "idj-east-rg" -> null
  - tls_private_key     = (sensitive value) -> null

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

local_file.idrsapub: Destroying... [id=b338a4a88b429fe02532cb17077592c28190188a]
local_file.idrsa: Destroying... [id=6e94572c465335f793b2cf9090a31e740d140685]
local_file.idrsapub: Destruction complete after 0s
local_file.idrsa: Destruction complete after 0s
tls_private_key.example_ssh: Destroying... [id=0e0824a94233b37283362ab9dfc50edde05231c3]
tls_private_key.example_ssh: Destruction complete after 0s
azurerm_network_interface_security_group_association.example: Destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC|/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_storage_account.my_storage_account: Destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Storage/storageAccounts/diagf7e5d20562da5489]
azurerm_network_interface_security_group_association.example: Destruction complete after 2s
azurerm_network_interface.my_terraform_nic: Destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkInterfaces/myNIC]
azurerm_network_security_group.my_terraform_nsg: Destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_storage_account.my_storage_account: Destruction complete after 3s
random_id.random_id: Destroying... [id=9-XSBWLaVIk]
random_id.random_id: Destruction complete after 0s
azurerm_network_interface.my_terraform_nic: Destruction complete after 5s
azurerm_public_ip.my_terraform_public_ip: Destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/publicIPAddresses/myPublicIP]
azurerm_subnet.my_terraform_subnet: Destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network/subnets/mySubnet]
azurerm_network_security_group.my_terraform_nsg: Still destroying... [id=/subscriptions/d955c0ba-13dc-44cf-a29a-...kSecurityGroups/myNetworkSecurityGroup, 10s elapsed]
azurerm_network_security_group.my_terraform_nsg: Destruction complete after 11s
azurerm_public_ip.my_terraform_public_ip: Still destroying... [id=/subscriptions/d955c0ba-13dc-44cf-a29a-...t.Network/publicIPAddresses/myPublicIP, 10s elapsed]
azurerm_subnet.my_terraform_subnet: Still destroying... [id=/subscriptions/d955c0ba-13dc-44cf-a29a-...works/example-network/subnets/mySubnet, 10s elapsed]
azurerm_public_ip.my_terraform_public_ip: Destruction complete after 11s
azurerm_subnet.my_terraform_subnet: Destruction complete after 11s
azurerm_virtual_network.examplevnet: Destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg/providers/Microsoft.Network/virtualNetworks/example-network]
azurerm_virtual_network.examplevnet: Still destroying... [id=/subscriptions/d955c0ba-13dc-44cf-a29a-...etwork/virtualNetworks/example-network, 10s elapsed]
azurerm_virtual_network.examplevnet: Destruction complete after 11s
azurerm_resource_group.rg: Destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg]
azurerm_resource_group.rg: Still destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg, 10s elapsed]
azurerm_resource_group.rg: Still destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg, 20s elapsed]
azurerm_resource_group.rg: Still destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg, 30s elapsed]
azurerm_resource_group.rg: Still destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg, 40s elapsed]
azurerm_resource_group.rg: Still destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg, 50s elapsed]
azurerm_resource_group.rg: Still destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg, 1m0s elapsed]
azurerm_resource_group.rg: Still destroying... [id=/subscriptions/d955c0ba-asdf-asdf-asdf-asdfasdfb22d/resourceGroups/idj-east-rg, 1m10s elapsed]
azurerm_resource_group.rg: Destruction complete after 1m17s

Destroy complete! Resources: 12 destroyed.

Summary

Today we looked at using Terraform locally to build out some basic infrastructure in Azure. We then expanded that to use a “remote-exec” provisioner to add python. Lastly, we added a “local-exec” provisioner paired with locally install ansible to handle the installation of a basic Apache2 ansible playbook.

Next week we’ll expand to adding Secrets access via AKV. Then we will dynamically fetch a Github token and pull down Github hosted ansible playbooks to install.

Using Hashi Terraform and Ansible in this way provides a nice single scalable path to launching and using Ansible playbooks during Infrastructure standup.

Terraform Ansible Azure

Have something to add? Feedback? Try our new forums

Isaac Johnson

Isaac Johnson

Cloud Solutions Architect

Isaac is a CSA and DevOps engineer who focuses on cloud migrations and devops processes. He also is a dad to three wonderful daughters (hence the references to Princess King sprinkled throughout the blog).

Theme built by C.S. Rhymes