Skip to content

Instantly share code, notes, and snippets.

@lAnubisl
Created July 6, 2023 16:35
Show Gist options
  • Save lAnubisl/4dcea7b448ce032c572116176bb4a0a3 to your computer and use it in GitHub Desktop.
Save lAnubisl/4dcea7b448ce032c572116176bb4a0a3 to your computer and use it in GitHub Desktop.
Integration between Azure API Management and Azure Blob Storage
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.45.0"
}
}
required_version = ">= 1.4.6"
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "rg" {
name = "rg-apim-to-blob"
location = "westeurope"
}
resource "azurerm_storage_account" "sa_adidas" {
name = "stadidas2july2023"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_storage_container" "sc_adidas" {
name = "reports"
storage_account_name = azurerm_storage_account.sa_adidas.name
container_access_type = "private"
}
resource "azurerm_storage_account" "sa_nike" {
name = "stnike2july2023"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_storage_container" "sc_nike" {
name = "reports"
storage_account_name = azurerm_storage_account.sa_nike.name
container_access_type = "private"
}
resource "azurerm_api_management" "apim" {
name = "apim-brands-july-2023"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
publisher_name = "My Company"
publisher_email = "[email protected]"
sku_name = "Consumption_0"
identity {
type = "SystemAssigned"
}
}
# Allow APIM to access the 'Adidas' storage account container.
resource "azurerm_role_assignment" "sc_adidas_role_assignment" {
scope = azurerm_storage_container.sc_adidas.resource_manager_id
role_definition_name = "Storage Blob Data Contributor"
principal_id = azurerm_api_management.apim.identity[0].principal_id
}
# Allow APIM to access the 'Nike' storage account container.
resource "azurerm_role_assignment" "sc_nike_role_assignment" {
scope = azurerm_storage_container.sc_nike.resource_manager_id
role_definition_name = "Storage Blob Data Contributor"
principal_id = azurerm_api_management.apim.identity[0].principal_id
}
resource "azurerm_api_management_backend" "apim_backend_adidas" {
name = "adidas-storage"
title = "adidas-storage title"
description = "Storage account for Adidas Description"
resource_group_name = azurerm_resource_group.rg.name
api_management_name = azurerm_api_management.apim.name
protocol = "http"
url = "https://${azurerm_storage_account.sa_adidas.name}.blob.core.windows.net/${azurerm_storage_container.sc_adidas.name}"
}
resource "azurerm_api_management_backend" "apim_backend_nike" {
name = "nike-storage"
title = "nike-storage title"
description = "Storage account for Nike Description"
resource_group_name = azurerm_resource_group.rg.name
api_management_name = azurerm_api_management.apim.name
protocol = "http"
url = "https://${azurerm_storage_account.sa_nike.name}.blob.core.windows.net/${azurerm_storage_container.sc_nike.name}"
}
resource "azurerm_api_management_product" "apim_product" {
product_id = "my_product_id"
api_management_name = azurerm_api_management.apim.name
resource_group_name = azurerm_resource_group.rg.name
display_name = "My Product"
description = "My Product Description"
terms = "My Product Terms"
subscription_required = true
subscriptions_limit = 1
approval_required = true
published = true
}
resource "azurerm_api_management_api" "apim_api" {
name = "example-api-name"
resource_group_name = azurerm_resource_group.rg.name
api_management_name = azurerm_api_management.apim.name
revision = "1"
display_name = "Integrations with Azure Managed Services"
api_type = "http"
path = "path"
protocols = ["https"]
subscription_key_parameter_names {
header = "subscription"
query = "subscription"
}
}
resource "azurerm_api_management_product_api" "apim_product_api" {
api_name = azurerm_api_management_api.apim_api.name
product_id = azurerm_api_management_product.apim_product.product_id
resource_group_name = azurerm_resource_group.rg.name
api_management_name = azurerm_api_management.apim.name
}
resource "azurerm_api_management_api_operation" "apim_api_opn" {
operation_id = "to-blob-storage"
api_name = azurerm_api_management_api.apim_api.name
api_management_name = azurerm_api_management_api.apim_api.api_management_name
resource_group_name = azurerm_api_management_api.apim_api.resource_group_name
display_name = "Send data to the blob storage"
method = "POST"
url_template = "/blobstorage"
description = "Send data to the blob storage"
}
resource "azurerm_api_management_api_operation_policy" "apim_api_operation_policy_blobstorage" {
api_name = azurerm_api_management_api_operation.apim_api_opn.api_name
api_management_name = azurerm_api_management_api_operation.apim_api_opn.api_management_name
resource_group_name = azurerm_api_management_api_operation.apim_api_opn.resource_group_name
operation_id = azurerm_api_management_api_operation.apim_api_opn.operation_id
xml_content = <<XML
<policies>
<inbound>
<base />
<choose>
<when condition="@(context.Request.Headers.GetValueOrDefault("brand","") == "adidas")">
<set-backend-service backend-id="${azurerm_api_management_backend.apim_backend_adidas.name}" />
</when>
<when condition="@(context.Request.Headers.GetValueOrDefault("brand","") == "nike")">
<set-backend-service backend-id="${azurerm_api_management_backend.apim_backend_nike.name}" />
</when>
<otherwise>
<return-response>
<set-status code="400" reason="Bad Request" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>@{
var json = new JObject() {{"Error", "Invalid brand"}} ;
return json.ToString(Newtonsoft.Json.Formatting.None);
}</set-body>
</return-response>
</otherwise>
</choose>
<rewrite-uri template="@($"{DateTime.UtcNow.ToString("\\y=yyyy/\\m=MM/\\d=dd/\\h=HH")}/{context.RequestId.ToString()}")" copy-unmatched-params="false" />
<authentication-managed-identity resource="https://storage.azure.com/" />
<set-header name="x-ms-date" exists-action="override">
<value>@(DateTime.UtcNow.ToString("R"))</value>
</set-header>
<set-header name="x-ms-version" exists-action="override">
<value>2023-01-03</value>
</set-header>
<set-header name="x-ms-blob-type" exists-action="override">
<value>BlockBlob</value>
</set-header>
<set-header name="x-ms-access-tier" exists-action="override">
<value>Hot</value>
</set-header>
<set-method>PUT</set-method>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<choose>
<when condition="@(context.Response.StatusCode == 201)">
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>@{
var json = new JObject() {{"OperationId", context.RequestId}} ;
return json.ToString(Newtonsoft.Json.Formatting.None);
}</set-body>
</when>
</choose>
</outbound>
<on-error>
<base />
</on-error>
</policies>
XML
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment