Error : Terraform Azure, setting hosting mode to high density for standard3 - terraform

I am trying to run a script for search service setting hosting mode to high density. But I get this error: An argument named "hosting_mode" is not expected here.
resource "azurerm_search_service" "acc" {
name = "${var.cognsearch_account_name}"
resource_group_name = "${azurerm_resource_group.rg.name}"
location = "${azurerm_resource_group.rg.location}"
sku = "standard3"
hosting_mode = "highDensity"
}

According to the documentation found here, hosting_mode is not a supported option. Looking at the REST API it a supported parameter. I suggest you open an issues with terraform-provider-azurerm. I did see that the standard2 and standard3 skus are only available if Microsoft enables it. Might make testing an issue. You will have to adjust it manually, use an ARM template in terraform to update it or create the resource if updates from default -> highDensity is not allowed. (Not indicated in the documentation).

Related

Azure - Create Function App hostkey with Terraform azapi/bicep/powershell

I'm working on automating the rotation of my azure function app's host key, which is used to maintain a more secure connection between my API Management and my function apps. The issue is that I can not figure out how to accomplish this based on the lack of clear documentation. I found a document for how to create a key for a specific function within the function app, but not for the host level. I've tried using the web ui resource manager to figure out what the proper values are, but host seems to have no values available by GET request to help me see what the formatting needs to be. In fact, I can't find any reference to my function app's host keys anywhere in the resource manager UI. (Of course I can in the portal).
I don't care if it's powershell, bicep, ARM, terraform azapi, whatever, I'd just like to find a way to accomplish the creation of a new hostkey so that I can control it's rotation with terraform. Does anyone know how to accomplish this?
Right now my attempt looks like
resource "azapi_resource" "function_host_key" {
type = "Microsoft.Web/sites/host/functionkeys#2018-11-01"
name = "${azurerm_windows_function_app.api_function.name}-host-key"
parent_id = "${azurerm_windows_function_app.api_function.id}/host"
body = jsonencode({
properties = {
name = "test-key-terraform"
value = "asdfasdfasdfasdfasdfasdfasdf"
}
})
}
I also tried
resource "azapi_resource" "function_host_key" {
type = "Microsoft.Web/sites#2018-11-01"
name = "${azurerm_windows_function_app.api_function.name}-host-key"
parent_id = "${azurerm_windows_function_app.api_function.id}/functionsAppKeys"
location = var.region
}
since it said the body was invalid, but this also throws an error due to there being no body. I'm wondering if this just isn't possible.
I also just tried
resource "azapi_resource" "function_host_key" {
type = "Microsoft.Web/host/functionkeys#2018-11-01"
name = "${azurerm_windows_function_app.api_function.name}-host-key"
parent_id = "${azurerm_windows_function_app.api_function.id}/host"
location = var.region
}
and the result said that it was expecting
parent_id of `parent_id is invalid`: expect ID of `Microsoft.Web/host`
so I'm not sure what that parent_id should be.
I found an example through a bash/powershell script using the azure rest API, but I get a 403 error when I attempt to do it, I can only assume because my function app is secured, but I'm not sure a good way to determine that.
There must be a way to create a key programmatically...
UPDATE
I believe that this has been purposely made impossible now to do with terraform and I need to, as grose and backwards as it may be, use a CLI command in my pipeline. I understand you can do this, but it is (ofc my opinion) that if I am using terraform, I have terraform manage something, not have random CLI commands outside of terraform doing things that TF should be able to manage.
I created a key using az functionapp keys set and that worked, and the output explicitly stated that the type of resource which was created was Microsoft.Web/sites/host/functionKeys, so I went to the Azure Resource Explorer to see what versions were available for this type, since it clearly exists.. and found that nope, azure does not have it listed.
What confuses me is that I see this being done w/ ARM templates and I believe that my code matches theirs, just I'm using AZAPI.. and I get a not found error. Giving up for now

Get inbound ip adress from azurerm_windows_web_app in Terraform

