Azure API Management instances with cheap-and-secure defaults: Developer_1 unless you say otherwise (every capability, development pricing, no SLA), a system-assigned identity on by default, legacy protocols and weak ciphers explicitly off, and tenant access (the direct management API) off until asked for. The first layer of the estate's MCP gateway architecture: the instance this module creates is what fronts MCP servers and REST-as-MCP tools.
- One way to do custom hostnames. Domains ride the standalone custom-domain resource (the
custom_domainobject), never the service'shostname_configurationblock, which is deliberately not exposed: the standalone resource changes domains without a full service update, and two ways to say the same thing is how drift arguments start. - The security posture is explicit. The
securityblock is always emitted with every legacy protocol and weak cipher off by default, so the secure state is visible in plan and state rather than implied by an absent block. - Instances key by name in a map, with the placement arguments (
resource_group_id,location,tags) at module level per the estate convention; the resource group name parses from its id. - Premium surface is present but not defaulted:
zonesandadditional_locationstype-check and pass through, they just cost money this module refuses to imply.
- Developer tier bills by the hour at development rates and carries no SLA; it is the right tier for everything short of production, and it is this module's default on purpose.
- An APIM create takes 30 to 45 minutes; plan CI accordingly (the self-test here is an
hour-scale run by nature). Deletes soft-delete the name: the examples' provider features set
purge_soft_delete_on_destroy = trueso repeated apply-destroy cycles do not collide. - The instance's
public_ip_addressesoutput is what firewalled backends allow-list; an advisory check warns when public access is disabled without vnet integration, which locks everything out.
CI runs a trivy config scan that gates on HIGH and CRITICAL findings. Waivers live in
.trivyignore.yaml, and every waiver is recorded here. There are currently none.
| ID | Where | Justification |
|---|
| Name | Version |
|---|---|
| terraform | >= 1.9.0, < 2.0.0 |
| azurerm | >= 4.0.0, < 5.0.0 |
| Name | Version |
|---|---|
| azurerm | 4.81.0 |
No modules.
| Name | Type |
|---|---|
| azurerm_api_management.this | resource |
| azurerm_api_management_custom_domain.this | resource |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| api_managements | API Management instances to create, keyed by instance name. The full azurerm_api_management surface, typed, with secure-and-cheap defaults: sku_name defaults to Developer_1 (the no-SLA development tier; every paid capability, none of the production cost), a system-assigned identity is on by default, tenant access (the direct management API) is off by default, and the security object's legacy protocol and cipher toggles all default off. Custom hostnames are managed through the custom_domain object (the standalone custom-domain resource, which updates domains without a full service update); the service-level hostname_configuration block is deliberately not exposed, so there is exactly one way to do it. sign_up, when enabled, requires its terms_of_service. delegation carries the portal sign-in and subscription delegation endpoints. additional_locations and zones only mean anything on Premium. |
map(object({ |
n/a | yes |
| location | The location the API Management instances are deployed to. | string |
n/a | yes |
| resource_group_id | Resource id of the resource group to deploy into; the name is parsed from it, per the estate's pass-ids principle. | string |
n/a | yes |
| tags | Tags applied to every instance. | map(string) |
{} |
no |
| Name | Description |
|---|---|
| custom_domain_ids | Map of instance name to its custom-domain resource id, for instances that set one. |
| developer_portal_urls | Map of instance name to its developer portal URL. |
| gateway_regional_urls | Map of instance name to its regional gateway URL. |
| gateway_urls | Map of instance name to its gateway base URL; MCP servers exposed through the instance live under it. |
| identity_principal_ids | Map of instance name to the system-assigned identity's principal id (null when the instance is UserAssigned only). |
| ids | Map of instance name to resource id. |
| ids_zipmap | Map of instance name to {name, id} for easy composition. |
| management_api_urls | Map of instance name to its management API URL. |
| portal_urls | Map of instance name to its legacy publisher portal URL. |
| private_ip_addresses | Map of instance name to its private IP addresses (vnet-integrated instances). |
| public_ip_addresses | Map of instance name to its public IP addresses; the source addresses to allow-list on firewalled backends. |
| scm_urls | Map of instance name to its SCM URL. |