I want to create a resource group in Azure with the help of Terraform and while creating it, I want to follow a naming convention.
Let's say, I have created a resource group rg-dev-001 with the help of terraform. And if I run the terraform script again next time then It should create rg-dev-002. How can I achieve it in terraform?
resource "azurerm_resource_group" "example" {
name = "rg-dev-xxx"
location = "West Europe"
}
Please use the below code to create resource groups in sequence in Terraform :
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "rg" {
count = number of resource groups to be created
name = "rg-dev-00${count.index+1}"
location = "LocationName"
}
Related
Context
Trying to understand how is working feature prevent_deletion_if_contains_resources in AzureRm on Terraform:
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = true
}
}
}
The documentation:
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/features-block#resource_group
Says:
Should the azurerm_resource_group resource check that there are no
Resources within the Resource Group during deletion? This means that
all Resources within the Resource Group must be deleted prior to
deleting the Resource Group. Defaults to true.
My issue
Whatever the value of prevent_deletion_if_contains_resources this never happens.
Terraform destroy work as fine
I can delete the Resource Group from the portal
What I did
This is the full script:
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = true
}
}
}
provider "azurerm" {
alias = "autreChoix"
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "rg2" {
name = "rg2"
location = "northeurope"
provider = azurerm.autreChoix
}
resource "azurerm_resource_group" "rg" {
name = "rg1"
location = "westeurope"
}
resource "azurerm_storage_account" "sa" {
name = "mystor1"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_storage_account" "sa2" {
name = "mystor2"
resource_group_name = azurerm_resource_group.rg2.name
location = azurerm_resource_group.rg2.location
account_tier = "Standard"
account_replication_type = "LRS"
}
Creates 2 RG. On with each value of prevent_deletion_if_contains_resources.
What I need
Does anybody tells me what I am missing?
Thanks
The main problem prevent_deletion_if_contains_resources solves is throwing a warning to the Terraform user when there are additional Resources within a Resource Group that it is trying to remove that it does not manage, since those Resources will also be deleted when the Resource Group is deleted by Terraform.
Here is the original issue: https://github.com/hashicorp/terraform-provider-azurerm/issues/1608, and later the default behavior in the provider was changed to be true as a result of this other issue: https://github.com/hashicorp/terraform-provider-azurerm/issues/13777.
That setting only applies to using Terraform. It does not prevent users in the Azure portal from deleting the Resource Group. However, I suspect that if you create the Resource Group using Terraform, then add a new Resource within that Resource Group using the Azure portal, and then finally perform a terraform destroy on that Resource Group, you should see an Terraform error if you have prevent_deletion_if_contains_resources set to true.
I have deployed resources on Microsoft Azure using terraform. I'm using azure storage account container to save my terraform states. I tried to configure terraform cloud to automate the deployment but I get this error.
Error: A resource with the ID "/subscriptions/{SUBSCRIPTION_ID}/resourceGroups/msk-stage-keyvault" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_resource_group" for more information.
with module.keyvault.azurerm_resource_group.msk-keyvault
on ../../modules/az-keyvault/main.tf line 2, in resource "azurerm_resource_group" "msk-keyvault":
resource "azurerm_resource_group" "msk-keyvault" {
It seems that terraform cloud is not using my backend state in my provider.tf. How do I make terraform cloud use my backend state in provider.tf.
My Backend Provider
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=2.91.0"
}
}
backend "azurerm" {
resource_group_name = "msk-configurations"
storage_account_name = "mskconfigurations"
container_name = "key-vault"
key = "stage.tfstate"
}
}
provider "azurerm" {
features {}
subscription_id = var.subscription
tenant_id = var.ternant_id
}
It looks like your main.tf has already existing keyvault state.
So Initially please check if you have already configured keyvault resource in main.tf file or if you have already imported the state.
If its already present in main.tf file , and if you are again giving it in the backend , please try to remove the one from main.tf file and then execute again.
Also please note that terraform backend needs azure storage account credentials before hand in order to store into the tfstate.
So please avoid creating storage simultaneously all account, container and then the keyvault resource to tfstate.
So if storage account is already created first , then terraform can refer it later in backend.
To preconfigure the storage account and container :
Example:
1. Create storage account and container one after the other instead in the same file:
provider "azurerm" {
features {}
}
data "azurerm_resource_group" "example" {
name = "resourcegroupname"
}
resource "azurerm_storage_account" "example" {
name = "<yourstorageaccountname>"
resource_group_name = data.azurerm_resource_group.example.name
location = data.azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_storage_container" "example" {
name = "newterraformcont"
storage_account_name = azurerm_storage_account.example.name
container_access_type = "private"
}
Then create the msk-keyvault resource group and store the tfstate in container.
This is my already created state file in terraform (terraform.tf)
provider "azurerm" {
features {}
}
terraform {
# Configure Terraform State Storage
backend "azurerm" {
resource_group_name = "<resourcegroup>"
storage_account_name = "<storage-earliercreated>"
container_name = " newterraformcont "
key = "terraform.tfstate"
}
}
resource "azurerm_resource_group" " msk-keyvault" {
name = "<msk-keyvault>"
location = "west us"
}
Reference:
azurerm_resource_group | Resources | hashicorp/azurerm | Terraform
Registry
https://www.jorgebernhardt.com/terraform-backend
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"]
}
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.
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.