Differences

This shows you the differences between two versions of the page.

Link to this comparison view

azure_terraform_getting_started [2020/06/20 14:59] (current)
Douglas Quintiliano dos Santos created
Line 1: Line 1:
 +====== Azure Terraform Getting Started ======
 +
 +Hello guys, here I shall show you some examples of Azure configuration with Terraform, because there are a lot information out there and sometimes is kind of crazy a lot of them with a lot of kinds of configuration that there is no start point for a beginner that why I will try to show the basic until the advanced. I will try to write as much as possible in my free time. So let's get started with Azure and Terraform.
 +
 +My Terraform configuration if you want to reproduce the configurations below.
 +<sxh bash>
 +terraform --version                                                                          191ms  Sat Apr  4 12:22:01 2020
 +Terraform v0.12.24
 ++ provider.azurerm v1.44.0
 +</sxh>
 +===== Defining the Provider Azurerm =====
 +
 +When we start to work with Terraform and Azure we need to define the provider and there a lot of options we can use here, following the link about the provider documentation take a look: [[https://www.terraform.io/docs/providers/azurerm/index.html|Azure Provider]]
 +
 +As we can use the code showed below in a team or another kind of sharing I will approach the configuration via environment variables that I think is the most secure for the how to. If you don't have idea how to set up the SPN for your azure account you can take a look at the following link: [[http://devops.douglasqsantos.com.br/doku.php/configuring_azure_spn_for_terraform|Configuring Azure SPN for Terraform]]
 +
 +Now we need to configure the environment variables for our project.
 +
 +The Subscription ID which should be used. This can also be sourced from the ARM_SUBSCRIPTION_ID Environment Variable.
 +<sxh bash>
 +export ARM_SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-62f9d45b6957"
 +</sxh>
 +
 +The Client ID which should be used. This can also be sourced from the ARM_CLIENT_ID Environment Variable.
 +<sxh bash>
 +export ARM_CLIENT_ID="xxxxxxxx-xxxx-xxxx-xxxx-e684b975d113"
 +</sxh>
 +
 +The Client Secret which should be used. This can also be sourced from the ARM_CLIENT_SECRET Environment Variable.
 +<sxh bash>
 +export ARM_CLIENT_SECRET="8Z:s.?3pa@2zjuM4Y-JEoUdlj@w9SXfb"
 +</sxh>
 +
 +The Tenant ID which should be used. This can also be sourced from the ARM_TENANT_ID Environment Variable.
 +<sxh bash>
 +export ARM_TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-9c8a75bbff3e"
 +</sxh>
 +
 +===== Creating a Resource Group =====
 +
 +Now let's create our first resource group, try to make all the resources group by it, so if your configuration grows and you need to remove or change it, it'll be a lot easer than try to figure out what's going on.
 +
 +Let's create a directory to hold all the configuration about our project.
 +<sxh bash>
 +mkdir terraform-azure
 +</sxh>
 +
 +Now let's access it
 +<sxh bash>
 +cd terraform-azure
 +</sxh>
 +
 +Now let's create our first resource group
 +<sxh bash>
 +vim main.tf
 +# Provider
 +# https://www.terraform.io/docs/providers/azurerm/index.html
 +provider "azurerm" {
 +  # With Terraform 12 we need to stick with 1.27
 +  version         = "~> 1.27"
 +  # The Subscription ID which should be used. This can also be sourced from the ARM_SUBSCRIPTION_ID Environment Variable.
 +  # subscription_id = "${var.subscription_id}"
 +  # The Client ID which should be used. This can also be sourced from the ARM_CLIENT_ID Environment Variable.
 +  # client_id       = "${var.client_id}"
 +  # The Client Secret which should be used. This can also be sourced from the ARM_CLIENT_SECRET Environment Variable.
 +  # client_secret   = "${var.client_secret}"
 +  # The Tenant ID which should be used. This can also be sourced from the ARM_TENANT_ID Environment Variable.
 +  # tenant_id       = "${var.tenant_id}"
 +}
 +
 +# Manages a Resource Group.
 +# https://www.terraform.io/docs/providers/azurerm/r/resource_group.html
 +resource "azurerm_resource_group" "web_server_rg" {
 +  # The Name which should be used for this Resource Group. 
 +  name     = "web-rg"
 +  # The Azure Region where the Resource Group should exist.
 +  location = "westus2"
 +}
 +</sxh>
 +
 +Now we need to init the terraform
 +<sxh bash>
 +terraform init                                                                                  4089ms  Sat Apr  4 08:38:21 2020
 +
 +Initializing the backend...
 +
 +Initializing provider plugins...
 +- Checking for available provider plugins...
 +- Downloading plugin for provider "azurerm" (hashicorp/azurerm) 1.44.0...
 +
 +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.
 +</sxh>
 +
 +Now we can run the terraform plan to take a look what will happen if we apply the configuration
 +<sxh bash>
 +terraform plan                                                                                           Sat Apr  4 08:55:43 2020
 +Refreshing Terraform state in-memory prior to plan...
 +The refreshed state will be used to calculate this plan, but will not be
 +persisted to local or remote state storage.
 +
 +
 +------------------------------------------------------------------------
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +Plan: 1 to add, 0 to change, 0 to destroy.
 +
 +------------------------------------------------------------------------
 +
 +Note: You didn't specify an "-out" parameter to save this plan, so Terraform
 +can't guarantee that exactly these actions will be performed if
 +"terraform apply" is subsequently run.
 +</sxh>
 +
 +As we can see the terraform plan didn't throw any errors, now we can apply the configuration
 +<sxh bash>
 +terraform apply                                                                                   7.4s  Sat Apr  4 08:56:05 2020
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +Plan: 1 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.web_server_rg: Creating...
 +azurerm_resource_group.web_server_rg: Creation complete after 7s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +
 +Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
 +</sxh>
 +
 +Now we can check if there is a new resource group into Azure Portal or we can check in the command line
 +<sxh bash>
 +az group list                                                                                    23.7s  Sat Apr  4 08:58:48 2020
 +[
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "web-rg",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": {},
 +    "type": "Microsoft.Resources/resourceGroups"
 +  }
 +]
 +</sxh>
 +
 +As we can see there is a new resource group create by Terraform. Now let's destroy it to continue the configuration.
 +<sxh bash>
 +terraform destroy                                                                               2229ms  Sat Apr  4 09:00:32 2020
 +azurerm_resource_group.web_server_rg: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  - destroy
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be destroyed
 +  - resource "azurerm_resource_group" "web_server_rg" {
 +      - id       = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg" -> null
 +      - location = "westus2" -> null
 +      - name     = "web-rg" -> null
 +      - tags     = {} -> null
 +    }
 +
 +Plan: 0 to add, 0 to change, 1 to destroy.
 +
 +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
 +
 +azurerm_resource_group.web_server_rg: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 10s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 20s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 30s elapsed]
 +azurerm_resource_group.web_server_rg: Destruction complete after 39s
 +
 +Destroy complete! Resources: 1 destroyed.
 +</sxh>
 +
 +Now let's make sure that there is no resource group named web-rg
 +<sxh bash>
 +az group show --name web-rg                                                                     1971ms  Sat Apr  4 09:05:12 2020
 +Resource group 'web-rg' could not be found.
 +</sxh>
 +
 +Let's list all the resource groups
 +<sxh bash>
 +az group list                                                                                    58.4s  Sat Apr  4 09:04:17 2020
 +[]
 +</sxh>
 +
 +**Resources:**
 +  * [[https://docs.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest|az group]]
 +===== Terraform Basic Variables =====
 +
 +Variables:
 +  * main.tf
 +  * Variable Files "**terraform.tfvars** or ***.auto.tfvars**"
 +  * Environment
 +  * Precedence - Command passed, environment & defaults 
 +
 +Example of using a tfvars file and command passed variable
 +<sxh bash>
 +terraform apply -var-file "var.tfvars" -var "server=web"
 +</sxh>
 +
 +
 +Let's create a file with some variables to take a look how to handle them
 +<sxh bash>
 +vim variables.tf
 +variable "server_name" {
 +  default = "web-server"
 +}
 + 
 +variable "locations" {
 +  type    = map
 +  default = {
 +    location1 = "westus2"
 +    location2 = "westeurope"
 +  }
 +}
 + 
 +variable "subnets" {
 +  type    = list
 +  default = ["10.0.1.10","10.0.1.11"]
 +}
 + 
 +variable "live" {
 +  type    = string
 +  default = false
 +}
 +</sxh>
 +
 +Now we can access the terraform console
 +<sxh bash>
 +terraform console                                                                                 1.8m  Sat Apr  4 09:19:28 2020
 +>
 +</sxh>
 +
 +Now lets get the name of server name inside the terraform console
 +<sxh bash>
 +> var.server_name
 +web-server
 +</sxh>
 +
 +As we could see the form to get the information of a string is var.variable_name just that simple.
 +
 +Let's take a look how to get information about a map
 +<sxh bash>
 +> var.locations
 +{
 +  "location1" = "westus2"
 +  "location2" = "westeurope"
 +}
 +</sxh>
 +
 +As we can see we have the information about the map and two values location1 and location2, to get the information about only location1 we can do
 +<sxh bash>
 +var.locations["location1"]
 +westus2
 +</sxh>
 +
 +Let's take a look how to get information about a list
 +<sxh bash>
 +> var.subnets
 +[
 +  "10.0.1.10",
 +  "10.0.1.11",
 +]
 +</sxh>
 +
 +As we can see we have the information about the list and two values 10.0.1.10 and 10.0.1.11, to get the information about only first id of the list we can do
 +<sxh bash>
 +> var.subnets[0]
 +10.0.1.10
 +</sxh>
 +
 +We can take a look of Terraform Variables in the following link: [[https://www.terraform.io/docs/configuration/variables.html|Input Variables]]
 +
 +===== Azure Locations =====
 +
 +We can get the global infrastructure from the following link: [[https://azure.microsoft.com/en-us/global-infrastructure/locations/|Azure locations]]
 +
 +But usually we need to get it from the Azure CLI so.
 +
 +Let's log in 
 +<sxh bash>
 +az login --service-principal -u $ARM_CLIENT_ID -p $ARM_CLIENT_SECRET -t $ARM_TENANT_ID
 +</sxh>
 +
 +Now we can get the locations
 +<sxh bash>
 +az account list-locations -o table                                                                                          Sat Apr  4 08:19:38 2020
 +DisplayName           Latitude    Longitude    Name
 +--------------------  ----------  -----------  ------------------
 +East Asia             22.267      114.188      eastasia
 +Southeast Asia        1.283       103.833      southeastasia
 +Central US            41.5908     -93.6208     centralus
 +East US               37.3719     -79.8164     eastus
 +East US 2             36.6681     -78.3889     eastus2
 +West US               37.783      -122.417     westus
 +North Central US      41.8819     -87.6278     northcentralus
 +South Central US      29.4167     -98.5        southcentralus
 +North Europe          53.3478     -6.2597      northeurope
 +West Europe           52.3667     4.9          westeurope
 +Japan West            34.6939     135.5022     japanwest
 +Japan East            35.68       139.77       japaneast
 +Brazil South          -23.55      -46.633      brazilsouth
 +Australia East        -33.86      151.2094     australiaeast
 +Australia Southeast   -37.8136    144.9631     australiasoutheast
 +South India           12.9822     80.1636      southindia
 +Central India         18.5822     73.9197      centralindia
 +West India            19.088      72.868       westindia
 +Canada Central        43.653      -79.383      canadacentral
 +Canada East           46.817      -71.217      canadaeast
 +UK South              50.941      -0.799       uksouth
 +UK West               53.427      -3.084       ukwest
 +West Central US       40.890      -110.234     westcentralus
 +West US 2             47.233      -119.852     westus2
 +Korea Central         37.5665     126.9780     koreacentral
 +Korea South           35.1796     129.0756     koreasouth
 +France Central        46.3772     2.3730       francecentral
 +France South          43.8345     2.1972       francesouth
 +Australia Central     -35.3075    149.1244     australiacentral
 +Australia Central 2   -35.3075    149.1244     australiacentral2
 +UAE Central           24.466667   54.366669    uaecentral
 +UAE North             25.266666   55.316666    uaenorth
 +South Africa North    -25.731340  28.218370    southafricanorth
 +South Africa West     -34.075691  18.843266    southafricawest
 +Switzerland North     47.451542   8.564572     switzerlandnorth
 +Switzerland West      46.204391   6.143158     switzerlandwest
 +Germany North         53.073635   8.806422     germanynorth
 +Germany West Central  50.110924   8.682127     germanywestcentral
 +Norway West           58.969975   5.733107     norwaywest
 +Norway East           59.913868   10.752245    norwayeast
 +</sxh>
 +
 +===== Refactoring the Resource Group =====
 +
 +Let's create the resource group using variables
 +
 +Now let's create the file that will hold the variables
 +<sxh bash>
 +vim terraform.tfvars
 +# Define the Web server Location
 +web_server_location   = "westus2"
 +# Define the Web Server Resource Group Name
 +web_server_rg         = "web-rg"
 +</sxh>
 +
 +**Note:** //A .tfvars file is used to assign values to variables that have already been declared in .tf files, not to declare new variables. //
 +
 +Now let's refactor the main.tf to use the variables
 +<sxh bash>
 +vim main.tf
 +## Defining the Variables
 +variable "web_server_location" {}
 +variable "web_server_rg" {}
 +
 +
 +# Provider
 +# https://www.terraform.io/docs/providers/azurerm/index.html
 +provider "azurerm" {
 +  # With Terraform 12 we need to stick with 1.27
 +  version         = "~> 1.27"
 +  # The Subscription ID which should be used. This can also be sourced from the ARM_SUBSCRIPTION_ID Environment Variable.
 +  # subscription_id = "${var.subscription_id}"
 +  # The Client ID which should be used. This can also be sourced from the ARM_CLIENT_ID Environment Variable.
 +  # client_id       = "${var.client_id}"
 +  # The Client Secret which should be used. This can also be sourced from the ARM_CLIENT_SECRET Environment Variable.
 +  # client_secret   = "${var.client_secret}"
 +  # The Tenant ID which should be used. This can also be sourced from the ARM_TENANT_ID Environment Variable.
 +  # tenant_id       = "${var.tenant_id}"
 +}
 +
 +# Manages a Resource Group.
 +# https://www.terraform.io/docs/providers/azurerm/r/resource_group.html
 +resource "azurerm_resource_group" "web_server_rg" {
 +  # The Name which should be used for this Resource Group.
 +  # Here we'll use the variable web_server_rg that was declared into terraform.tfvars
 +  name     = var.web_server_rg
 +  # The Azure Region where the Resource Group should exist.
 +  # Here we'll use the variable web_server_location that was declared into terraform.tfvars
 +  location = var.web_server_location
 +}
 +</sxh>
 +
 +Now we can run the terraform plan to take a look what will happen if we apply the configuration
 +<sxh bash>
 +terraform plan                                                                               238ms  Sat Apr  4 09:44:02 2020
 +Refreshing Terraform state in-memory prior to plan...
 +The refreshed state will be used to calculate this plan, but will not be
 +persisted to local or remote state storage.
 +
 +
 +------------------------------------------------------------------------
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +Plan: 1 to add, 0 to change, 0 to destroy.
 +
 +------------------------------------------------------------------------
 +
 +Note: You didn't specify an "-out" parameter to save this plan, so Terraform
 +can't guarantee that exactly these actions will be performed if
 +"terraform apply" is subsequently run.
 +</sxh>
 +
 +As we can see the terraform plan didn't throw any errors, and we have the same configuration as before, now we can apply the configuration
 +<sxh bash>
 +terraform apply                                                                                   7.5s  Sat Apr  4 09:44:20 2020
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +Plan: 1 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.web_server_rg: Creating...
 +azurerm_resource_group.web_server_rg: Creation complete after 7s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +
 +Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
 +</sxh>
 +
 +Now we can check if there is a new resource group into Azure Portal or we can check in the command line
 +<sxh bash>
 +az group list                                                                                    27.8s  Sat Apr  4 09:46:13 2020
 +[
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "web-rg",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": {},
 +    "type": "Microsoft.Resources/resourceGroups"
 +  }
 +]
 +</sxh>
 +
 +As we can see there is a new resource group create by Terraform. Now let's destroy it to continue the configuration.
 +<sxh bash>
 +terraform destroy                                                                               3338ms  Sat Apr  4 09:46:17 2020
 +azurerm_resource_group.web_server_rg: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  - destroy
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be destroyed
 +  - resource "azurerm_resource_group" "web_server_rg" {
 +      - id       = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg" -> null
 +      - location = "westus2" -> null
 +      - name     = "web-rg" -> null
 +      - tags     = {} -> null
 +    }
 +
 +Plan: 0 to add, 0 to change, 1 to destroy.
 +
 +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
 +
 +azurerm_resource_group.web_server_rg: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 10s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 20s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 30s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 40s elapsed]
 +azurerm_resource_group.web_server_rg: Destruction complete after 42s
 +
 +Destroy complete! Resources: 1 destroyed.
 +</sxh>
 +
 +Now let's make sure that there is no resource group named web-rg
 +<sxh bash>
 +az group show --name web-rg                                                                       1.2m  Sat Apr  4 09:48:24 2020
 +Resource group 'web-rg' could not be found.
 +</sxh>
 +
 +Let's list all the resource groups
 +<sxh bash>
 +az group list                                                                               2396ms  Sat Apr  4 09:48:26 2020
 +[]
 +</sxh>
 +
 +**Resources:**
 +  * [[https://docs.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest|az group]]
 +
 +===== Terraform with Azure VNET =====
 +
 +**Azure VNET:**
 +  * Virtual Network 
 +  * Logical isolated network 
 +  * Address space 
 +  * Subnets 
 +  * Connectivity - VNET, VPN, Endpoints 
 +  * NSG 
 +
 +Let's update the file that will hold the variables with the new variables for the VNET
 +<sxh bash>
 +vim terraform.tfvars
 +# Define the Web server Location
 +web_server_location       = "westus2"
 +# Define the Web Server Resource Group Name
 +web_server_rg             = "web-rg"
 +# Resource Prefix 
 +resource_prefix           = "web-server"
 +# Address Space
 +web_server_address_space  = "10.0.0.0/22" 
 +</sxh>
 +
 +**Note:** //A .tfvars file is used to assign values to variables that have already been declared in .tf files, not to declare new variables. //
 +
 +Let's Edit the main.tf to use add the new resource called azurerm_virtual_network
 +<sxh bash>
 +vim main.tf
 +## Defining the Variables
 +variable "web_server_location" {}
 +variable "web_server_rg" {}
 +variable "resource_prefix" {}
 +variable "web_server_address_space" {}
 +
 +# Provider
 +# https://www.terraform.io/docs/providers/azurerm/index.html
 +provider "azurerm" {
 +  # With Terraform 12 we need to stick with 1.27
 +  version         = "~> 1.27"
 +  # The Subscription ID which should be used. This can also be sourced from the ARM_SUBSCRIPTION_ID Environment Variable.
 +  # subscription_id = "${var.subscription_id}"
 +  # The Client ID which should be used. This can also be sourced from the ARM_CLIENT_ID Environment Variable.
 +  # client_id       = "${var.client_id}"
 +  # The Client Secret which should be used. This can also be sourced from the ARM_CLIENT_SECRET Environment Variable.
 +  # client_secret   = "${var.client_secret}"
 +  # The Tenant ID which should be used. This can also be sourced from the ARM_TENANT_ID Environment Variable.
 +  # tenant_id       = "${var.tenant_id}"
 +}
 +
 +# Manages a Resource Group.
 +# https://www.terraform.io/docs/providers/azurerm/r/resource_group.html
 +resource "azurerm_resource_group" "web_server_rg" {
 +  # The Name which should be used for this Resource Group.
 +  # Here we'll use the variable web_server_rg that was declared into terraform.tfvars
 +  name     = var.web_server_rg
 +  # The Azure Region where the Resource Group should exist.
 +  # Here we'll use the variable web_server_location that was declared into terraform.tfvars
 +  location = var.web_server_location
 +}
 +
 +
 +# Manages a virtual network including any configured subnets. 
 +# Each subnet can optionally be configured with a security group to be associated with the subnet.
 +# https://www.terraform.io/docs/providers/azurerm/r/virtual_network.html
 +resource "azurerm_virtual_network" "web_server_vnet" {
 +  # (Required) The name of the virtual network. Changing this forces a new resource to be created.
 +  # Note: here as we need to interpolate the variable with some kind of string we need to use "${}-string" inside quotes
 +  name                  = "${var.resource_prefix}-vnet"
 +  # (Required) The location/region where the virtual network is created. Changing this forces a new resource to be created.
 +  location              = var.web_server_location
 +  #  (Required) The name of the resource group in which to create the virtual network.
 +  resource_group_name   = azurerm_resource_group.web_server_rg.name
 +  # (Required) The address space that is used the virtual network. You can supply more than one address space. Changing this forces a new resource to be created.
 +  address_space         = [var.web_server_address_space]
 +}
 +</sxh>
 +
 +Now we can run the terraform plan to take a look what will happen if we apply the configuration
 +<sxh bash>
 +terraform plan                                                                                    9.2s  Sat Apr  4 10:12:00 2020
 +Refreshing Terraform state in-memory prior to plan...
 +The refreshed state will be used to calculate this plan, but will not be
 +persisted to local or remote state storage.
 +
 +
 +------------------------------------------------------------------------
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be created
 +  + resource "azurerm_virtual_network" "web_server_vnet" {
 +      + address_space       = [
 +          + "10.0.0.0/22",
 +        ]
 +      + id                  = (known after apply)
 +      + location            = "westus2"
 +      + name                = "web-server-vnet"
 +      + resource_group_name = "web-rg"
 +      + tags                = (known after apply)
 +
 +      + subnet {
 +          + address_prefix = (known after apply)
 +          + id             = (known after apply)
 +          + name           = (known after apply)
 +          + security_group = (known after apply)
 +        }
 +    }
 +
 +Plan: 2 to add, 0 to change, 0 to destroy.
 +
 +------------------------------------------------------------------------
 +
 +Note: You didn't specify an "-out" parameter to save this plan, so Terraform
 +can't guarantee that exactly these actions will be performed if
 +"terraform apply" is subsequently run.
 +</sxh>
 +
 +As we can see the terraform plan didn't throw any errors, now we can apply the configuration
 +<sxh bash>
 +terraform apply                                                                                 2674ms  Sat Apr  4 10:18:15 2020
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be created
 +  + resource "azurerm_virtual_network" "web_server_vnet" {
 +      + address_space       = [
 +          + "10.0.0.0/22",
 +        ]
 +      + id                  = (known after apply)
 +      + location            = "westus2"
 +      + name                = "web-server-vnet"
 +      + resource_group_name = "web-rg"
 +      + tags                = (known after apply)
 +
 +      + subnet {
 +          + address_prefix = (known after apply)
 +          + id             = (known after apply)
 +          + name           = (known after apply)
 +          + security_group = (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.web_server_rg: Creating...
 +azurerm_resource_group.web_server_rg: Creation complete after 8s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_virtual_network.web_server_vnet: Creating...
 +azurerm_virtual_network.web_server_vnet: Still creating... [10s elapsed]
 +azurerm_virtual_network.web_server_vnet: Creation complete after 14s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +
 +Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
 +</sxh>
 +
 +Now we can check if there is a new resource group into Azure Portal or we can check in the command line
 +<sxh bash>
 +az group list                                                                                    38.2s  Sat Apr  4 10:23:07 2020
 +[
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "web-rg",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": {},
 +    "type": "Microsoft.Resources/resourceGroups"
 +  },
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/NetworkWatcherRG",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "NetworkWatcherRG",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": null,
 +    "type": "Microsoft.Resources/resourceGroups"
 +  }
 +]
 +</sxh>
 +
 +Now let's list the VNET
 +<sxh bash>
 +az network vnet list                                                                            2261ms  Sat Apr  4 10:23:15 2020
 +[
 +  {
 +    "addressSpace": {
 +      "addressPrefixes": [
 +        "10.0.0.0/22"
 +      ]
 +    },
 +    "bgpCommunities": null,
 +    "ddosProtectionPlan": null,
 +    "dhcpOptions": {
 +      "dnsServers": []
 +    },
 +    "enableDdosProtection": false,
 +    "enableVmProtection": false,
 +    "etag": "W/\"5d2178ea-d82a-438e-81fc-658424826beb\"",
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet",
 +    "location": "westus2",
 +    "name": "web-server-vnet",
 +    "provisioningState": "Succeeded",
 +    "resourceGroup": "web-rg",
 +    "resourceGuid": "00e0ddcd-1a88-4395-8a1c-980c6bec4bdb",
 +    "subnets": [],
 +    "tags": {},
 +    "type": "Microsoft.Network/virtualNetworks",
 +    "virtualNetworkPeerings": []
 +  }
 +]
 +</sxh>
 +
 +As we can see there is a new resource group create by Terraform. Now let's destroy it to continue the configuration.
 +<sxh bash>
 +terraform destroy                                                                               2882ms  Sat Apr  4 10:26:53 2020
 +azurerm_resource_group.web_server_rg: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_virtual_network.web_server_vnet: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  - destroy
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be destroyed
 +  - resource "azurerm_resource_group" "web_server_rg" {
 +      - id       = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg" -> null
 +      - location = "westus2" -> null
 +      - name     = "web-rg" -> null
 +      - tags     = {} -> null
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be destroyed
 +  - resource "azurerm_virtual_network" "web_server_vnet" {
 +      - address_space       = [
 +          - "10.0.0.0/22",
 +        ] -> null
 +      - dns_servers         = [] -> null
 +      - id                  = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet" -> null
 +      - location            = "westus2" -> null
 +      - name                = "web-server-vnet" -> null
 +      - resource_group_name = "web-rg" -> null
 +      - tags                = {} -> null
 +    }
 +
 +Plan: 0 to add, 0 to change, 2 to destroy.
 +
 +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
 +
 +azurerm_virtual_network.web_server_vnet: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +azurerm_virtual_network.web_server_vnet: Destruction complete after 2s
 +azurerm_resource_group.web_server_rg: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 10s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 20s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 30s elapsed]
 +azurerm_resource_group.web_server_rg: Destruction complete after 38s
 +
 +Destroy complete! Resources: 2 destroyed.
 +</sxh>
 +
 +
 +Let's list all the resource groups
 +<sxh bash>
 +az group list                                                                                       1m  Sat Apr  4 10:29:56 2020
 +[
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/NetworkWatcherRG",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "NetworkWatcherRG",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": null,
 +    "type": "Microsoft.Resources/resourceGroups"
 +  }
 +]
 +</sxh>
 +
 +Now we have only one resource group Called: **NetworkWatcherRG**, bellow the description about it.
 +
 +Network Watcher is a regional service that enables you to monitor and diagnose conditions at a network scenario level in, to, and from Azure. Scenario level monitoring enables you to diagnose problems at an end to end network level view. Network diagnostic and visualization tools available with Network Watcher help you understand, diagnose, and gain insights to your network in Azure. Network Watcher is enabled through the creation of a Network Watcher resource. This resource allows you to utilize Network Watcher capabilities.
 +
 +**Resources:**
 +  * [[https://docs.microsoft.com/en-us/cli/azure/network/vnet?view=azure-cli-latest|az network vnet]]
 +  * [[https://docs.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest|az group]]
 +  * [[https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-create|Azure Network Watcher instance]]
 +
 +===== Terraform Dependencies =====
 +
 +Let's take a look the kinds of dependencies that we may face
 +
 +This resource has no dependency of another one, it just dependes of the variable web_server_rg and if does not has any default value or declaration when you run plan or apply it will ask you about it.
 +<sxh bash>
 +# No dependency 
 +resource "azurerm_resource_group" "web_server_rg"
 +  name = var.web_server_rg
 +}
 +
 +# No dependency 
 +resource "azurerm_virtual_network" "web_server_vnet" {
 +  name                = "${var.resource_prefix}-vnet"
 +  resource_group_name = var.web_server_rg
 +}
 +</sxh>
 +
 +This resource has indirect dependency of another one, in this case we depend of **azurerm_resource_group.web_server_rg.name**, when we run the plan or apply and the resource required is not present we shall have a failure about it
 +<sxh bash>
 +# Indirect dependency 
 +resource "azurerm_virtual_network" "web_server_vnet" {
 +  name                = "${var.resource_prefix}-vnet"
 +  resource_group_name = azurerm_resource_group.web_server_rg.name
 +}
 +</sxh>
 +
 +This resource has direct dependency of this one, in this case we depend of **azurerm_resource_group.web_server_rg** when we run the plan or apply and the resource required is not present we shall have a failure about it. For example we try to create the virtual network inside the resource group that should've be created before this resource we'll have a failure about the dependency.
 +<sxh bash>
 +# Direct dependency 
 +resource "azurerm_virtual_network" "web_server_vnet" {
 +  name                = "${var.resource_prefix}-vnet"
 +  resource_group_name = var.web_server_rg
 +  depends_on          = [ "azurerm_resource_group.web_server_rg" ]
 +}
 +</sxh>
 +
 +===== Terraform with Azure Subnet =====
 +
 +**Azure Subnet:**
 +  * Subnetwork within a VNET 
 +  * Address space 
 +  * Segmentation 
 +  * NSG 
 +
 +Let's update the file that will hold the variables with the new variables for the Subnets
 +<sxh bash>
 +vim terraform.tfvars
 +# Define the Web server Location
 +web_server_location       = "westus2"
 +# Define the Web Server Resource Group Name
 +web_server_rg             = "web-rg"
 +# Resource Prefix 
 +resource_prefix           = "web-server"
 +# Address Space
 +web_server_address_space  = "10.0.0.0/22" 
 +# Web Server Address Prefix 
 +web_server_address_prefix = "10.0.1.0/24"
 +</sxh>
 +
 +**Note:** //A .tfvars file is used to assign values to variables that have already been declared in .tf files, not to declare new variables. //
 +
 +Let's Edit the main.tf to use add the new resource called azurerm_subnet
 +<sxh bash>
 +vim main.tf
 +## Defining the Variables
 +variable "web_server_location" {}
 +variable "web_server_rg" {}
 +variable "resource_prefix" {}
 +variable "web_server_address_space" {}
 +variable "web_server_address_prefix" {}
 +
 +
 +# Provider
 +# https://www.terraform.io/docs/providers/azurerm/index.html
 +provider "azurerm" {
 +  # With Terraform 12 we need to stick with 1.27
 +  version         = "~> 1.27"
 +  # The Subscription ID which should be used. This can also be sourced from the ARM_SUBSCRIPTION_ID Environment Variable.
 +  # subscription_id = "${var.subscription_id}"
 +  # The Client ID which should be used. This can also be sourced from the ARM_CLIENT_ID Environment Variable.
 +  # client_id       = "${var.client_id}"
 +  # The Client Secret which should be used. This can also be sourced from the ARM_CLIENT_SECRET Environment Variable.
 +  # client_secret   = "${var.client_secret}"
 +  # The Tenant ID which should be used. This can also be sourced from the ARM_TENANT_ID Environment Variable.
 +  # tenant_id       = "${var.tenant_id}"
 +}
 +
 +# Manages a Resource Group.
 +# https://www.terraform.io/docs/providers/azurerm/r/resource_group.html
 +resource "azurerm_resource_group" "web_server_rg" {
 +  # The Name which should be used for this Resource Group.
 +  # Here we'll use the variable web_server_rg that was declared into terraform.tfvars
 +  name     = var.web_server_rg
 +  # The Azure Region where the Resource Group should exist.
 +  # Here we'll use the variable web_server_location that was declared into terraform.tfvars
 +  location = var.web_server_location
 +}
 +
 +
 +# Manages a virtual network including any configured subnets. 
 +# Each subnet can optionally be configured with a security group to be associated with the subnet.
 +# https://www.terraform.io/docs/providers/azurerm/r/virtual_network.html
 +resource "azurerm_virtual_network" "web_server_vnet" {
 +  # (Required) The name of the virtual network. Changing this forces a new resource to be created.
 +  # Note: here as we need to interpolate the variable with some kind of string we need to use "${}-string" inside quotes
 +  name                  = "${var.resource_prefix}-vnet"
 +  # (Required) The location/region where the virtual network is created. Changing this forces a new resource to be created.
 +  location              = var.web_server_location
 +  #  (Required) The name of the resource group in which to create the virtual network.
 +  resource_group_name   = azurerm_resource_group.web_server_rg.name
 +  # (Required) The address space that is used the virtual network. You can supply more than one address space. Changing this forces a new resource to be created.
 +  address_space         = [var.web_server_address_space]
 +}
 +
 +
 +# Manages a subnet. Subnets represent network segments within the IP space defined by the virtual network.
 +# https://www.terraform.io/docs/providers/azurerm/r/subnet.html
 +resource "azurerm_subnet" "web_server_subnet" {
 +  #  (Required) The name of the subnet. Changing this forces a new resource to be created
 +  name                      = "${var.resource_prefix}-subnet"
 +  # (Required) The name of the resource group in which to create the subnet. Changing this forces a new resource to be created.
 +  resource_group_name       = azurerm_resource_group.web_server_rg.name
 +  # (Required) The name of the virtual network to which to attach the subnet. Changing this forces a new resource to be created.
 +  virtual_network_name      = azurerm_virtual_network.web_server_vnet.name
 +  # (Required) The address prefix to use for the subnet.
 +  address_prefix            = var.web_server_address_prefix
 +}
 +</sxh>
 +
 +Now we can run the terraform plan to take a look what will happen if we apply the configuration
 +<sxh bash>
 +terraform plan                                                                                  2688ms  Sat Apr  4 10:30:29 2020
 +Refreshing Terraform state in-memory prior to plan...
 +The refreshed state will be used to calculate this plan, but will not be
 +persisted to local or remote state storage.
 +
 +
 +------------------------------------------------------------------------
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +  # azurerm_subnet.web_server_subnet will be created
 +  + resource "azurerm_subnet" "web_server_subnet" {
 +      + address_prefix                                 = "10.0.1.0/24"
 +      + enforce_private_link_endpoint_network_policies = false
 +      + enforce_private_link_service_network_policies  = false
 +      + id                                             = (known after apply)
 +      + ip_configurations                              = (known after apply)
 +      + name                                           = "web-server-subnet"
 +      + resource_group_name                            = "web-rg"
 +      + virtual_network_name                           = "web-server-vnet"
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be created
 +  + resource "azurerm_virtual_network" "web_server_vnet" {
 +      + address_space       = [
 +          + "10.0.0.0/22",
 +        ]
 +      + id                  = (known after apply)
 +      + location            = "westus2"
 +      + name                = "web-server-vnet"
 +      + resource_group_name = "web-rg"
 +      + tags                = (known after apply)
 +
 +      + subnet {
 +          + address_prefix = (known after apply)
 +          + id             = (known after apply)
 +          + name           = (known after apply)
 +          + security_group = (known after apply)
 +        }
 +    }
 +
 +Plan: 3 to add, 0 to change, 0 to destroy.
 +
 +------------------------------------------------------------------------
 +
 +Note: You didn't specify an "-out" parameter to save this plan, so Terraform
 +can't guarantee that exactly these actions will be performed if
 +"terraform apply" is subsequently run.
 +</sxh>
 +
 +As we can see the terraform plan didn't throw any errors, now we can apply the configuration
 +<sxh bash>
 +terraform apply                                                                                   7.2s  Sat Apr  4 11:14:35 2020
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +  # azurerm_subnet.web_server_subnet will be created
 +  + resource "azurerm_subnet" "web_server_subnet" {
 +      + address_prefix                                 = "10.0.1.0/24"
 +      + enforce_private_link_endpoint_network_policies = false
 +      + enforce_private_link_service_network_policies  = false
 +      + id                                             = (known after apply)
 +      + ip_configurations                              = (known after apply)
 +      + name                                           = "web-server-subnet"
 +      + resource_group_name                            = "web-rg"
 +      + virtual_network_name                           = "web-server-vnet"
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be created
 +  + resource "azurerm_virtual_network" "web_server_vnet" {
 +      + address_space       = [
 +          + "10.0.0.0/22",
 +        ]
 +      + id                  = (known after apply)
 +      + location            = "westus2"
 +      + name                = "web-server-vnet"
 +      + resource_group_name = "web-rg"
 +      + tags                = (known after apply)
 +
 +      + subnet {
 +          + address_prefix = (known after apply)
 +          + id             = (known after apply)
 +          + name           = (known after apply)
 +          + security_group = (known after apply)
 +        }
 +    }
 +
 +Plan: 3 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.web_server_rg: Creating...
 +azurerm_resource_group.web_server_rg: Creation complete after 4s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_virtual_network.web_server_vnet: Creating...
 +azurerm_virtual_network.web_server_vnet: Still creating... [10s elapsed]
 +azurerm_virtual_network.web_server_vnet: Creation complete after 13s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +azurerm_subnet.web_server_subnet: Creating...
 +azurerm_subnet.web_server_subnet: Creation complete after 3s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet]
 +
 +Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
 +</sxh>
 +
 +Now we can check if there is a new resource group into Azure Portal or we can check in the command line
 +<sxh bash>
 +az group list                                                                                    43.2s  Sat Apr  4 11:22:47 2020
 +[
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/NetworkWatcherRG",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "NetworkWatcherRG",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": null,
 +    "type": "Microsoft.Resources/resourceGroups"
 +  },
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "web-rg",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": {},
 +    "type": "Microsoft.Resources/resourceGroups"
 +  }
 +]
 +</sxh>
 +
 +Now let's list the VNET
 +<sxh bash>
 +az network vnet list                                                                            2999ms  Sat Apr  4 11:22:53 2020
 +[
 +  {
 +    "addressSpace": {
 +      "addressPrefixes": [
 +        "10.0.0.0/22"
 +      ]
 +    },
 +    "bgpCommunities": null,
 +    "ddosProtectionPlan": null,
 +    "dhcpOptions": {
 +      "dnsServers": []
 +    },
 +    "enableDdosProtection": false,
 +    "enableVmProtection": false,
 +    "etag": "W/\"41bc2a42-e22f-49c8-a396-6aae118adae3\"",
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet",
 +    "location": "westus2",
 +    "name": "web-server-vnet",
 +    "provisioningState": "Succeeded",
 +    "resourceGroup": "web-rg",
 +    "resourceGuid": "a1b2d72a-c6c4-4314-8b19-4019519229c6",
 +    "subnets": [
 +      {
 +        "addressPrefix": "10.0.1.0/24",
 +        "addressPrefixes": null,
 +        "delegations": [],
 +        "etag": "W/\"41bc2a42-e22f-49c8-a396-6aae118adae3\"",
 +        "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet",
 +        "ipConfigurationProfiles": null,
 +        "ipConfigurations": null,
 +        "name": "web-server-subnet",
 +        "natGateway": null,
 +        "networkSecurityGroup": null,
 +        "privateEndpointNetworkPolicies": "Enabled",
 +        "privateEndpoints": null,
 +        "privateLinkServiceNetworkPolicies": "Enabled",
 +        "provisioningState": "Succeeded",
 +        "purpose": null,
 +        "resourceGroup": "web-rg",
 +        "resourceNavigationLinks": null,
 +        "routeTable": null,
 +        "serviceAssociationLinks": null,
 +        "serviceEndpointPolicies": null,
 +        "serviceEndpoints": [],
 +        "type": "Microsoft.Network/virtualNetworks/subnets"
 +      }
 +    ],
 +    "tags": {},
 +    "type": "Microsoft.Network/virtualNetworks",
 +    "virtualNetworkPeerings": []
 +  }
 +]
 +</sxh>
 +
 +Now let's list the subnet that we've just created
 +<sxh bash>
 +az network vnet subnet list -g web-rg --vnet-name web-server-vnet                               2398ms  Sat Apr  4 11:23:48 2020
 +[
 +  {
 +    "addressPrefix": "10.0.1.0/24",
 +    "addressPrefixes": null,
 +    "delegations": [],
 +    "etag": "W/\"41bc2a42-e22f-49c8-a396-6aae118adae3\"",
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet",
 +    "ipConfigurationProfiles": null,
 +    "ipConfigurations": null,
 +    "name": "web-server-subnet",
 +    "natGateway": null,
 +    "networkSecurityGroup": null,
 +    "privateEndpointNetworkPolicies": "Enabled",
 +    "privateEndpoints": null,
 +    "privateLinkServiceNetworkPolicies": "Enabled",
 +    "provisioningState": "Succeeded",
 +    "purpose": null,
 +    "resourceGroup": "web-rg",
 +    "resourceNavigationLinks": null,
 +    "routeTable": null,
 +    "serviceAssociationLinks": null,
 +    "serviceEndpointPolicies": null,
 +    "serviceEndpoints": [],
 +    "type": "Microsoft.Network/virtualNetworks/subnets"
 +  }
 +]
 +</sxh>
 +
 +As we can see there is a new resource group create by Terraform. Now let's destroy it to continue the configuration.
 +<sxh bash>
 +terraform destroy                                                                               1657ms  Sat Apr  4 11:25:19 2020
 +azurerm_resource_group.web_server_rg: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_virtual_network.web_server_vnet: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +azurerm_subnet.web_server_subnet: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet]
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  - destroy
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_resource_group.web_server_rg will be destroyed
 +  - resource "azurerm_resource_group" "web_server_rg" {
 +      - id       = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg" -> null
 +      - location = "westus2" -> null
 +      - name     = "web-rg" -> null
 +      - tags     = {} -> null
 +    }
 +
 +  # azurerm_subnet.web_server_subnet will be destroyed
 +  - resource "azurerm_subnet" "web_server_subnet" {
 +      - address_prefix                                 = "10.0.1.0/24" -> null
 +      - enforce_private_link_endpoint_network_policies = false -> null
 +      - enforce_private_link_service_network_policies  = false -> null
 +      - id                                             = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet" -> null
 +      - ip_configurations                              = [] -> null
 +      - name                                           = "web-server-subnet" -> null
 +      - resource_group_name                            = "web-rg" -> null
 +      - service_endpoints                              = [] -> null
 +      - virtual_network_name                           = "web-server-vnet" -> null
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be destroyed
 +  - resource "azurerm_virtual_network" "web_server_vnet" {
 +      - address_space       = [
 +          - "10.0.0.0/22",
 +        ] -> null
 +      - dns_servers         = [] -> null
 +      - id                  = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet" -> null
 +      - location            = "westus2" -> null
 +      - name                = "web-server-vnet" -> null
 +      - resource_group_name = "web-rg" -> null
 +      - tags                = {} -> null
 +
 +      - subnet {
 +          - address_prefix = "10.0.1.0/24" -> null
 +          - id             = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet" -> null
 +          - name           = "web-server-subnet" -> null
 +        }
 +    }
 +
 +Plan: 0 to add, 0 to change, 3 to destroy.
 +
 +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
 +
 +azurerm_subnet.web_server_subnet: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet]
 +azurerm_subnet.web_server_subnet: Destruction complete after 2s
 +azurerm_virtual_network.web_server_vnet: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +azurerm_virtual_network.web_server_vnet: Destruction complete after 2s
 +azurerm_resource_group.web_server_rg: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 10s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 20s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 30s elapsed]
 +azurerm_resource_group.web_server_rg: Destruction complete after 39s
 +
 +Destroy complete! Resources: 3 destroyed.
 +</sxh>
 +
 +
 +Let's list all the resource groups
 +<sxh bash>
 +az group list                                                                                       1m  Sat Apr  4 11:29:01 2020
 +[
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/NetworkWatcherRG",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "NetworkWatcherRG",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": null,
 +    "type": "Microsoft.Resources/resourceGroups"
 +  }
 +]
 +</sxh>
 +
 +Now we have only one resource group Called: **NetworkWatcherRG**, bellow the description about it.
 +
 +Network Watcher is a regional service that enables you to monitor and diagnose conditions at a network scenario level in, to, and from Azure. Scenario level monitoring enables you to diagnose problems at an end to end network level view. Network diagnostic and visualization tools available with Network Watcher help you understand, diagnose, and gain insights to your network in Azure. Network Watcher is enabled through the creation of a Network Watcher resource. This resource allows you to utilize Network Watcher capabilities.
 +
 +**Resources:**
 +  * [[https://docs.microsoft.com/en-us/cli/azure/network/vnet?view=azure-cli-latest|az network vnet]]
 +  * [[https://docs.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest|az group]]
 +  * [[https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-create|Azure Network Watcher instance]]
 +
 +===== Terraform with Azure Network Interface =====
 +
 +**Azure Network Interface:**
 +  * Subnet/VNET
 +  * IP Private and Public
 +  * Static and Dynamic
 +  * DNS Settings
 +  * NSG 
 +
 +Let's update the file that will hold the variables with the new variables for the Network Interfaces
 +<sxh bash>
 +vim terraform.tfvars
 +# Define the Web server Location
 +web_server_location       = "westus2"
 +# Define the Web Server Resource Group Name
 +web_server_rg             = "web-rg"
 +# Resource Prefix 
 +resource_prefix           = "web-server"
 +# Address Space
 +web_server_address_space  = "10.0.0.0/22" 
 +# Web Server Address Prefix 
 +web_server_address_prefix = "10.0.1.0/24"
 +# Web Server Name
 +web_server_name           = "web-01"
 +</sxh>
 +
 +**Note:** //A .tfvars file is used to assign values to variables that have already been declared in .tf files, not to declare new variables. //
 +
 +Let's Edit the main.tf to use add the new resource called azurerm_subnet
 +<sxh bash>
 +vim main.tf
 +## Defining the Variables
 +variable "web_server_location" {}
 +variable "web_server_rg" {}
 +variable "resource_prefix" {}
 +variable "web_server_address_space" {}
 +variable "web_server_address_prefix" {}
 +variable "web_server_name" {}
 +
 +
 +
 +# Provider
 +# https://www.terraform.io/docs/providers/azurerm/index.html
 +provider "azurerm" {
 +  # With Terraform 12 we need to stick with 1.27
 +  version         = "~> 1.27"
 +  # The Subscription ID which should be used. This can also be sourced from the ARM_SUBSCRIPTION_ID Environment Variable.
 +  # subscription_id = "${var.subscription_id}"
 +  # The Client ID which should be used. This can also be sourced from the ARM_CLIENT_ID Environment Variable.
 +  # client_id       = "${var.client_id}"
 +  # The Client Secret which should be used. This can also be sourced from the ARM_CLIENT_SECRET Environment Variable.
 +  # client_secret   = "${var.client_secret}"
 +  # The Tenant ID which should be used. This can also be sourced from the ARM_TENANT_ID Environment Variable.
 +  # tenant_id       = "${var.tenant_id}"
 +}
 +
 +# Manages a Resource Group.
 +# https://www.terraform.io/docs/providers/azurerm/r/resource_group.html
 +resource "azurerm_resource_group" "web_server_rg" {
 +  # The Name which should be used for this Resource Group.
 +  # Here we'll use the variable web_server_rg that was declared into terraform.tfvars
 +  name     = var.web_server_rg
 +  # The Azure Region where the Resource Group should exist.
 +  # Here we'll use the variable web_server_location that was declared into terraform.tfvars
 +  location = var.web_server_location
 +}
 +
 +
 +# Manages a virtual network including any configured subnets. 
 +# Each subnet can optionally be configured with a security group to be associated with the subnet.
 +# https://www.terraform.io/docs/providers/azurerm/r/virtual_network.html
 +resource "azurerm_virtual_network" "web_server_vnet" {
 +  # (Required) The name of the virtual network. Changing this forces a new resource to be created.
 +  # Note: here as we need to interpolate the variable with some kind of string we need to use "${}-string" inside quotes
 +  name                  = "${var.resource_prefix}-vnet"
 +  # (Required) The location/region where the virtual network is created. Changing this forces a new resource to be created.
 +  location              = var.web_server_location
 +  #  (Required) The name of the resource group in which to create the virtual network.
 +  resource_group_name   = azurerm_resource_group.web_server_rg.name
 +  # (Required) The address space that is used the virtual network. You can supply more than one address space. Changing this forces a new resource to be created.
 +  address_space         = [var.web_server_address_space]
 +}
 +
 +
 +# Manages a subnet. Subnets represent network segments within the IP space defined by the virtual network.
 +# https://www.terraform.io/docs/providers/azurerm/r/subnet.html
 +resource "azurerm_subnet" "web_server_subnet" {
 +  #  (Required) The name of the subnet. Changing this forces a new resource to be created
 +  name                      = "${var.resource_prefix}-subnet"
 +  # (Required) The name of the resource group in which to create the subnet. Changing this forces a new resource to be created.
 +  resource_group_name       = azurerm_resource_group.web_server_rg.name
 +  # (Required) The name of the virtual network to which to attach the subnet. Changing this forces a new resource to be created.
 +  virtual_network_name      = azurerm_virtual_network.web_server_vnet.name
 +  # (Required) The address prefix to use for the subnet.
 +  address_prefix            = var.web_server_address_prefix
 +}
 +
 +# Manages a Network Interface.
 +# https://www.terraform.io/docs/providers/azurerm/r/network_interface.html
 +resource "azurerm_network_interface" "web_server_nic" {
 +  # (Required) The name of the Network Interface. Changing this forces a new resource to be created.
 +  name                      = "${var.web_server_name}-nic"
 +  # (Required) The location where the Network Interface should exist. Changing this forces a new resource to be created.
 +  location                  = var.web_server_location
 +  # (Required) The name of the Resource Group in which to create the Network Interface. Changing this forces a new resource to be created.
 +  resource_group_name       = azurerm_resource_group.web_server_rg.name
 +
 +  # (Required) One or more ip_configuration blocks as defined below.
 +  ip_configuration {
 +    # (Required) A name used for this IP Configuration.
 +    name                          = "${var.web_server_name}-ip"
 +    # (Optional) The ID of the Subnet where this Network Interface should be located in.
 +    subnet_id                     = azurerm_subnet.web_server_subnet.id
 +    # (Optional) The IP Version to use. Possible values are IPv4 or IPv6. Defaults to IPv4.
 +    private_ip_address_version    = "IPv4"
 +    # (Required) The allocation method used for the Private IP Address. Possible values are Dynamic and Static.
 +    private_ip_address_allocation = "Dynamic"
 +  }
 +}
 +</sxh>
 +
 +Now we can run the terraform plan to take a look what will happen if we apply the configuration
 +<sxh bash>
 +terraform plan                                                                                  3389ms  Sat Apr  4 11:29:34 2020
 +Refreshing Terraform state in-memory prior to plan...
 +The refreshed state will be used to calculate this plan, but will not be
 +persisted to local or remote state storage.
 +
 +
 +------------------------------------------------------------------------
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_network_interface.web_server_nic will be created
 +  + resource "azurerm_network_interface" "web_server_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_fqdn                 = (known after apply)
 +      + location                      = "westus2"
 +      + mac_address                   = (known after apply)
 +      + name                          = "web-01-nic"
 +      + private_ip_address            = (known after apply)
 +      + private_ip_addresses          = (known after apply)
 +      + resource_group_name           = "web-rg"
 +      + tags                          = (known after apply)
 +      + virtual_machine_id            = (known after apply)
 +
 +      + ip_configuration {
 +          + application_gateway_backend_address_pools_ids = (known after apply)
 +          + application_security_group_ids                = (known after apply)
 +          + load_balancer_backend_address_pools_ids       = (known after apply)
 +          + load_balancer_inbound_nat_rules_ids           = (known after apply)
 +          + name                                          = "web-01-ip"
 +          + primary                                       = (known after apply)
 +          + private_ip_address                            = (known after apply)
 +          + private_ip_address_allocation                 = "dynamic"
 +          + private_ip_address_version                    = "IPv4"
 +          + subnet_id                                     = (known after apply)
 +        }
 +    }
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +  # azurerm_subnet.web_server_subnet will be created
 +  + resource "azurerm_subnet" "web_server_subnet" {
 +      + address_prefix                                 = "10.0.1.0/24"
 +      + enforce_private_link_endpoint_network_policies = false
 +      + enforce_private_link_service_network_policies  = false
 +      + id                                             = (known after apply)
 +      + ip_configurations                              = (known after apply)
 +      + name                                           = "web-server-subnet"
 +      + resource_group_name                            = "web-rg"
 +      + virtual_network_name                           = "web-server-vnet"
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be created
 +  + resource "azurerm_virtual_network" "web_server_vnet" {
 +      + address_space       = [
 +          + "10.0.0.0/22",
 +        ]
 +      + id                  = (known after apply)
 +      + location            = "westus2"
 +      + name                = "web-server-vnet"
 +      + resource_group_name = "web-rg"
 +      + tags                = (known after apply)
 +
 +      + subnet {
 +          + address_prefix = (known after apply)
 +          + id             = (known after apply)
 +          + name           = (known after apply)
 +          + security_group = (known after apply)
 +        }
 +    }
 +
 +Plan: 4 to add, 0 to change, 0 to destroy.
 +
 +------------------------------------------------------------------------
 +
 +Note: You didn't specify an "-out" parameter to save this plan, so Terraform
 +can't guarantee that exactly these actions will be performed if
 +"terraform apply" is subsequently run.
 +</sxh>
 +
 +As we can see the terraform plan didn't throw any errors, now we can apply the configuration
 +<sxh bash>
 +terraform apply                                                                                     9s  Sat Apr  4 12:05:28 2020
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  + create
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_network_interface.web_server_nic will be created
 +  + resource "azurerm_network_interface" "web_server_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_fqdn                 = (known after apply)
 +      + location                      = "westus2"
 +      + mac_address                   = (known after apply)
 +      + name                          = "web-01-nic"
 +      + private_ip_address            = (known after apply)
 +      + private_ip_addresses          = (known after apply)
 +      + resource_group_name           = "web-rg"
 +      + tags                          = (known after apply)
 +      + virtual_machine_id            = (known after apply)
 +
 +      + ip_configuration {
 +          + application_gateway_backend_address_pools_ids = (known after apply)
 +          + application_security_group_ids                = (known after apply)
 +          + load_balancer_backend_address_pools_ids       = (known after apply)
 +          + load_balancer_inbound_nat_rules_ids           = (known after apply)
 +          + name                                          = "web-01-ip"
 +          + primary                                       = (known after apply)
 +          + private_ip_address                            = (known after apply)
 +          + private_ip_address_allocation                 = "dynamic"
 +          + private_ip_address_version                    = "IPv4"
 +          + subnet_id                                     = (known after apply)
 +        }
 +    }
 +
 +  # azurerm_resource_group.web_server_rg will be created
 +  + resource "azurerm_resource_group" "web_server_rg" {
 +      + id       = (known after apply)
 +      + location = "westus2"
 +      + name     = "web-rg"
 +      + tags     = (known after apply)
 +    }
 +
 +  # azurerm_subnet.web_server_subnet will be created
 +  + resource "azurerm_subnet" "web_server_subnet" {
 +      + address_prefix                                 = "10.0.1.0/24"
 +      + enforce_private_link_endpoint_network_policies = false
 +      + enforce_private_link_service_network_policies  = false
 +      + id                                             = (known after apply)
 +      + ip_configurations                              = (known after apply)
 +      + name                                           = "web-server-subnet"
 +      + resource_group_name                            = "web-rg"
 +      + virtual_network_name                           = "web-server-vnet"
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be created
 +  + resource "azurerm_virtual_network" "web_server_vnet" {
 +      + address_space       = [
 +          + "10.0.0.0/22",
 +        ]
 +      + id                  = (known after apply)
 +      + location            = "westus2"
 +      + name                = "web-server-vnet"
 +      + resource_group_name = "web-rg"
 +      + tags                = (known after apply)
 +
 +      + subnet {
 +          + address_prefix = (known after apply)
 +          + id             = (known after apply)
 +          + name           = (known after apply)
 +          + security_group = (known after apply)
 +        }
 +    }
 +
 +Plan: 4 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.web_server_rg: Creating...
 +azurerm_resource_group.web_server_rg: Creation complete after 8s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_virtual_network.web_server_vnet: Creating...
 +azurerm_virtual_network.web_server_vnet: Still creating... [10s elapsed]
 +azurerm_virtual_network.web_server_vnet: Creation complete after 11s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +azurerm_subnet.web_server_subnet: Creating...
 +azurerm_subnet.web_server_subnet: Creation complete after 4s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet]
 +azurerm_network_interface.web_server_nic: Creating...
 +azurerm_network_interface.web_server_nic: Still creating... [10s elapsed]
 +azurerm_network_interface.web_server_nic: Creation complete after 11s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic]
 +
 +Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
 +</sxh>
 +
 +Now we can check if there is a new resource group into Azure Portal or we can check in the command line
 +<sxh bash>
 +az group list                                                                                    55.5s  Sat Apr  4 12:06:37 2020
 +[
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/NetworkWatcherRG",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "NetworkWatcherRG",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": null,
 +    "type": "Microsoft.Resources/resourceGroups"
 +  },
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "web-rg",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": {},
 +    "type": "Microsoft.Resources/resourceGroups"
 +  }
 +]
 +</sxh>
 +
 +Now let's list the VNET
 +<sxh bash>
 +az network vnet list                                                                            2279ms  Sat Apr  4 12:07:09 2020
 +[
 +  {
 +    "addressSpace": {
 +      "addressPrefixes": [
 +        "10.0.0.0/22"
 +      ]
 +    },
 +    "bgpCommunities": null,
 +    "ddosProtectionPlan": null,
 +    "dhcpOptions": {
 +      "dnsServers": []
 +    },
 +    "enableDdosProtection": false,
 +    "enableVmProtection": false,
 +    "etag": "W/\"c02bebd6-a1a2-4f17-adbc-fa6b80d5d8d5\"",
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet",
 +    "location": "westus2",
 +    "name": "web-server-vnet",
 +    "provisioningState": "Succeeded",
 +    "resourceGroup": "web-rg",
 +    "resourceGuid": "9d8309a8-6867-4f34-93b0-e82af625acd5",
 +    "subnets": [
 +      {
 +        "addressPrefix": "10.0.1.0/24",
 +        "addressPrefixes": null,
 +        "delegations": [],
 +        "etag": "W/\"c02bebd6-a1a2-4f17-adbc-fa6b80d5d8d5\"",
 +        "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet",
 +        "ipConfigurationProfiles": null,
 +        "ipConfigurations": [
 +          {
 +            "etag": null,
 +            "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic/ipConfigurations/web-01-ip",
 +            "name": null,
 +            "privateIpAddress": null,
 +            "privateIpAllocationMethod": null,
 +            "provisioningState": null,
 +            "publicIpAddress": null,
 +            "resourceGroup": "web-rg",
 +            "subnet": null
 +          }
 +        ],
 +        "name": "web-server-subnet",
 +        "natGateway": null,
 +        "networkSecurityGroup": null,
 +        "privateEndpointNetworkPolicies": "Enabled",
 +        "privateEndpoints": null,
 +        "privateLinkServiceNetworkPolicies": "Enabled",
 +        "provisioningState": "Succeeded",
 +        "purpose": null,
 +        "resourceGroup": "web-rg",
 +        "resourceNavigationLinks": null,
 +        "routeTable": null,
 +        "serviceAssociationLinks": null,
 +        "serviceEndpointPolicies": null,
 +        "serviceEndpoints": [],
 +        "type": "Microsoft.Network/virtualNetworks/subnets"
 +      }
 +    ],
 +    "tags": {},
 +    "type": "Microsoft.Network/virtualNetworks",
 +    "virtualNetworkPeerings": []
 +  }
 +]
 +</sxh>
 +
 +Now let's list the subnet that we've just created
 +<sxh bash>
 +az network vnet subnet list -g web-rg --vnet-name web-server-vnet                               1799ms  Sat Apr  4 12:07:47 2020
 +[
 +  {
 +    "addressPrefix": "10.0.1.0/24",
 +    "addressPrefixes": null,
 +    "delegations": [],
 +    "etag": "W/\"c02bebd6-a1a2-4f17-adbc-fa6b80d5d8d5\"",
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet",
 +    "ipConfigurationProfiles": null,
 +    "ipConfigurations": [
 +      {
 +        "etag": null,
 +        "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic/ipConfigurations/web-01-ip",
 +        "name": null,
 +        "privateIpAddress": null,
 +        "privateIpAllocationMethod": null,
 +        "provisioningState": null,
 +        "publicIpAddress": null,
 +        "resourceGroup": "web-rg",
 +        "subnet": null
 +      }
 +    ],
 +    "name": "web-server-subnet",
 +    "natGateway": null,
 +    "networkSecurityGroup": null,
 +    "privateEndpointNetworkPolicies": "Enabled",
 +    "privateEndpoints": null,
 +    "privateLinkServiceNetworkPolicies": "Enabled",
 +    "provisioningState": "Succeeded",
 +    "purpose": null,
 +    "resourceGroup": "web-rg",
 +    "resourceNavigationLinks": null,
 +    "routeTable": null,
 +    "serviceAssociationLinks": null,
 +    "serviceEndpointPolicies": null,
 +    "serviceEndpoints": [],
 +    "type": "Microsoft.Network/virtualNetworks/subnets"
 +  }
 +]
 +</sxh>
 +
 +Now Let's list the network Interface
 +<sxh bash>
 +az network nic list                                                                         1133ms  Sat Apr  4 12:16:13 2020
 +[
 +  {
 +    "dnsSettings": {
 +      "appliedDnsServers": [],
 +      "dnsServers": [],
 +      "internalDnsNameLabel": null,
 +      "internalDomainNameSuffix": "vaeyhhlhna0e5e3q3avpmjnm0f.xx.internal.cloudapp.net",
 +      "internalFqdn": null
 +    },
 +    "enableAcceleratedNetworking": false,
 +    "enableIpForwarding": false,
 +    "etag": "W/\"83c39a33-4a93-4f8a-a57b-3513dbd8f95a\"",
 +    "hostedWorkloads": [],
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic",
 +    "ipConfigurations": [
 +      {
 +        "applicationGatewayBackendAddressPools": null,
 +        "applicationSecurityGroups": null,
 +        "etag": "W/\"83c39a33-4a93-4f8a-a57b-3513dbd8f95a\"",
 +        "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic/ipConfigurations/web-01-ip",
 +        "loadBalancerBackendAddressPools": null,
 +        "loadBalancerInboundNatRules": null,
 +        "name": "web-01-ip",
 +        "primary": true,
 +        "privateIpAddress": "10.0.1.4",
 +        "privateIpAddressVersion": "IPv4",
 +        "privateIpAllocationMethod": "Dynamic",
 +        "privateLinkConnectionProperties": null,
 +        "provisioningState": "Succeeded",
 +        "publicIpAddress": null,
 +        "resourceGroup": "web-rg",
 +        "subnet": {
 +          "addressPrefix": null,
 +          "addressPrefixes": null,
 +          "delegations": null,
 +          "etag": null,
 +          "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet",
 +          "ipConfigurationProfiles": null,
 +          "ipConfigurations": null,
 +          "name": null,
 +          "natGateway": null,
 +          "networkSecurityGroup": null,
 +          "privateEndpointNetworkPolicies": null,
 +          "privateEndpoints": null,
 +          "privateLinkServiceNetworkPolicies": null,
 +          "provisioningState": null,
 +          "purpose": null,
 +          "resourceGroup": "web-rg",
 +          "resourceNavigationLinks": null,
 +          "routeTable": null,
 +          "serviceAssociationLinks": null,
 +          "serviceEndpointPolicies": null,
 +          "serviceEndpoints": null
 +        },
 +        "type": "Microsoft.Network/networkInterfaces/ipConfigurations",
 +        "virtualNetworkTaps": null
 +      }
 +    ],
 +    "location": "westus2",
 +    "macAddress": null,
 +    "name": "web-01-nic",
 +    "networkSecurityGroup": null,
 +    "primary": null,
 +    "privateEndpoint": null,
 +    "provisioningState": "Succeeded",
 +    "resourceGroup": "web-rg",
 +    "resourceGuid": "7f7c3993-8682-41c6-868a-87afaedb4618",
 +    "tags": {},
 +    "tapConfigurations": [],
 +    "type": "Microsoft.Network/networkInterfaces",
 +    "virtualMachine": null
 +  }
 +]
 +</sxh>
 +
 +As we can see there is a new resource group create by Terraform. Now let's destroy it to continue the configuration.
 +<sxh bash>
 +terraform destroy                                                                               1855ms  Sat Apr  4 12:17:05 2020
 +azurerm_resource_group.web_server_rg: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_virtual_network.web_server_vnet: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +azurerm_subnet.web_server_subnet: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet]
 +azurerm_network_interface.web_server_nic: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic]
 +
 +An execution plan has been generated and is shown below.
 +Resource actions are indicated with the following symbols:
 +  - destroy
 +
 +Terraform will perform the following actions:
 +
 +  # azurerm_network_interface.web_server_nic will be destroyed
 +  - resource "azurerm_network_interface" "web_server_nic" {
 +      - applied_dns_servers           = [] -> null
 +      - dns_servers                   = [] -> null
 +      - enable_accelerated_networking = false -> null
 +      - enable_ip_forwarding          = false -> null
 +      - id                            = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic" -> null
 +      - location                      = "westus2" -> null
 +      - name                          = "web-01-nic" -> null
 +      - private_ip_address            = "10.0.1.4" -> null
 +      - private_ip_addresses          = [
 +          - "10.0.1.4",
 +        ] -> null
 +      - resource_group_name           = "web-rg" -> null
 +      - tags                          = {} -> null
 +
 +      - ip_configuration {
 +          - application_gateway_backend_address_pools_ids = [] -> null
 +          - application_security_group_ids                = [] -> null
 +          - load_balancer_backend_address_pools_ids       = [] -> null
 +          - load_balancer_inbound_nat_rules_ids           = [] -> null
 +          - name                                          = "web-01-ip" -> null
 +          - primary                                       = true -> null
 +          - private_ip_address                            = "10.0.1.4" -> null
 +          - private_ip_address_allocation                 = "dynamic" -> null
 +          - private_ip_address_version                    = "IPv4" -> null
 +          - subnet_id                                     = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet" -> null
 +        }
 +    }
 +
 +  # azurerm_resource_group.web_server_rg will be destroyed
 +  - resource "azurerm_resource_group" "web_server_rg" {
 +      - id       = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg" -> null
 +      - location = "westus2" -> null
 +      - name     = "web-rg" -> null
 +      - tags     = {} -> null
 +    }
 +
 +  # azurerm_subnet.web_server_subnet will be destroyed
 +  - resource "azurerm_subnet" "web_server_subnet" {
 +      - address_prefix                                 = "10.0.1.0/24" -> null
 +      - enforce_private_link_endpoint_network_policies = false -> null
 +      - enforce_private_link_service_network_policies  = false -> null
 +      - id                                             = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet" -> null
 +      - ip_configurations                              = [
 +          - "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic/ipConfigurations/web-01-ip",
 +        ] -> null
 +      - name                                           = "web-server-subnet" -> null
 +      - resource_group_name                            = "web-rg" -> null
 +      - service_endpoints                              = [] -> null
 +      - virtual_network_name                           = "web-server-vnet" -> null
 +    }
 +
 +  # azurerm_virtual_network.web_server_vnet will be destroyed
 +  - resource "azurerm_virtual_network" "web_server_vnet" {
 +      - address_space       = [
 +          - "10.0.0.0/22",
 +        ] -> null
 +      - dns_servers         = [] -> null
 +      - id                  = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet" -> null
 +      - location            = "westus2" -> null
 +      - name                = "web-server-vnet" -> null
 +      - resource_group_name = "web-rg" -> null
 +      - tags                = {} -> null
 +
 +      - subnet {
 +          - address_prefix = "10.0.1.0/24" -> null
 +          - id             = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet" -> null
 +          - name           = "web-server-subnet" -> null
 +        }
 +    }
 +
 +Plan: 0 to add, 0 to change, 4 to destroy.
 +
 +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
 +
 +azurerm_network_interface.web_server_nic: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/networkInterfaces/web-01-nic]
 +azurerm_network_interface.web_server_nic: Destruction complete after 3s
 +azurerm_subnet.web_server_subnet: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet/subnets/web-server-subnet]
 +azurerm_subnet.web_server_subnet: Destruction complete after 3s
 +azurerm_virtual_network.web_server_vnet: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg/providers/Microsoft.Network/virtualNetworks/web-server-vnet]
 +azurerm_virtual_network.web_server_vnet: Destruction complete after 2s
 +azurerm_resource_group.web_server_rg: Destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 10s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 20s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 30s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 40s elapsed]
 +azurerm_resource_group.web_server_rg: Still destroying... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/web-rg, 50s elapsed]
 +azurerm_resource_group.web_server_rg: Destruction complete after 53s
 +
 +Destroy complete! Resources: 4 destroyed.
 +</sxh>
 +
 +
 +Let's list all the resource groups
 +<sxh bash>
 +az group list                                                                                       1m  Sat Apr  4 11:29:01 2020
 +[
 +  {
 +    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/NetworkWatcherRG",
 +    "location": "westus2",
 +    "managedBy": null,
 +    "name": "NetworkWatcherRG",
 +    "properties": {
 +      "provisioningState": "Succeeded"
 +    },
 +    "tags": null,
 +    "type": "Microsoft.Resources/resourceGroups"
 +  }
 +]
 +</sxh>
 +
 +Now we have only one resource group Called: **NetworkWatcherRG**, bellow the description about it.
 +
 +Network Watcher is a regional service that enables you to monitor and diagnose conditions at a network scenario level in, to, and from Azure. Scenario level monitoring enables you to diagnose problems at an end to end network level view. Network diagnostic and visualization tools available with Network Watcher help you understand, diagnose, and gain insights to your network in Azure. Network Watcher is enabled through the creation of a Network Watcher resource. This resource allows you to utilize Network Watcher capabilities.
 +
 +**Resources:**
 +  * [[https://docs.microsoft.com/en-us/cli/azure/network/vnet?view=azure-cli-latest|az network vnet]]
 +  * [[https://docs.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest|az group]]
 +  * [[https://docs.microsoft.com/en-us/cli/azure/network/nic?view=azure-cli-latest#az-network-nic-list|az network nic]]
 +  * [[https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-create|Azure Network Watcher instance]]
  
Print/export
QR Code
QR Code azure_terraform_getting_started (generated for current page)