Terraform azure Incompatible provider version - terraform

When i'm trying to initialize terraform, i'm getting following error only with vnet module,
But terraform initilization working with azure_resource_group, azure_virtual_machine modules
Terraform 0.13 and earlier allowed provider version constraints inside the
provider configuration block, but that is now deprecated and will be removed
in a future version of Terraform. To silence this warning, move the provider
version constraint into the required_providers block.
Error: Failed to query available provider packages
Could not retrieve the list of available versions for provider
hashicorp/azure: provider registry registry.terraform.io does not have a
provider named registry.terraform.io/hashicorp/azure
If you have just upgraded directly from Terraform v0.12 to Terraform v0.14
then please upgrade to Terraform v0.13 first and follow the upgrade guide for
that release, which might help you address this problem.
Did you intend to use terraform-providers/azure? If so, you must specify that
source address in each module which requires that provider. To see which
modules are currently depending on hashicorp/azure,
enter image description here
enter image description here
main.tf
resource "azurerm_virtual_network" "vnet" {
for_each = { for n in var.networks : n.name => n }
name = each.value.name
address_space = each.value.address_space
location = each.value.location
resource_group_name = each.value.rg_name
dynamic "subnet" {
for_each = each.value.subnets
content {
name = subnet.value.name
address_prefix = subnet.value.address_prefixes
}
}
}
variables.tf
variable networks {
type = list(object({
name = string
address_space = list(string)
rg_name = string
location = string
subnets = list(object({
name = string
address_prefixes = string
}))
}))
}
module (main.tf)
module "azurevnet"{
source = "./vnet"
networks = var.networks
}
provider.tf
provider "azurerm" {
version = "=2.37.0"
}

As I know, the registry terraform-providers/azure is a deprecated provider. This model will not add new things anymore and Azure already change into ARM model. So I recommend you use the terraform-providers/azurerm model only and it supports more Azure features.
Update:
And use the azurerm model, the directory structure would look like this:
main.tf
module "azurevnet" {
source = "./vnet"
networks = var.networks
}
providers.tf
provider "azurerm" {
features {}
version = "=2.37.0"
}
vnet/main.tf
variable "networks" {}
resource "azurerm_virtual_network" "vnet" {
for_each = { for n in var.networks : n.name => n }
name = each.value.name
address_space = each.value.address_space
location = each.value.location
resource_group_name = each.value.rg_name
dynamic "subnet" {
for_each = each.value.subnets
content {
name = subnet.value.name
address_prefix = subnet.value.address_prefixes
}
}
}
I only give the code for VNet, but other resources will be in the same format. And you can also do not use the providers.tf file and put the content into the main.tf file.

Related

Terraform returning the path of Azure Resource Group instead of ID

I'm using Terraform to manage my Infrastructure and Terratest for Testing.
In terraform, I have a module called ResourceGroup (located in the Modules folder)
resource "azurerm_resource_group" "azResourceGroup" {
name = var.resource_group_name
location = var.resource_region
tags = var.tags
}
output "resource_group_name" {
value = azurerm_resource_group.azResourceGroup.id
}
And I'm using this module in the main.tf to create an Azure Resource Group.
module "azResourceGroup" {
source = "./Modules/ResourceGroup"
resource_group_name = var.resource_group_name
tags = var.tags
}
output "resource_group_name" {
value = "${module.azResourceGroup.resource_group_name}"
}
When I execute terraform apply the output of main.tf is returning the full path of the newly created Resource Group instead of its ID.
Here's the Output
Changes to Outputs:
- resource_group_name = "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-x/resourceGroups/rg-svf-nprd-test" -> null
Preferably, it should return only rg-svf-nprd-test (Id from output variable).
Am I missing anything here? Please help me with this.

Terraform source error - Error: Failed to query available provider packages

