How can I create an Azure CosmosDB Serverless using Terraform? - azure

I've been trying to create the serverless offer of the cosmosdb database using Terraform, but haven't been able to do so.
After reading Microsoft's documentations and the Azurerm terraform registry documentations, I could code this resource:
resource "azurerm_cosmosdb_account" "resume-challenge-cosmosdb" {
name = var.cosmosdb-name
location = var.region
resource_group_name = azurerm_resource_group.cloud-resume-rg.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
enable_automatic_failover = false
enable_free_tier = true
consistency_policy {
consistency_level = "BoundedStaleness"
max_interval_in_seconds = 300
max_staleness_prefix = 100000
}
geo_location {
location = "brazilsouth"
failover_priority = 0
}
}
but it creates the regular version of the cosmosdb.

To make a CosmosDB account serverless using the AzureRM Terraform provider you need to enable the EnableServerless capability on the azurerm_cosmosdb_account. To do this you must add a capabilities block with name = "EnableServerless". Applying this to your above example would look like so:
resource "azurerm_cosmosdb_account" "resume-challenge-cosmosdb" {
name = var.cosmosdb-name
location = var.region
resource_group_name = azurerm_resource_group.cloud-resume-rg.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
enable_automatic_failover = false
enable_free_tier = true
consistency_policy {
consistency_level = "BoundedStaleness"
max_interval_in_seconds = 300
max_staleness_prefix = 100000
}
geo_location {
location = "brazilsouth"
failover_priority = 0
}
capabilities {
name = "EnableServerless"
}
}
I found this by searching for the word "serverless" on the azurerm_cosmosdb_account resource docs.

Related

Terraform Azurerm: Create blob if not exists

I got Terrafrom code that creates storage account, container and block blob. Is it possible to configure that block blob is created only if it doesn't already exist?
In case of re-running terraform I wouldn't like to replace blob if it is already there as the content might have been manually modified and i would like to keep it.
Any tips? Only alternative I could think of is running powershell/bash script during further deployment steps that would create file if needed, but I am curious if this can be done just with Terraform.
locals {
storage_account_name_teast = format("%s%s", local.main_pw_prefix_short, "teast")
}
resource "azurerm_storage_account" "teaststorage" {
name = local.storage_account_name_teast
resource_group_name = azurerm_resource_group.main.name
location = var.location
account_tier = var.account_tier
account_replication_type = var.account_replication_type
allow_nested_items_to_be_public = false
min_tls_version = "TLS1_2"
network_rules {
default_action = "Deny"
bypass = [
"AzureServices"
]
virtual_network_subnet_ids = []
ip_rules = local.ip_rules
}
tags = var.tags
}
resource "azurerm_storage_container" "teastconfig" {
name = "config"
storage_account_name = azurerm_storage_account.teaststorage.name
container_access_type = "private"
}
resource "azurerm_storage_blob" "teastfeaturetoggle" {
name = "featureToggles.json"
storage_account_name = azurerm_storage_account.teaststorage.name
storage_container_name = azurerm_storage_container.teastconfig.name
type = "Block"
source = "vars-pr-default-toggles.json"
}
After scanning through terraform plan I figured out it was forcing a blob replacement because of:
content_md5 = "9a95db04fb1ff3abcd7ff81fcfb96307" -> null # forces replacement
I added lifecycle hook to blob resource to prevent it:
resource "azurerm_storage_blob" "teastfeaturetoggle" {
name = "featureToggles.json"
storage_account_name = azurerm_storage_account.teaststorage.name
storage_container_name = azurerm_storage_container.teastconfig.name
type = "Block"
source = "vars-pr-default-toggles.json"
lifecycle {
ignore_changes = [
content_md5,
]
}
}

Terraform - Add tags to failover SQL databases

