what is the 'availability_zone' argument in terraform for azure? - terraform-provider-azure

I'm trying to create a Virtual network in Azure with a NAT gateway, using terraform.
I'm getting the following warning when I run terraform plan :
Warning: Argument is deprecated
│
│ with azurerm_public_ip.example2,
│ on PublicIPandNAT.tf line 16, in resource "azurerm_public_ip" "example2":
│ 16: zones = ["1"]
│
│ This property has been deprecated in favour of `availability_zone` due to a breaking behavioural change in Azure:
│ https://azure.microsoft.com/en-us/updates/zone-behavior-change/
│
│ (and one more similar warning elsewhere)
╵
Do you want to perform these actions?
But in the azurerm provider documentation on registry.terraform.io, there is no reference to a availability_zone argument in the azurerm_public_ip resource.
Is the terraform documentation out of date? what is the syntax of the availability_zone argument? and what is the risk of using the zones argument?

Trying to create a Virtual network in Azure with a NAT gateway, using
terraform.
To create Virtual network with NAT Gateway using terraform, we have tried at our end with following code and it works fine without any error.
You can use the below code to do the same by adding your required name :-
main.tf:-
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "nat-gateway-example-rg"
location = "West Europe"
}
resource "azurerm_public_ip" "example" {
name = "nat-gateway-publicIP"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
allocation_method = "Static"
sku = "Standard"
zones = ["1"]
}
resource "azurerm_virtual_network" "example" {
name = "example-network"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
address_space = ["10.0.0.0/16"]
dns_servers = ["10.0.0.4", "10.0.0.5"]
}
resource "azurerm_public_ip_prefix" "example" {
name = "nat-gateway-publicIPPrefix"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
prefix_length = 30
zones = ["1"]
}
resource "azurerm_nat_gateway" "example" {
name = "nat-Gateway"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku_name = "Standard"
idle_timeout_in_minutes = 10
zones = ["1"]
}
OUTPUT DETAILS:-
My terraform version :-
what is the syntax of the availability_zone argument? and what is the
risk of using the zones argument?
AFAIK, there is no risk of use availability zone and you can find the reference in aforementioned code .
For more information please refer this HashiCorp| azurerm_nat_gateway

Related

Prevent a Terraform resource with for_each from being created depending on a condition

I'm using the following resources to create a DynamoDB table with items from a JSON file of objects.
module "dynamodb_label" {
source = "./modules/labels"
enabled = var.ENABLE_TABLE
name = var.dynamodb_name
context = module.this.context
}
locals {
json_data = file("./items.json")
items = jsondecode(local.json_data)
}
module "dynamodb_table" {
source = "./aws-dynamodb"
count = var.ENABLE_TABLE ? 1 : 0
hash_key = "schema"
hash_key_type = "S"
autoscale_write_target = 50
autoscale_read_target = 50
autoscale_min_read_capacity = 5
autoscale_max_read_capacity = 1000
autoscale_min_write_capacity = 5
autoscale_max_write_capacity = 1000
enable_autoscaler = true
enable_encryption = true
enable_point_in_time_recovery = true
ttl_enabled = false
dynamodb_attributes = [
{
name = "schema"
type = "S"
}
]
context = module.dynamodb_label.context
}
resource "aws_dynamodb_table_item" "dynamodb_table_item" {
for_each = var.ENABLE_TABLE ? local.items : {}
table_name = module.dynamodb_table.table_name
hash_key = "schema"
item = jsonencode(each.value)
depends_on = [module.dynamodb_table]
}
The JSON file
{
"Item1": {
"schema": {
"S": "https://schema.org/government-documents#id-card"
},
"properties": {
"S": "{\"documentName\":{\"type\":\"string\"},\"dateOfBirth\":{\"type\":\"string\"}}"
}
},
"Item2": {
"schema": {
"S": "https://schema.org/government-documents#drivers-license"
},
"properties": {
"S": "{\"documentName\":{\"type\":\"string\"},\"dateOfBirth\":{\"type\":\"string\"}}"
}
}
}
I'm getting the following error
Error: Inconsistent conditional result types
on dynamodb-table.tf line 173, in resource "aws_dynamodb_table_item" "dynamodb_table_item":
173: for_each = var.ENABLE_TABLE ? local.items : {}
├────────────────
│ local.items is object with 13 attributes
│ var.ENABLE_TABLE is a bool, known only after apply
The true and false result expressions must have consistent types. The given expressions are object and object, respectively.
I've tried many options to pass this error even change the variable type from bool to object. If I remove the condition in for_each and just pass local.items the aws_dynamodb_table_item tries to create regardless of the depends_on and it fails of course to create because table_name is returned empty because of count = module.dynamodb_label.enabled ? 1 : 0 in dynamodb_table module
I want the aws_dynamodb_table_item to be skipped if var.ENABLE_TABLE is set to false
What am I missing here? Any hint is highly appreciated.
EDIT: Tried the following so far all with same error;
for_each = var.ENABLE_TABLE == true ? local.schemas : {}
for_each = var.ENABLE_TABLE ? local.items : {}
Maybe you can try this:
resource "aws_dynamodb_table_item" "dynamodb_table_item" {
for_each = var.ENABLE_TABLE : local.items ? {}
table_name = module.dynamodb_table.table_name
hash_key = "schema"
item = jsonencode(local.for_each)
depends_on = [module.dynamodb_table]
}
EDIT: in this case the variable var.ENABLE_TABLE must be boolean.
After experimenting for 2 days around different types of expressions to get around this issue a kind sir on Reddit referred to this solution and it worked like a charm;
for_each = { for k,v in local.items : k => v if var.ENABLE_TABLE }
For anyone with a similar requirement this seems a gem that I have missed and recommend you to use it.
The true and false result expressions must have consistent types. The given expressions are object and object, respectively.
I think I found what's the issue is
You should've used jsondecode but used jsonencode instead.
locals {
json_data = file("./items.json")
items = jsondecode(local.json_data)
}
Secondly I run into this issue
╷
│ Error: Incorrect attribute value type
│
│ on main.tf line 14, in resource "aws_dynamodb_table_item" "dynamodb_table_item":
│ 14: item = each.value
│ ├────────────────
│ │ each.value is object with 2 attributes
│
│ Inappropriate value for attribute "item": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│ on main.tf line 14, in resource "aws_dynamodb_table_item" "dynamodb_table_item":
│ 14: item = each.value
│ ├────────────────
│ │ each.value is object with 2 attributes
│
│ Inappropriate value for attribute "item": string required.
For that I used this
resource "aws_dynamodb_table_item" "dynamodb_table_item" {
for_each = var.ENABLE_TABLE ? local.items : {}
table_name = module.dynamodb_table.table_name
hash_key = "schema"
item = each.value.properties.S
depends_on = [module.dynamodb_table]
}
Hope this helps you debug.

Error: "zone": conflicts with availability_set_id - Azure - Terraform

We have some Linux clusters (two machines each) running on Azure and we would like that each node of the cluster be created in different zones and using availability set.
We are trying to create the VM on Azure using Terraform:
resource "azurerm_linux_virtual_machine" "move-az-test" {
count = "1"
name = "move-az-test01"
location = var.azure_location_short
resource_group_name = azurerm_resource_group.rg.name
size = "Standard_B1S"
zone = 1
computer_name = "move-az01"
disable_password_authentication = true
admin_username = var.os_user
admin_password = var.os_password
availability_set_id = azurerm_availability_set.avset.id
network_interface_ids = [azurerm_network_interface.move-az-nic.id]
source_image_reference {
publisher = "OpenLogic"
offer = "CentOS"
sku = "7.6"
version = "latest"
}
os_disk {
name = "move-az-test0_OsDisk"
caching = "ReadWrite"
disk_size_gb = "128"
storage_account_type = "Standard_LRS"
}
}
But we have the message error: Error: "zone": conflicts with availability_set_id
The short answer is that the availability set and the availability zone can't exist at the same time. You can take deeper learning about them. The former is in a logical grouping of the VMs and the latter improves the availability on the physical regions.

terraform azurerm_scheduled_query_rules_log

