I Have a terraform code which use module inside a module.
main.tf
module "FunctionApp" {
source = "../modules/FunctionApp"
location = var.location
resourceGroupName = module.rg.name
}
module FunctionApp - main.tf
resource "azurerm_resource_group" "example" {
name = "azure-functions-test-rg"
location = "westus2"
}
resource "azurerm_storage_account" "example" {
name = "functionsappsacostco"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
min_tls_version = "TLS1_2"
}
resource "azurerm_app_service_plan" "example" {
name = "azure-functions-test-service-plan"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
kind = "windows"
sku {
tier = "PremiumV2"
size = "P1v2"
}
}
resource "azurerm_function_app" "example" {
name = "test-azure-functions-csco"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_app_service_plan.example.id
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
version = "~4"
}
module "fz_slot" {
source = "./fz-slot"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_app_service_plan.example.id
function_app_name = azurerm_function_app.example.name
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
}
module fz-slot - main.tf
resource "azurerm_function_app_slot" "example" {
provider = azurerm.old
name = "staging"
location = var.location
resource_group_name = var.resource_group_name
app_service_plan_id = var.app_service_plan_id
function_app_name = var.function_app_name
storage_account_name = var.storage_account_name
storage_account_access_key = var.storage_account_access_key
version = "~4"
}
I want to use the latest azurerm version in all the resources other than fz-slot module. In fz-slot module i want to use azurerm 2.67.0 version.
How can I achive this ?
You cannot do it.
You must create two terraform configurations, one for each version provider.
Related
I got question is there a way to import azure funtion app to api managment api using terraform.
https://learn.microsoft.com/en-us/azure/api-management/import-function-app-as-api
below is link to terraform resource but I do not see funtion app in import section
A import block supports the following:
content_format - (Required) The format of the content from which the API Definition should be imported. possible values are: openapi, openapi+json, openapi+json-link, openapi-link, swagger-json, swagger-link- json, wadl-link-json, wadl-xml, wsdl and wsdl-link.
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api
Is this possible?
import-function-app-as-api
Try below terraform code to import function app as an api with Azure api management. I added the function App Url under import block and was able to deployed successfully.
main.tf:
provider "azurerm"{
features{}
}
resource "azurerm_resource_group" "example" {
name = "<resource name>"
location = "West Europe"
}
resource "azurerm_storage_account" "example" {
name = "xxxxstorageaccount"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_app_service_plan" "example" {
name = "azure-functions-test-service-plan"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku {
tier = "Standard"
size = "S1"
}
}
resource "azurerm_function_app" "example" {
name = "xxxfunctionapp"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_app_service_plan.example.id
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
}
resource "azurerm_api_management" "example" {
name = "xxxxapim"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
publisher_name = "xxx"
publisher_email = "xxx#terraform.io"
sku_name = "Developer_1"
}
resource "azurerm_api_management_api" "example" {
name = "xxxapi"
resource_group_name = azurerm_resource_group.example.name
api_management_name = azurerm_api_management.example.name
revision = "1"
display_name = "Example API"
path = "example"
protocols = ["https"]
import {
content_format = "swagger-link-json"
content_value = azurerm_function_app.example.name
}
}
terraform plan:
terraform apply:
Deployed in Portal:
Reference: Terraform registry
I want to create a cluster inside a VNET, so that later I can create a connection to the on-premise resources.
I have following problem:
│ Error: Unsupported argument │ │ on main.tf line 130, in resource "azurerm_kubernetes_cluster" "aks": │ 130: user_assigned_identity_id = azurerm_user_assigned_identity.identity.id │ │ An argument named "user_assigned_identity_id" is not expected here.
My main.tf:
`
data "azurerm_resource_group" "aks-rg" {
name = var.resource_group_name
}
resource "azurerm_role_assignment" "role_acrpull" {
scope = azurerm_container_registry.acr.id
role_definition_name = "AcrPull"
principal_id = azurerm_kubernetes_cluster.aks.kubelet_identity.0.object_id
#skip_service_principal_aad_check = true
}
resource "azurerm_container_registry" "acr" {
name = var.acr_name
resource_group_name = data.azurerm_resource_group.aks-rg.name
location = var.location
sku = "Standard"
admin_enabled = false
}
resource "azurerm_network_security_group" "pusg" {
name = "Public_Security_Group"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
}
resource "azurerm_virtual_network" "puvnet" {
name = "Public_VNET"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
address_space = ["10.19.0.0/16"]
dns_servers = ["10.19.0.4", "10.19.0.5"]
}
resource "azurerm_subnet" "osubnet" {
name = "Outer_Subnet"
resource_group_name = data.azurerm_resource_group.aks-rg.name
address_prefixes = ["10.19.1.0/24"]
virtual_network_name = azurerm_virtual_network.puvnet.name
}
resource "azurerm_subnet" "isubnet" {
name = "Inner_Subnet"
resource_group_name = data.azurerm_resource_group.aks-rg.name
address_prefixes = ["10.19.2.0/24"]
virtual_network_name = azurerm_virtual_network.puvnet.name
}
resource "azurerm_subnet" "firewall_subnet" {
name = "AzureFirewallSubnet"
resource_group_name = data.azurerm_resource_group.aks-rg.name
virtual_network_name = azurerm_virtual_network.puvnet.name
address_prefixes = ["10.19.3.0/24"]
}
resource "azurerm_user_assigned_identity" "identity" {
resource_group_name = data.azurerm_resource_group.aks-rg.name
location = var.location
name = "identityh"
}
resource "azurerm_role_assignment" "networkRole" {
scope = data.azurerm_resource_group.aks-rg.id
role_definition_name = "Network Contributor"
principal_id = azurerm_user_assigned_identity.identity.principal_id
}
resource "azurerm_route_table" "routeTable" {
name = "rt-FWall"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
}
resource "azurerm_route" "route1" {
name = "dg-route1"
resource_group_name = data.azurerm_resource_group.aks-rg.name
route_table_name = azurerm_route_table.routeTable.name
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = azurerm_firewall.firewall.ip_configuration.0.private_ip_address
}
resource "azurerm_subnet_route_table_association" "base" {
subnet_id = azurerm_subnet.osubnet.id
route_table_id = azurerm_route_table.routeTable.id
}
resource "azurerm_public_ip" "firewall_public_ip" {
name = "pip-firewall"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_firewall" "firewall" {
name = "public_firewall"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
sku_name = "AZFW_VNet"
sku_tier = "Standard"
ip_configuration {
name = "ipconfig"
subnet_id = azurerm_subnet.firewall_subnet.id
public_ip_address_id = azurerm_public_ip.firewall_public_ip.id
}
}
resource "azurerm_kubernetes_cluster" "aks" {
name = var.cluster_name
kubernetes_version = var.kubernetes_version
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
dns_prefix = var.cluster_name
network_profile {
network_plugin = "azure"
outbound_type = "userDefinedRouting"
}
default_node_pool {
name = "system"
node_count = var.system_node_count
vm_size = "Standard_DS2_v2"
vnet_subnet_id = azurerm_subnet.osubnet.id
}
identity {
type = "UserAssigned"
user_assigned_identity_id = azurerm_user_assigned_identity.identity.id
}
}
`
Region is Germany West Central. Kubernetes version 1.24.3, Azurerm 3.33, Terraform 1.3
I have tried different approaches I found over internet, but none seemed to work. Best case scenario is when creation takes too long and terraform stops without creating cluster.
That argument does not seem to be a part of the identity block. The argument that can be used inside of the identity block is identity_ids [1]:
resource "azurerm_kubernetes_cluster" "aks" {
name = var.cluster_name
kubernetes_version = var.kubernetes_version
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
dns_prefix = var.cluster_name
network_profile {
network_plugin = "azure"
outbound_type = "userDefinedRouting"
}
default_node_pool {
name = "system"
node_count = var.system_node_count
vm_size = "Standard_DS2_v2"
vnet_subnet_id = azurerm_subnet.osubnet.id
}
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.identity.id]
}
}
Note that the identity_ids argument is a list, hence the square brackets around the identity.
[1] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster#identity_ids
I am Following this docs page to deploy azure function with app settings https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/function_app
My terraform file looks like :
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.10.0"
}
}
}
provider "azurerm" {
}
resource "azurerm_resource_group" "example" {
name = "azure-functions-test-rg"
location = "West Europe"
}
resource "azurerm_storage_account" "example" {
name = "funcdemo123shafiq"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_app_service_plan" "example" {
name = "azure-functions-test-service-plan"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku {
tier = "Standard"
size = "S1"
}
}
resource "azurerm_function_app" "example" {
name = "test-azure-shafiq123"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_app_service_plan.example.id
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
os_type = "linux"
version = "~4"
app_settings {
FUNCTIONS_WORKER_RUNTIME = "python"
TESTING_KEY = "TESTING_VALUE"
}
site_config {
linux_fx_version = "python|3.9"
}
}
When try to deploy this through terraform apply command , I am getting this error.
│ Error: Unsupported block type
│
│ on main.tf line 46, in resource "azurerm_function_app" "example":
│ 46: app_settings {
│
│ Blocks of type "app_settings" are not expected here. Did you mean to define argument "app_settings"? If so, use the equals sign to assign it a value.
app_setting is supported on specific version of Terraform AzureRM provider. There is bug fixed availble for those version. I have used 3.3.0 provider version and it is working for me as expected and also you can't configure the value of site_config.Its value will be decide automatically based on the result of applying this configuration, same you can check in the updated document of Terraform
main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.3.0"
}
}
}
provider "azurerm" {
features{}
}
data "azurerm_resource_group" "example" {
name = "v-rXXXXXree"
#location = "West Europe"
}
resource "azurerm_storage_account" "example" {
name = "funcdemo123shafiq4535"
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_service_plan" "example" {
name = "azure-functions-test-service-plan1"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
os_type = "Linux"
sku_name = "Y1"
}
resource "azurerm_linux_function_app" "example" {
name = "test-azure-shafi4353"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
service_plan_id = azurerm_service_plan.example.id
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
#os_type = "linux"
#version = "~3"
app_settings={
FUNCTIONS_WORKER_RUNTIME = "python"
TESTING_KEY = "TESTING_VALUE"
}
site_config {
#linux_fx_version = "python|3.9"
}
}
I am using the below while deploying a virtual machine to specific zone in region eastus
resource "azurerm_linux_virtual_machine" "vm" {
.........
.........
zones = [1]
}
but terraform validate says
An argument named "zones" is not expected here. Did you mean "zone"?
You should prefer for_each and set to count and index. you can use this transformer code to create a virtual Machine in 3 Availability Zone. You can set the number of Zones according to your needs
provider "azurerm" {
features {}
}
data "azurerm_resource_group" "example" {
name = "XXXXXXXXX"
}
resource "azurerm_virtual_network" "example" {
name = "example-network"
address_space = ["10.0.0.0/16"]
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
}
resource "azurerm_subnet" "example" {
name = "internal"
resource_group_name = data.azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]
}
resource "azurerm_network_interface" "example" {
#count=3
name = "example-nic"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_linux_virtual_machine" "example" {
#count=3
name = "example-machine"
resource_group_name = data.azurerm_resource_group.example.name
location = data.azurerm_resource_group.example.location
size = "Standard_F2"
for_each = local.zones
zone = each.value
admin_username = "adminuser"
network_interface_ids = [
azurerm_network_interface.example.id,
]
admin_ssh_key {
username = "adminuser"
public_key = file("~/.ssh/id_rsa.pub")
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
}
locals {
zones = toset(["1","2","3"])
}
I created a private link for app configuration in Azure cloud.
My terraform code:
resource "azurerm_virtual_network" "example" {
name = "example-network"
address_space = ["10.0.0.0/16"]
location = var.location
resource_group_name = var.resource_group_name
}
resource "azurerm_subnet" "service" {
name = "service"
resource_group_name = var.resource_group_name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
enforce_private_link_service_network_policies = true
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_subnet" "endpoint" {
name = "endpoint"
resource_group_name = var.resource_group_name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_app_configuration" "appconf" {
name = "app-butfa"
resource_group_name = var.resource_group_name
location = var.location
}
resource "azurerm_private_endpoint" "example" {
name = "butfa-endpoint"
location = var.location
resource_group_name = var.resource_group_name
subnet_id = azurerm_subnet.endpoint.id
private_service_connection {
name = "butfa-privateserviceconnection"
private_connection_resource_id = azurerm_app_configuration.appconf.id
is_manual_connection = false
subresource_names = ["configurationStores"]
}
}
But when I run : terraform apply I got this error:
Error: creating Private Endpoint "butfa-endpoint" (Resource Group "DefaultResourceGroup-SEA"): network.PrivateEndpointsClient#CreateOrUpdate: Failure sending request: StatusCode=0 -- Original Error: Code="SkuFeatureNotSupported" Message="Call to Microsoft.AppConfiguration/configurationStores failed. Error message: The current SKU does not support 'private endpoint connection'." Details=[]
on init.services.tf line 62, in resource "azurerm_private_endpoint" "example":
62: resource "azurerm_private_endpoint" "example" {
Does anyone help?
Default of sku app configuration is free
set sku to standard
resource "azurerm_app_configuration" "appconf" {
name = "app-butfa"
resource_group_name = var.resource_group_name
location = var.location
sku = "standard"
}