I am trying to deploy a new infrastructure using terraform (for the first time) and I am getting the following error. I've tried everything but nothing seems to fix the issue.
Looks like it is asking for a provider hashicorp/azure ?
Can anyone help please??
Initializing provider plugins...
- Finding latest version of hashicorp/azure...
- Finding hashicorp/azurerm versions matching "2.98.0"...
- Installing hashicorp/azurerm v2.98.0...
- Installed hashicorp/azurerm v2.98.0 (signed by HashiCorp)
╷
│ Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider hashicorp/azure: provider registry registry.terraform.io does not have a provider named registry.terraform.io/hashicorp/azure
│
│ Did you intend to use terraform-providers/azure? If so, you must specify that source address in each module which requires that provider. To see which modules are currently depending on hashicorp/azure, run the following command:
│ terraform providers
╵
lucas#Azure:~$ terraform providers
Providers required by configuration:
.
├── provider[registry.terraform.io/hashicorp/azurerm] 2.98.0
└── provider[registry.terraform.io/hashicorp/azure]
The code that I am using to create the infrastructure is the below:
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=2.98.0"
}
}
}
provider "azurerm" {
features {}
subscription_id = "910910be-a61e-4e1f-a72a-7e43456c0836"
}
# Create a resource group
resource "azurerm_resource_group" "rg" {
name = "default"
location = "West Europe"
}
# Create a virtual network
resource "azurerm_virtual_network" "vpc" {
name = "default-network"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
address_space = ["10.0.0.0/16"]
}
# Create frontend subnet
resource "azurerm_subnet" "subnet_frontend" {
name = "internal"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vpc.name
address_prefixes = ["10.0.1.0/24"]
}
# Create backend subnet
resource "azurerm_subnet" "subnet_backend" {
name = "internal"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vpc.name
address_prefixes = ["10.0.2.0/24"]
}
# Create frontend network interface
resource "azurerm_network_interface" "frontend_nic" {
name = "frontend_nic"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.subnet_frontend.id
private_ip_address_allocation = "Dynamic"
}
}
# Create backend network interface
resource "azurerm_network_interface" "backend_nic" {
name = "backend_nic"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.subnet_backend.id
private_ip_address_allocation = "Dynamic"
}
}
# Create frontend VM based on module
resource "azure_instance" "frontend" {
source = "./vm"
name = "frontend"
rg = module.azurerm_resource_group.rg.name
location = module.azurerm_resource_group.rg.location
nic = module.azurerm_network_interface.frontend_nic
}
# Create backend VM based on module
resource "azure_instance" "backend" {
source = "./vm"
name = "backend"
rg = module.azurerm_resource_group.rg.name
location = module.azurerm_resource_group.rg.location
nic = module.azurerm_network_interface.backend_nic
}
My terraform version is: Terraform v1.1.5 and I am using on Azure CLI via bash.
Any idea of what is causing this issue and how to fix it?
Thanks!
This often happens when one accidentally specifies "hashicorp/azure" or "hashicorp/azurem" instead of "hashicorp/azurerm" in the required_providers block. Did you check the "vm" module referenced in the "azure_instance" module calls? There might be an erroneous "hashicorp/azure" specified there.

Terraform Error : If multiple configurations are required, set the "alias" argument for alternative configurations [provider-azure]

Here im trying to add resources in azure portal in Terraform
I've tried setting alias but right after I made some changes in configuration file and I run terraform init command it throws an error like this
can anyone help me with this as I am newly working with Terraform and azure
NOTE: This is the error message I am getting
DUPLICATE PROVIDER CONFIGURATION
A DEFAULT (NON-ALIASED) PROVIDER CONFIGURATION FOR AZURERM WAS ALREADY
GIVEN AT MAIN.TF 12,1-19 . IF MULTIPLE CONFIGURATIONS ARE REQUIRED SET
THE "ALIAS" ARGUMENT FOR ALTERNATIVE CONFIGURATION.
As you have already initialized terraform provider and azurerm provider in above . Again initializing it will error out with duplicate provider configuration.
So Please remove this block:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 2.74"
}
}
required_version = ">= 0.14.9"
}
And you can use directly the below:
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "RG" {
name = "myRG"
location = "WestUS2"
}
resource "azurerm_virtual_network" "vnet" {
name = "myvnet"
location = azurerm_resource_group.RG.location
resource_group_name = azurerm_resource_group.RG.name
address_space = ["10.0.0.0/16"]
}

Terraform tried creating a "implicit dependency" but the next stage of my code still fails to find the Azure resource group just created

