Terraform Azure database module - unknown resource - azure

trying to use the database module from: https://registry.terraform.io/modules/Azure/database/azurerm/1.0.1
i have made objects in Azure from my workstation, so the basics are all in place.
I copied the main / variables / outputs files to a folder (sql) and then used the example (below) to call it.
# Configure the Azure Provider
provider "azurerm" {}
module "sql-database" {
source = "./sql"
resource_group_name = "myapp"
location = "westus"
db_name = "mydatabase"
sql_admin_username = "mradministrator"
sql_password = "P#ssw0rd12345!"
tags = {
environment = "dev"
costcenter = "it"
}
}
When i run terraform init, i get the below error, any idea what im doing wrong?
PS C:\GITHUB\terraform_azure\app> terraform init
Initializing modules...
- module.sql-database
Error getting plugins: 9 problems:
- output 'sql_server_name': unknown resource 'azurerm_sql_server.server'
referenced in variable azurerm_sql_server.server.name
- output 'sql_server_location': unknown resource 'azurerm_sql_server.server'
referenced in variable azurerm_sql_server.server.location
- output 'sql_server_version': unknown resource 'azurerm_sql_server.server'
referenced in variable azurerm_sql_server.server.version
- output 'sql_server_fqdn': unknown resource 'azurerm_sql_server.server'
referenced in variable azurerm_sql_server.server.fully_qualified_domain_name
- output 'connection_string': unknown resource 'azurerm_sql_server.server'
referenced in variable azurerm_sql_server.server.administrator_login_password
- output 'connection_string': unknown resource 'azurerm_sql_server.server'
referenced in variable azurerm_sql_server.server.fully_qualified_domain_name
- output 'connection_string': unknown resource 'azurerm_sql_database.db'
referenced in variable azurerm_sql_database.db.name
- output 'connection_string': unknown resource 'azurerm_sql_server.server'
referenced in variable azurerm_sql_server.server.administrator_login
- output 'database_name': unknown resource 'azurerm_sql_database.db'
referenced in variable azurerm_sql_database.db.name