Hi I'm running terraform
Terraform v0.13.4
provider registry.terraform.io/hashicorp/azurerm v2.41.0
I'm trying to set up azure metric monitoring for vm
resource "azurerm_scheduled_query_rules_log" "scheduled_rules" {
for_each = local.alert_rules
name = "${var.client_initial}-${each.key}"
location = var.resource_group_name.location
resource_group_name = var.resource_group_name
criteria {
metric_name = each.value.metric_name
dimension {
name = "Computer"
operator = "Include"
values = var.virtual_machines
}
}
data_source_id = var.log_analytics_workspace_ID
description = each.value.description
enabled = true
}
However when i run plan, it tells me
53: resource "azurerm_scheduled_query_rules_log" "scheduled_rules" {
The provider provider.azurerm does not support resource type
"azurerm_scheduled_query_rules_log".
I see this new resource is introduced in azurerm 2.1, not sure why it's not available on 2.41.0?
I also face the same error. It should be the resource azurerm_monitor_scheduled_query_rules_log instead of azurerm_scheduled_query_rules_log. There might be some mistakes or do not update in the terraform Example Usage.
Here is a working example with Terraform v0.14.3 + azurerm v2.41.0
# Example: LogToMetric Action for the named Computer
resource "azurerm_monitor_scheduled_query_rules_log" "example" {
name = format("%s-queryrule", "some")
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
criteria {
metric_name = "Average_% Idle Time"
dimension {
name = "Computer"
operator = "Include"
values = ["targetVM"]
}
}
data_source_id = azurerm_log_analytics_workspace.example.id
description = "Scheduled query rule LogToMetric example"
enabled = true
}

Issues in passing key vault secrets to the Data.tf and referencing in Main.tf

I have created multiple key vault secrets in the Azure portal and trying pass them in terraform Data.tf. But i am not sure how to pass multiple secrets and refer in the main.tf. Can someone help on this.
My requirement is to pass multiple values in the Name attribute and refer in Main.tf
data.tf
data "azurerm_key_vault" "key_vault" {
name = "test-key-vault-cts"
resource_group_name = "gcdmvrlyprd03-30cf06a8"
}
data "azurerm_key_vault_secret" "admin_password" {
name = "admin-password"
key_vault_id = data.azurerm_key_vault.key_vault.id
}
Main.tf
module "location_us-west" {
source = "./Modules"
web_server_location = "westus2"
web_server_rg = "${var.web_server_rg}-us-west"
resource_prefix = "${var.resource_prefix}-us-west"
web_server_address_space = "10.0.0.0/22"
#web_server_address_prefix = "10.0.1.0/24"
web_server_name = var.web_server_name
environment = var.environment
size = var.vm_size
admin_user = var.user
admin_password = data.azurerm_key_vault_secret.admin_password.value
web_server_count = var.web_server_count
web_server_subnets = {
"web-server" = "10.0.1.0/24"
"AzureBastionSubnet" = "10.0.2.0/24"
}
}
If you want to reference a second secret via data, create a second block of code.
data "azurerm_key_vault_secret" "admin_password2" {
name = "admin-password2"
key_vault_id = data.azurerm_key_vault.key_vault.id
}
In my opinion, you can put the data sources together with the module location_us-west in the main.tf file. So that you can quote the data.azurerm_key_vault_secret.admin_password.value directly. I don't recommend you desperate the data sources from the main.tf file if you just want to quote the secrets without any other actions.
And for the secrets, you need to put the names for multiple secrets to get them from the Key vault. So if you want to get multiple secrets only one time, you can change the code like this example:
variable "secret_names" {
type = list
default = [
"test1",
"test2"
]
}
data "azurerm_key_vault" "example" {
name = "key_vault_name"
resource_group_name = "group_name"
}
data "azurerm_key_vault_secret" "example" {
count = length(var.secret_names)
name = element(var.secret_names, count.index)
key_vault_id = data.azurerm_key_vault.example.id
}
Then the output data.azurerm_key_vault_secret.example.*.value will contain all the secret values in a list.

Need more detail on how to deploy an Azure IaaS into a specific Availability Zone?

Need more detail on how to create a resource for placing an IaaS into an specific availability zone during azurerm terraform deployment?
https://www.terraform.io/docs/providers/azurerm/r/virtual_machine.html#zones
This link does not give me enough detail on how to write the option of choosing a specific availability zone for a VM that will be deployed using azure terraform.
zones  - (Optional) A list of a single item of the Availability Zone which the Virtual Machine should be allocated in.
The documentation is saying that you need a terraform list with a single item which is the zone that you want the VM created. Here is what that looks like for East US using Zone 1.
resource "azurerm_virtual_machine" "main" {
name = "${var.prefix}-vm"
location = "${azurerm_resource_group.main.location}"
resource_group_name = "${azurerm_resource_group.main.name}"
network_interface_ids = ["${azurerm_network_interface.main.id}"]
vm_size = "Standard_DS1_v2"
# Zone info
zones = [1]
storage_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
storage_os_disk {
name = "myosdisk1"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "hostname"
admin_username = "testadmin"
admin_password = "Password1234!"
}
os_profile_linux_config {
disable_password_authentication = false
}
tags = {
environment = "staging"
}
}

Resources