I am trying to figure out a way to add tags to the failover DBs created with the help of terraform registry - azurerm_mssql_failover_group.
if I use the tags field mentioned as part of terraform documentation, it adds tags to the failover group but it does not set tags on the failover databases created.
My code for the resource group is as below
resource "azurerm_mssql_failover_group" "sql-database-failover" {
name = "sqldatabasefailover1"
server_id = "Id of Primary SQL Server"
databases = [
"Id of primary SQL dbs"
]
partner_server {
id = "Id of secondary (failover) SQL server"
}
read_write_endpoint_failover_policy {
mode = "Automatic"
grace_minutes = 60
}
tags = local.common_tags
}
I tried looking for terraform registry which can help us add tags to the already present DB but could not find any. Any help will be appreciated.
Regards Tarun
I tried to reproduce the same in my environment .
I created local tags as below and tried to add to failover group.
Code referred from : azurerm_sql_failover_group | Resources | hashicorp/azurerm | Terraform Registry
Code:
locals {
resource_tags = {
project_name = "failovergroup",
category = "devbackupresource"
}
}
resource "azurerm_mssql_server" "primary" {
name = "ka-sql-primary"
resource_group_name = data.azurerm_resource_group.example.name
location = "southeastasia"
version = "12.0"
administrator_login = "sqladmin"
administrator_login_password = "xxx"
}
resource "azurerm_mssql_server" "secondary" {
name = "ka-sql-secondary"
resource_group_name = data.azurerm_resource_group.example.name
location = "westeurope"
version = "12.0"
administrator_login = "sqladmin"
administrator_login_password = "xxx"
}
resource "azurerm_mssql_database" "db1" {
name = "kadb1"
server_id = azurerm_mssql_server.primary.id
}
resource "azurerm_mssql_failover_group" "example" {
name = "kav-example-failover-group"
server_id = azurerm_mssql_server.primary.id
databases = [azurerm_mssql_database.db1.id]
tags = local.resource_tags
partner_server {
id = azurerm_mssql_server.secondary.id
}
read_write_endpoint_failover_policy {
mode = "Automatic"
grace_minutes = 60
}
}
But the tags are not added to secondaryDb which is intended for failover group.
You can use the tags in Secondary Db resource block ” azurerm_mssql_server” for secondary as below.
locals {
resource_tags = {
...
}
}
resource "azurerm_mssql_server" "secondary" {
name = "ka-sql-secondary"
resource_group_name = data.azurerm_resource_group.example.name
location = "westeurope"
version = "12.0"
administrator_login = "sqladmin"
administrator_login_password = "pa$$w0rd"
tags = local.resource_tags
}
resource "azurerm_mssql_failover_group" "example" {
name = "kav-example-failover-group
server_id = azurerm_mssql_server.primary.id
databases = [azurerm_mssql_database.db1.id]
...
}
This created tags to my secondary sql server in azure .
Edit:
tag-support-microsoftsql
See Auto-failover groups limitations .One may need to create tags manually .
Also Note: Database restore operations don't restore the tags of the
original database.

Terraform deployment for 'Work pace based Application Insight' on Azure

I have been trying to figure out a way to prepare a terraform template for my app service/az function where I can connect it to application Insight while creating them through Terraform. Well the it worked, BUT the application Insight shows
Migrate this resource to Workspace-based Application Insights to gain support for all of the capabilities of Log Analytics, including Customer-Managed Keys and Commitment Tiers. Click here to learn more and migrate in a few clicks.
How do I acheive it from terraform? As from the documentation page of terraform there is no mention of such setup. Appreciate you help on this.
Here is the terraform code for az-function
resource "azurerm_linux_function_app" "t_funcapp" {
name = "t-function-app"
location = local.resource_location
resource_group_name = local.resource_group_name
service_plan_id = azurerm_service_plan.t_app_service_plan.id
storage_account_name = azurerm_storage_account.t_funcstorage.name
storage_account_access_key = azurerm_storage_account.t_funcstorage.primary_access_key
site_config {
application_stack {
java_version = "11"
}
remote_debugging_enabled = false
ftps_state = "AllAllowed"
}
app_settings = {
APPINSIGHTS_INSTRUMENTATIONKEY = "${azurerm_application_insights.t_appinsights.instrumentation_key}"
}
depends_on = [
azurerm_resource_group.t_rg,
azurerm_service_plan.t_app_service_plan,
azurerm_storage_account.t_funcstorage,
azurerm_application_insights.t_appinsights
]
}
Here is the terraform code for app insight
resource "azurerm_application_insights" "t_appinsights" {
name = "t-appinsights"
location = local.resource_location
resource_group_name = local.resource_group_name
application_type = "web"
depends_on = [
azurerm_log_analytics_workspace.t_workspace
]
}
output "instrumentation_key" {
value = azurerm_application_insights.t_appinsights.instrumentation_key
}
output "app_id" {
value = azurerm_application_insights.t_appinsights.app_id
}
You must create a Log Analytics Workspace and add it to your Application Insights.
For example
resource "azurerm_log_analytics_workspace" "example" {
name = "workspace-test"
location = local.resource_location
resource_group_name = local.resource_group_name
sku = "PerGB2018"
retention_in_days = 30
}
resource "azurerm_application_insights" "t_appinsights" {
name = "t-appinsights"
location = local.resource_location
resource_group_name = local.resource_group_name
workspace_id = azurerm_log_analytics_workspace.example.id
application_type = "web"
}
output "instrumentation_key" {
value = azurerm_application_insights.t_appinsights.instrumentation_key
}
output "app_id" {
value = azurerm_application_insights.t_appinsights.app_id
}
Hope this helps!