Would be grateful for any assistance, I thought I had nailed this one when I stumbled across the following link ...
Creating a resource group with terraform in azure: Cannot find resource group directly after creating it
However, the next stage of my code is still failing...
Error: Code="ResourceGroupNotFound" Message="Resource group 'ShowTell' could not be found
# We strongly recommend using the required_providers block to set the
# Azure Provider source and version being used
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=2.64.0"
}
}
}
# Configure the Microsoft Azure Provider
provider "azurerm" {
features {}
}
variable "resource_group_name" {
type = string
default = "ShowTell"
description = ""
}
# Create your resource group
resource "azurerm_resource_group" "example" {
name = var.resource_group_name
location = "UK South"
}
# Should be accessible from LukesContainer.uksouth.azurecontainer.io
resource "azurerm_container_group" "LukesContainer" {
name = "LukesContainer"
location = "UK South"
resource_group_name = "${var.resource_group_name}"
ip_address_type = "public"
dns_name_label = "LukesContainer"
os_type = "Linux"
container {
name = "hello-world"
image = "microsoft/aci-helloworld:latest"
cpu = "0.5"
memory = "1.5"
ports {
port = "443"
protocol = "TCP"
}
}
container {
name = "sidecar"
image = "microsoft/aci-tutorial-sidecar"
cpu = "0.5"
memory = "1.5"
}
tags = {
environment = "testing"
}
}
In order to create an implicit dependency you must refer directly to the object that the dependency relates to. In your case, that means deriving the resource group name from the resource group object itself, rather than from the variable you'd used to configure that object:
resource "azurerm_container_group" "LukesContainer" {
name = "LukesContainer"
location = "UK South"
resource_group_name = azurerm_resource_group.example.name
# ...
}
With the configuration you included in your question, both the resource group and the container group depend on var.resource_group_name but there was no dependency between azurerm_container_group.LukesContainer and azurerm_resource_group.example, and so Terraform is therefore free to create those two objects in either order.
By deriving the container group's resource group name from the resource group object you tell Terraform that the resource group must be processed first, and then its results used to populate the container group.

Terraform 0.13 - Modules, for_each and providers

UPDATED
I am trying to provision multiple SQL databases in Azure using Terraform.
My child module has the following code that provisions a SQL database:
providers.tf
// default provider
provider "azurerm" {
alias = "main"
features {}
}
// The provider that can access the storage account to store diagnostics
provider "azurerm" {
alias = "storage_account"
features {}
}
sql_db.tf
resource "azurerm_mssql_database" "default" {
name = var.name
base_name = var.base_name
...
tags = var.tags
provider = azurerm.main
}
data.tf
data "azurerm_storage_account" "storage" {
name = var.storage_account_name
resource_group_name = var.storage_account_rg
provider = azurerm.storage_account
}
I am calling this module in my main.tf file as follows where I want to provision multiple SQL databases using a for_each:
module "sql_db" {
for_each = var.sql_db
source = "...../sql_db.git"
base_name = each.value.base_name
name = each.value.name
providers = {
azurerm.main = azurerm.main
azurerm.storage_account = azurerm.storage_account
}
}
provider "azurerm" {
features {}
version = "=2.20.0"
}
// default provider
provider "azurerm" {
alias = "main"
features {}
}
provider "azurerm" {
alias = "storage_account"
features {}
}
When I run plan, I get the following error:
Error: Module does not support for_each
on main.tf line 35, in module "sql_db":
35: for_each = var.sql_db
Module "sql_db" cannot be used with for_each because it contains a nested
provider configuration for "azurerm.main", at
.terraform\modules\sql_db\providers.tf:2,10-19.
This module can be made compatible with for_each by changing it to receive all
of its provider configurations from the calling module, by using the
"providers" argument in the calling module block.
Error: Module does not support for_each
on main.tf line 35, in module "sql_db":
35: for_each = var.sql_db
Module "sql_db" cannot be used with for_each because it contains a nested
provider configuration for "azurerm.storage_account", at
.terraform\modules\sql_db\providers.tf:8,10-19.
This module can be made compatible with for_each by changing it to receive all
of its provider configurations from the calling module, by using the
"providers" argument in the calling module block.
The simple answer is, it's not supported. From the Terraform documentation:
A module containing its own provider configurations is not compatible with the for_each, count, and depends_on arguments that were introduced in Terraform v0.13.
HashiCorp has been absolutely adamant that providers can never be declared dynamically, which is why they allow neither a for_each/count within a provider block, nor a for_each/count on a module that contains a provider block.

Resources