I want to create azurerm_mssql_firewall_rule resource witch allows IP of "Azure windows web app".
When I write it manually it works fine. f.e.:
resource "azurerm_mssql_firewall_rule" "api_cloud" {
name = var.cloud_firewal_rule_name
server_id = azurerm_mssql_server.api.id
start_ip_address = "00.000.000.00"
end_ip_address = "00.000.000.00"
}
I want to get IP address like this start_ip_address/end_ip_address = azurerm_windows_web_app.api.inbound_ip_address.
But there isn't inbound option in azurerm_windows_web_app, I can only access outbound addresses azurerm_windows_web_app.api.outbound_ip_addresses.
Is there is anyway do something like this?
IN SHORT:
How to get this IP address with terraform?
Yes, there is but it's a bit complicated due to the way Terraform works. I used a Linux App Service in my examples but it should work identically for both Windows and Linux versions. Let's go:
So, things are a bit more complicated due to the fact that App Services have quite a big range of possible outbound IP addresses as they are running on a shared infrastructure. Therefore it returns a list with an unknown length. That makes things annoying for Terraform. As an example, this is how you usually iterate through multiple items in Terraform using for_each:
resource "azurerm_mssql_firewall_rule" "example" {
for_each = toset(azurerm_linux_web_app.api_app.outbound_ip_address_list)
name = "FirewallRule"
server_id = azurerm_mssql_server.example.id
start_ip_address = each.key
end_ip_address = each.key
}
In this snippet, you take the list of outbound IP addresses from the App Service, cast them to a set, and then iterate through it. However, this only works if the App Service already exists - if you are starting from an empty slate, you will face the following error:
azurerm_linux_web_app.api_app.outbound_ip_address_list is a list of
string, known only after apply
The "for_each" map includes keys
derived from resource attributes that cannot be determined until
apply, and so Terraform cannot determine the full set of keys that
will identify the instances of this resource.
When working with
unknown values in for_each, it's better to define the map keys
statically in your configuration and place apply-time results only in
the map values.
Alternatively, you could use the -target
planning option to first apply only the resources that the for_each
value depends on, and then apply a second time to fully converge.
Luckily Terraform has a quite helpful error message, which tells us how we can work around the problem. Using the -target parameter we can first create the App Service like this
terraform apply -target=azurerm_linux_web_app.api_app
This should only create the App Service and dependencies required by it. Afterward, we can then execute Terraform normally and it should work as desired without any errors. It's not very pretty, but currently, there are no better ways of achieving exactly what you want.

Deploying and configuring Postgres server in Azure with Terraform

I'm deploying Azure Postgres Flexible Server with Terraform as described in GitHub. The configuration works as expected, no issues there. The only divination from that GitHub template is that I want to configure pgBouncer for Postgres which is now supported natively. I don't see a way how I can create this configuration (i.e., enable this feature).
I've done some research and discovered the configuration feature is not quite available (at least according to the open ticket in GitHub here). At the same time, one of the published replies suggests using azurerm_postgresql_flexible_server_configuration and this resource type is available in Terraform indeed. However, Microsoft documentation states that to enable and configure pgBouncer I need to introduce 7 parameters. I thought that to make the code tidier, I can use a list and foreach loop, like this:
locals {
pg_config = {
"pgbouncer.default_pool_size" : "50",
"pgBouncer.max_client_conn" : "5000",
"pgBouncer.pool_mode" : "TRANSACTION"
etc...
}
}
resource "azurerm_postgresql_flexible_server_configuration" "postgres_fs_config" {
for_each = local.pg_config
name = each.key
value = each.value
server_id = azurerm_postgresql_flexible_server.postgres-fs.id
}
Is this the best way to configure Postgres (without involving CDK)? Did I miss something?
Ok, I verified this approach and it works like a charm. Will stick to it for now.

The argument "storage_connection_string" is required, but no definition was found

I'm currently trying to set up an Azure Function app using Terraform.
Using the documentation from Hasihcorp found here.
However when running a terraform plan I'm getting the following error: The argument "storage_connection_string" is required, but no definition was found.
According to the documentation there is no such valid parameter and as such I've not included it. I've only found one entry on this while looking about and it was only a question, with no response. I'm not well versed in Azure so don't know if I need the storage_connection_string or if it's the API that is messing with me.
The resource snippet:
resource "azurerm_function_app" "this" {
name = "function-name"
resource_group_name = "resource-group"
location = "location"
app_service_plan_id = "id"
storage_account_name = "name"
storage_account_access_key = "key"
Formatting and referencing of values are set up but I don't have the code on this computer so made more sense to just post it like this.
This most likely arises from using an outdated version of the azure provider. E.g. version 2.0.0 has a required storage_connection_string. That got removed in some version.
Solution: upgrade your used provider version. Somewhere you should have declared that you want to use the azure provider. At that place you should specify a version constraint as well, e.g.:
terraform {
required_providers {
azure = {
version = "~> 2.40.0"
}
}
}
Or alternatively you should only look at the documentation matching your current provider + terraform version.

Network settings for Terraform aws_launch_template?

Terraform v0.12.x
I'm trying to create an AWS launch template using of course the aws_launch_template resource, and trying to relate to what the AWS console gives me when I try to create a launch template there. In the AWS console, I see the "Network settings" option seen in screen shot.
However, but I don't see a corresponding setting for the Terraform resource? Is that correct? I think I need to set it because when I try to create a spot fleet request, using Terraform's aws_spot_fleet_request resource, and using the launch template created by Terraform, it defaults to the "EC2-Classic" setting, which doesn't work for me. I get this error
Error: Error requesting spot fleet: InvalidSpotFleetRequestConfig: Invalid: (InstanceType: r5a.xlarge with Os: Linux/UNIX and EC2-Classic)
How can I fix this?
Ah, in the aws_spot_request resource, add an overrides that specifies a subnet id, which will of course put the instances in a VPC
resource "aws_spot_fleet_request" "jenkins_build_fleet" {
...
launch_template_config {
launch_template_specification {
id = module.launch_template.id
version = module.launch_template.version
}
overrides {
subnet_id = "subnet-12345abcde"
}
}
}

Resources