Unable to create Service Bus Authorization Rule in Azure

We are using terraform version of 0.12.19 and azurerm provider version 2.10.0 for deploying the service bus and its queues and authorization rules. So when we ran the terraform apply it created the service bus and queue but it throwed the below error for the creation of authorization rules.
But when we checked the azure portal these authorization rules were present and in tf state file as well we were able to find the entries of both the resources and they had a parameter Status as "Tainted" in it.. So when we tried to run the apply again to see if will recreate/replace the existing resources but it was failing with the same error. Now we are unable to proceed further as even when we run the plan for creating the new resources its failing at this point and not letting us proceed further.
We even tried to untainted it and run the apply but it seems still we are getting this issue though the resources doesn't have the status tainted parameter in tf state. Can you please help us here the solution so that we can resolve this. (We can't move forward to new version of terraform cli as there are so many modules dependent on it and it will impact our production deployments as well.)
Error: Error making Read request on Azure ServiceBus Queue Authorization Rule "" (Queue "sample-check-queue" / Namespace "sample-check-bus" / Resource Group "My-RG"): servicebus.QueuesClient#GetAuthorizationRule: Invalid input: autorest/validation: validation failed: parameter=authorizationRuleName constraint=MinLength value="" details: value length must be greater than or equal to 1
azurerm_servicebus_queue_authorization_rule.que-sample-check-lsr: Refreshing state... [id=/subscriptions//resourcegroups/My-RG/providers/Microsoft.ServiceBus/namespaces/sample-check-bus/queues/sample-check-queue/authorizationrules/lsr]
Below is the service_bus.tf file code:
provider "azurerm" {
version = "=2.10.0"
features {}
}
provider "azurerm" {
features {}
alias = "cloud_operations"
}
resource "azurerm_servicebus_namespace" "service_bus" {
name = "sample-check-bus"
resource_group_name = "My-RG"
location = "West Europe"
sku = "Premium"
capacity = 1
zone_redundant = true
tags = {
source = "terraform"
}
}
resource "azurerm_servicebus_queue" "que-sample-check" {
name = "sample-check-queue"
resource_group_name = "My-RG"
namespace_name = azurerm_servicebus_namespace.service_bus.name
dead_lettering_on_message_expiration = true
requires_duplicate_detection = false
requires_session = false
enable_partitioning = false
default_message_ttl = "P15D"
lock_duration = "PT2M"
duplicate_detection_history_time_window = "PT15M"
max_size_in_megabytes = 1024
max_delivery_count = 05
}
resource "azurerm_servicebus_queue_authorization_rule" "que-sample-check-lsr" {
name = "lsr"
resource_group_name = "My-RG"
namespace_name = azurerm_servicebus_namespace.service_bus.name
queue_name = azurerm_servicebus_queue.que-sample-check.name
listen = true
send = true
}
resource "azurerm_servicebus_queue_authorization_rule" "que-sample-check-AsyncReportBG-AsncRprt" {
name = "AsyncReportBG-AsncRprt"
resource_group_name = "My-RG"
namespace_name = azurerm_servicebus_namespace.service_bus.name
queue_name = azurerm_servicebus_queue.que-sample-check.name
listen = true
send = true
manage = false
}
I have tried the below terraform code to create authorization rules and could create them successfully:
I have followed this azurerm_servicebus_queue_authorization_rule |
Resources | hashicorp/azurerm | Terraform Registry having latest
version of hashicorp/azurerm terraform provider.
This maybe even related to arguments queue_name. arguments of
resources changed to queue_id in 3.X.X versions
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "example" {
name = "xxxx"
location = "xx"
}
provider "azurerm" {
features {}
alias = "cloud_operations"
}
resource "azurerm_servicebus_namespace" "service_bus" {
name = "sample-check-bus"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
sku = "Premium"
capacity = 1
zone_redundant = true
tags = {
source = "terraform"
}
}
resource "azurerm_servicebus_queue" "que-sample-check" {
name = "sample-check-queue"
#resource_group_name = "My-RG"
namespace_id = azurerm_servicebus_namespace.service_bus.id
#namespace_name =
azurerm_servicebus_namespace.service_bus.name
dead_lettering_on_message_expiration = true
requires_duplicate_detection = false
requires_session = false
enable_partitioning = false
default_message_ttl = "P15D"
lock_duration = "PT2M"
duplicate_detection_history_time_window = "PT15M"
max_size_in_megabytes = 1024
max_delivery_count = 05
}
resource "azurerm_servicebus_queue_authorization_rule" "que-sample-check-lsr"
{
name = "lsr"
#resource_group_name = "My-RG"
#namespace_name = azurerm_servicebus_namespace.service_bus.name
queue_id = azurerm_servicebus_queue.que-sample-check.id
#queue_name = azurerm_servicebus_queue.que-sample-check.name
listen = true
send = true
manage = false
}
resource "azurerm_servicebus_queue_authorization_rule" "que-sample-check- AsyncReportBG-AsncRprt" {
name = "AsyncReportBG-AsncRprt"
#resource_group_name = "My-RG"
#namespace_name = azurerm_servicebus_namespace.service_bus.name
queue_id = azurerm_servicebus_queue.que-sample-check.id
#queue_name = azurerm_servicebus_queue.que-sample-check.name
listen = true
send = true
manage = false
}
Authorization rules created without error:
Please try to change the name of the authorization rule named “lsr” with increased length and also please try to create one rule at a time in your case .
Thanks all for your inputs and suggestions.
Code is working fine now with the terraform provider version 2.56.0 and terraform cli version 0.12.19. Please let me know if any concerns.

Terraform with Azure Marketplace

I've started to get into Terraform and am loving it, since for cost reasons I have my services across a number of infrastructure providers, so it makes it easy to replicate full services without issues across IaaS providers.
I use some third-party services through the Azure marketplace, similar to Heroku's Add-Ons. I see a facility in Terraform for Heroku Add-On declarations, but not for Azure marketplace subscriptions. How can I do this?
Update:
How do I create an Azure marketplace order/subscription via Terraform?
If I understand your preoblem correctly I think the key is to create declare VM with the following sections with placeholder replaced;
plan {
publisher = "${publisher}" // e.g. bitnami
product = "${offer}" // e.g. elk
name = "${sku}" // e.g. 46
}
storage_image_reference {
publisher = "${publisher}" // e.g. bitnami
offer = "${offer}" // e.g. elk
sku = "${sku}" // e.g. 46
version = "${version}" // e.g. latest
}
So a complete VM resource definition would lok something like this.
resource "azurerm_virtual_machine" "virtual_machine" {
count = "${var.vm_count}"
name = "${element(module.template.vm_names, count.index)}"
location = "${var.location}"
resource_group_name = "${var.resource_group_name}"
network_interface_ids = ["${element(azurerm_network_interface.network_interface.*.id, count.index)}"]
vm_size = "${var.vm_size}"
delete_data_disks_on_termination = true
delete_os_disk_on_termination = true
plan {
publisher = "${var.publisher}"
product = "${var.offer}"
name = "${var.sku}"
}
boot_diagnostics {
enabled = true
storage_uri = "${var.boot_diagnostics_storage_url}"
}
storage_image_reference {
publisher = "${var.publisher}"
offer = "${var.offer}"
sku = "${var.sku}"
version = "${var.version}"
}
storage_os_disk {
name = "primarydisk"
vhd_uri = "${join("", list(var.disks_container_url, "/" , element(module.template.vm_names, count.index), ".vhd"))}"
caching = "ReadWrite"
create_option = "FromImage"
}
os_profile {
computer_name = "${element(module.template.vm_names, count.index)}"
admin_username = "${element(module.template.user_names, count.index)}"
}
os_profile_linux_config {
disable_password_authentication = true
ssh_keys = [{
path = "/home/${element(module.template.user_names, count.index)}/.ssh/authorized_keys"
key_data = "${replace(file("../vars/keys/vm.pub"),"\n","")}"
}]
}
tags {
environment = "${var.resource_group_name}"
}
}
resource "azurerm_marketplace_agreement"

Resources