# Configure the Azure Provider
provider "azurerm" {}
module "sql-database" {
version = "1.0.1"
source = "./sql"
resource_group_name = "myapp"
location = "westus"
db_name = "mydatabase"
sql_admin_username = "mradministrator"
sql_password = "P#ssw0rd12345!"
tags = {
environment = "dev"
costcenter = "it"
}
}
Updated the main file to above and it worked (AKA I added the version number.. Not sure why that made it work! I dont see anything in the database Main file saying anything about version.. but that got it the init completing!

Related

Using azure azurerm_resource_provider_registration with newly created subscription

I am working on creating Azure landing zone and part of that is to enable/disable resource providers on the newly created subscriptions.
I have tried to used alias with a variable but i am getting error that i cant use variable in an alias so is there any way through which i can use this feature on multiple subscription
This is my code main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.0.0"
}
}
}
#list of providers i want to register
locals {
# List is compiled from here
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-services-resource-providers
provider_list = [
"Microsoft.Storage"
]
provider_map = { for p in local.provider_list : p => p }
}
# Registering a default provider here and skipping registration
# as i will do it later
provider "azurerm" {
features {}
skip_provider_registration = true
}
# I am creating a subscription here with same alias as the name
# the subscription is being created under and EA enrollment but
# any type of subscription will do
resource "azurerm_subscription" "feature_subscription" {
billing_scope_id = "/providers/Microsoft.Billing/billingAccounts/xxx/enrollmentAccounts/xx"
alias = var.temp_alias # "test-provider-registration"
subscription_name = "test-provider-registration"
}
#this is what i have created to point out my azurerm_resource_provider_registration
#module i am using variable in alias which is failing
provider "azurerm" {
alias = var.temp_alias
subscription_id = azurerm_subscription.feature_subscription.id
features {
}
skip_provider_registration = true
}
#module through which i am registering the resource providers
module "azurerm_resource_provider_registration-provider" {
source = "../modules/azurerm_resource_provider_registration"
providers = {
azurerm = azurerm.test-provider-registration
}
feature_list = local.provider_map
}
#the module code is mentioned here
#resource "azurerm_resource_provider_registration" "provider" {
# for_each = var.feature_list
# name = each.value
#}
I am getting this error when i run it
There are some problems with the configuration, described below.
The Terraform configuration must be valid before initialization so that
Terraform can determine which modules and providers need to be installed.
╷
Error: Variables not allowed
│
On main.tf line 25: Variables may not be used here.
╵
╷
Error: Unsuitable value type
│
On main.tf line 25: Unsuitable value: value must be known
There is a workaround available like using this
resource "null_resource" "provider_registration" {
for_each = local.provider_map
provisioner "local-exec" {
command = "az account set --subscription ${data.azurerm_subscription.subscription.subscription_id} && az provider register --namespace ${each.value}"
}
}
but i want to use the state file for the resource registration if possible as i have more subscriptions in a loop
Error: Unsuitable value type | Unsuitable value: value must be known
Need to check:
This problem usually occurs with module sources or versions. When invoking a module, using variables instead of passing direct values for the source and some other arguments causes this error. terraform initdoesn't take variable inputs with modules in backend state configuration.
Note: And also include required version for modules.
To make it work, use direct values for module block instead of accessing from other resources.
Pass provider explicitly to make it work as detailed in terraform providers.
providers = {
azurerm = azurerm.test-provider-registration
}
feature_list = local.provider_map
}
}
module "azurerm_resource_provider_registration-provider" {
source ="../modules/azurerm_resource_provider_registration"
version = <required version> //Use latest one
After checking the above conditions, I tried same in my environment and it was initialized successfully:
Refer aliasing for the deployment in multiple subscriptions detailed by #Jeff Brown

A resource with the ID "/subscriptions/.../resourceGroups/rgaks/providers/Microsoft.Storage/storageAccounts/aksbackupstorage" already exists

I have created storage account and container inside it to store my aks backup using terraform. I have created child module for the storage account and container.I am creating the storage account and continer calling it from root module from "main.tf".i have created two modules such as module Ex:"module aks_backup_storage" and "module aks_backup_conatiner". The module have been created successfully after applying the terraform command "terraform apply" but at the end it is raising the following errors are mentioned bellow in the console.
A resource with the ID "/subscriptions/...../resourceGroups/rg-aks-backup-storage/providers/Microsoft.Storage/storageAccounts/aksbackupstorage" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_storage_account" for more information.
failed creating container: failed creating container: containers.Client#Create: Failure sending request: StatusCode=409 -- Original Error: autorest/azure: Service returned an error. Status=<nil> Code="ContainerAlreadyExists" Message="The specified container already exists.\nRequestId:f.........\nTime:2022-12-28T12:52:08.2075701Z"
root module
module "aks_backup_storage" {
source = "../modules/aks_pv_storage_container"
rg_aks_backup_storage = var.rg_aks_backup_storage
aks_backup_storage_account = var.aks_backup_storage_account
aks_backup_container = var.aks_backup_container
rg_aks_backup_storage_location = var.rg_aks_backup_storage_location
aks_backup_retention_days = var.aks_backup_retention_days
}
Child module
resource "azurerm_resource_group" "rg_aksbackup" {
name = var.rg_aks_backup_storage
location = var.rg_aks_backup_storage_location
}
resource "azurerm_storage_account" "aks_backup_storage" {
name = var.aks_backup_storage_account
resource_group_name = var.rg_aks_backup_storage
location = var.rg_aks_backup_storage_location
account_kind = "StorageV2"
account_tier = "Standard"
account_replication_type = "ZRS"
access_tier = "Hot"
enable_https_traffic_only = true
min_tls_version = "TLS1_2"
#allow_blob_public_access = false
allow_nested_items_to_be_public = false
is_hns_enabled = false
blob_properties {
container_delete_retention_policy {
days = var.aks_backup_retention_days
}
delete_retention_policy {
days = var.aks_backup_retention_days
}
}
}
# Different container can be created for the different backup level such as cluster, Namespace, PV
resource "azurerm_storage_container" "aks_backup_container" {
#name = "aks-backup-container"
name = var.aks_backup_container
#storage_account_name = azurerm_storage_account.aks_backup_storage.name
storage_account_name= var.aks_backup_storage_account
}
I have also try to import the resource using the bellow command
terraform import ['azurerm_storage_account.aks_backup_storage /subscriptions/a3ae2713-0218-47a2-bb72-c6198f50c56f/resourceGroups/rg-aks-backup-storage/providers/Microsoft.Storage/storageAccounts/aksbackupstorage']
But it also saying ZSH command not found
zsh: no matches found: [azurerm_storage_account.aks_backup_storage /subscriptions/a3ae2713-0218-47a2-bb72-c6198f50c56f/resourceGroups/rg-aks-backup-storage/providers/Microsoft.Storage/storageAccounts/aksbackupstorage/]
I had no issue when i was creating the resources using the same code without declaring any module.
Now, I have several modules in root module in the main.tf file
here is my project directory structure
I really appreciate any suggestions thanks in advance
variable.tf
variable "rg_aks_backup_storage" {
type = string
description = "storage account name for the backup"
default = "rg-aks-backup-storage"
}
variable "aks_backup_storage_account" {
type = string
description = "storage account name for the backup"
default = "aksbackupstorage"
}
variable "aks_backup_container" {
type = string
description = "storage container name "
#default = "aks-storage-container"
default = "aksbackupstoragecontaine"
}
variable "rg_aks_backup_storage_location" {
type = string
default = "westeurope"
}
variable "aks_backup_retention_days" {
type = number
default = 90
}
The storage account name that you use must be unique within Azure (see naming restrictions). I checked, and the default storage account name that you are using is already taken. Have you tried changing the name to something you know is unique?
A way to consistently do this would be to add a random suffix at the end of the name, eg:
resource "random_string" "random_suffix" {
length = 6
special = false
upper = false
}
resource "azurerm_storage_account" "aks_backup_storage" {
name = join("", tolist([var.aks_backup_storage_account, random_string.random_suffix.result]))
...
}
I also received the same error when I tried to run terraform apply while creating container registry.
It usually occurs when the terraform state file (running locally) does not match the Portal terraform state file resources.
Even if a resource with the same name does not exist in the portal or resource group, it will appear in terraform state files if it was deployed previously. If you've received these types of issues, verify the tf state file in portal. If the resource is not existent, use the following command to import it.
Note: Validate that the terraform state files are identical. Run terraform init & terraform apply once you are done with the changes.
To resolve this error, Use terraform import .
Here I tried to import the container registry (let's say) and it imported successfully.
terraform import azurerm_container_registry.acr "/subscriptions/<subscriptionID>/resourceGroups/<resourceGroup>/providers/Microsoft.ContainerRegistry/registries/xxxxcontainerRegistry1"
Output:
After that I applied terraform apply and successfully deployed the resource without any errors.
Deployed successfully in Portal:

How to access terragrunt variables in terraform code

I have terragrunt config where have declared the variables using locals as below at root level. In the child module , have declared the child terragrunt config file called (terragrunt.hcl).
parent terragrunt file has following code :
locals {
location = "East US"
}
child module terragrunt file has below code :
include {
path = find_in_parent_folders()
}
locals {
myvars = read_terragrunt_config(find_in_parent_folders("terragrunt.hcl"))
location = local.myvars.locals.location
}
now, trying to access location variable in the terraform code (main.tf) using following code :
location = "${var.location}"
but it throws error:
Error: Reference to undeclared input variable
on main.tf line 13, in resource "azurerm_resource_group" "example":
13: location = "${var.location}"
Not getting how i can access variables defined in the terragrunt file in the terraform code . please suggest
This error message means that your root module doesn't declare that it is expecting to be given a location value, and so you can't refer to it.
In your root Terraform module you can declare that you are expecting this variable by declaring it with a variable block, as the error message hints:
variable "location" {
type = string
}
This declaration will then make it valid to refer to var.location elsewhere in the root module, and it will also cause Terraform to produce an error if you accidentally run it without providing a value for this location variable.

Terraform - How do I map different azure environment variable files?

I have below two environments terraform files
devenv_variables.tfvars
testenv_variables.tfvars
Here is devenv_variables.tfvars
location = "westeurope"
resource_group_name = "devenv-cloudresources-rg"
Here is testenv_variables.tfvars
location = "westeurope"
resource_group_name = "testenv-cloudresources-rg"
Here is my main.tf
# Configure the Microsoft Azure Provider
provider "azurerm" {
version = "=2.0.0"
features {}
subscription_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
provider "azurerm" {
alias = "testenv"
subscription_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
# Create a resource group
resource "azurerm_resource_group" {
provider = "azurerm.testenv" //How do I pass provider based on variables here?
name = "${var.resource_group_name}"
location = "${var.location}"
}
My requirement is, based on passed tfvar file as parameter, it should choose the subscription.
terraform apply -var-file="devenv_variables.tfvars"
when I type below command resource shall create in test environment
terraform apply -var-file="testenv_variables.tfvars"
I think, I need to define client id, and password to login to respective subscriptions.
tfvars files should only contain the values of variables.
The declaration of variables should happen in regular tf files.
variables.tf
variable "location" {
type = "string"
description = "The azure location where the resources is created"
}
devenv_variables.tfvars
location = "West Europe"
This tutorial can also help you with some more information and examples.
All you have to do this just make same variable name in both files. when you run the command terraform plan–var-file='variable's_file_name' & terraform apply–var-file='variable's_file_name'
on that point terraform will get different value from different file.
for demo
variable.tf (contain all variables)
variable "resource_group" {
type = string
description = "Resource Group"
default = ""
}
dev.tfvars (contain development variable's values)
resource_group="name_of_my_resource_group_dev"
prod.tfvars (contain production variable's values)
resource_group="name_of_my_resource_group_prod"
now when you run command terraform plan–var-file='dev.tfvars' it take the value from dev.tfvars file.

How to reference a resource created by a Terraform module

I'm using the AWS VPC Terraform module to create a VPC. Additionally, I want to create and attach an Internet Gateway to this VPC using the aws_internet_gateway resource.
Here is my code:
module "vpc" "vpc_default" {
source = "terraform-aws-modules/vpc/aws"
name = "${var.env_name}-vpc-default"
cidr = "10.0.0.0/16"
enable_dns_hostnames = true
}
resource "aws_internet_gateway" "vpc_default_igw" {
vpc_id = "${vpc.vpc_default.id}"
tags {
Name = "${var.env_name}-vpc-igw-vpcDefault"
}
}
When I run terraform init, I get the following error:
Initializing modules...
- module.vpc
Error: resource 'aws_internet_gateway.vpc_default_igw' config: unknown resource 'vpc.vpc_default' referenced in variable vpc.vpc_default.id
How can I reference a resource created by a Terraform module?
Since you're using a module, you need to change the format of the reference slightly. Module Outputs use the form ${module.<module name>.<output name>}. It's also important to note, you can only reference values outputted from a module.
In your specific case, this would become ${module.vpc.vpc_id} based on the VPC Module's Outputs.

Resources