Skip to content

Commit

Permalink
feat: Backporting azure_management_api and `azure_management_produc…
Browse files Browse the repository at this point in the history
…t` modules (#2)
  • Loading branch information
Krusty93 authored Dec 11, 2024
1 parent 2b2eacf commit e4bda36
Show file tree
Hide file tree
Showing 10 changed files with 494 additions and 0 deletions.
113 changes: 113 additions & 0 deletions api_management_api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# api management api

This module allow the creation of api management product, and associate to a groups and create policy if requested

## Architecture

![This is an image](./docs/module-arch.drawio.png)

## How to use it

```ts
locals {
apim_devopslab_webapp_python_alpha_api = {
# params for all api versions
display_name = "Webapp Python Alpha api"
description = "Webapp Python Alpha api"
path = "webapp-python-alpha"
subscription_required = false
service_url = "http://mock-aks/webapp-python-alpha"
api_name = "${var.env}-webapp-python-alpha-api"
}
}

# resource "azurerm_api_management_api_version_set" "apim_devopslab_webapp_python_alpha_api" {
# name = local.apim_devopslab_webapp_python_alpha_api.api_name
# resource_group_name = module.apim.resource_group_name
# api_management_name = module.apim.name
# display_name = local.apim_devopslab_webapp_python_alpha_api.display_name
# versioning_scheme = "Segment"
# }

module "apim_devopslab_webapp_python_alpha_api_v1" {
source = "git::https://github.com/pagopa/terraform-azurerm-v4.git//api_management_api?ref=v1.0.0"

name = local.apim_devopslab_webapp_python_alpha_api.api_name
api_management_name = module.apim.name
product_ids = [module.apim_product_devopslab.product_id]
subscription_required = local.apim_devopslab_webapp_python_alpha_api.subscription_required
# version_set_id = azurerm_api_management_api_version_set.apim_devopslab_webapp_python_alpha_api.id
# api_version = "v1"
service_url = "${local.apim_devopslab_webapp_python_alpha_api.service_url}/"
resource_group_name = module.apim.resource_group_name

description = local.apim_devopslab_webapp_python_alpha_api.description
display_name = local.apim_devopslab_webapp_python_alpha_api.display_name
path = local.apim_devopslab_webapp_python_alpha_api.path
protocols = ["https"]

content_format = "openapi"
content_value = templatefile("./api/devopslab/webapp-python/openapi_webapp_python.json.tftpl", {
projectName = local.apim_devopslab_webapp_python_alpha_api.display_name
})

xml_content = file("./api/devopslab/webapp-python/_base_policy.xml")
}

```

<!-- markdownlint-disable -->
<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.9.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~> 4 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_api_management_api.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api) | resource |
| [azurerm_api_management_api_operation_policy.api_operation_policy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource |
| [azurerm_api_management_api_policy.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_policy) | resource |
| [azurerm_api_management_product_api.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_product_api) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_api_management_name"></a> [api\_management\_name](#input\_api\_management\_name) | n/a | `string` | n/a | yes |
| <a name="input_api_operation_policies"></a> [api\_operation\_policies](#input\_api\_operation\_policies) | List of api policy for given operation. | <pre>list(object({<br/> operation_id = string<br/> xml_content = string<br/> }<br/> ))</pre> | `[]` | no |
| <a name="input_api_type"></a> [api\_type](#input\_api\_type) | (Optional) Type of API. Possible values are graphql, http, soap, and websocket. Defaults to http. | `string` | `"http"` | no |
| <a name="input_api_version"></a> [api\_version](#input\_api\_version) | The Version number of this API, if this API is versioned. | `string` | `null` | no |
| <a name="input_content_format"></a> [content\_format](#input\_content\_format) | The format of the content from which the API Definition should be imported. | `string` | `"swagger-json"` | no |
| <a name="input_content_value"></a> [content\_value](#input\_content\_value) | The Content from which the API Definition should be imported. | `string` | n/a | yes |
| <a name="input_description"></a> [description](#input\_description) | n/a | `string` | n/a | yes |
| <a name="input_display_name"></a> [display\_name](#input\_display\_name) | n/a | `string` | n/a | yes |
| <a name="input_name"></a> [name](#input\_name) | n/a | `string` | n/a | yes |
| <a name="input_oauth2_authorization"></a> [oauth2\_authorization](#input\_oauth2\_authorization) | n/a | <pre>object({<br/> authorization_server_name = string<br/> }<br/> )</pre> | <pre>{<br/> "authorization_server_name": null<br/>}</pre> | no |
| <a name="input_path"></a> [path](#input\_path) | n/a | `string` | n/a | yes |
| <a name="input_product_ids"></a> [product\_ids](#input\_product\_ids) | n/a | `list(string)` | `[]` | no |
| <a name="input_protocols"></a> [protocols](#input\_protocols) | n/a | `list(string)` | n/a | yes |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | n/a | `string` | n/a | yes |
| <a name="input_revision"></a> [revision](#input\_revision) | n/a | `string` | `"1"` | no |
| <a name="input_revision_description"></a> [revision\_description](#input\_revision\_description) | n/a | `string` | `null` | no |
| <a name="input_service_url"></a> [service\_url](#input\_service\_url) | n/a | `string` | n/a | yes |
| <a name="input_subscription_key_names"></a> [subscription\_key\_names](#input\_subscription\_key\_names) | Override the default name of the header and query string containing the subscription key header | <pre>object({<br/> header = string<br/> query = string<br/> })</pre> | `null` | no |
| <a name="input_subscription_required"></a> [subscription\_required](#input\_subscription\_required) | Should this API require a subscription key? | `bool` | `false` | no |
| <a name="input_version_set_id"></a> [version\_set\_id](#input\_version\_set\_id) | The ID of the Version Set which this API is associated with. | `string` | `null` | no |
| <a name="input_xml_content"></a> [xml\_content](#input\_xml\_content) | The XML Content for this Policy as a string | `string` | `null` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_id"></a> [id](#output\_id) | n/a |
| <a name="output_name"></a> [name](#output\_name) | n/a |
<!-- END_TF_DOCS -->
66 changes: 66 additions & 0 deletions api_management_api/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
resource "azurerm_api_management_api" "this" {
name = var.api_version != null ? join("-", [var.name, var.api_version]) : var.name
resource_group_name = var.resource_group_name
api_management_name = var.api_management_name
revision = var.revision
revision_description = var.revision_description
display_name = var.display_name
description = var.description
api_type = var.api_type

dynamic "oauth2_authorization" {
for_each = var.oauth2_authorization.authorization_server_name != null ? ["dummy"] : []
content {
authorization_server_name = var.oauth2_authorization.authorization_server_name
}
}

path = var.path
protocols = var.protocols
service_url = var.service_url
subscription_required = var.subscription_required
version = var.api_version
version_set_id = var.version_set_id

import {
content_format = var.content_format
content_value = var.content_value
}

dynamic "subscription_key_parameter_names" {
for_each = var.subscription_key_names == null ? [] : ["dummy"]
content {
header = var.subscription_key_names.header
query = var.subscription_key_names.query
}
}
}

resource "azurerm_api_management_api_policy" "this" {
count = var.xml_content == null ? 0 : 1
api_name = azurerm_api_management_api.this.name
api_management_name = var.api_management_name
resource_group_name = var.resource_group_name

xml_content = var.xml_content
}

resource "azurerm_api_management_product_api" "this" {
for_each = toset(var.product_ids)

product_id = each.value
api_name = azurerm_api_management_api.this.name
api_management_name = var.api_management_name
resource_group_name = var.resource_group_name
}

resource "azurerm_api_management_api_operation_policy" "api_operation_policy" {
for_each = { for p in var.api_operation_policies : format("%s%s", p.operation_id, var.api_version == null ? "" : var.api_version) => p }

api_name = azurerm_api_management_api.this.name
api_management_name = var.api_management_name
resource_group_name = var.resource_group_name
operation_id = each.value.operation_id

xml_content = each.value.xml_content
}
7 changes: 7 additions & 0 deletions api_management_api/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "id" {
value = azurerm_api_management_api.this.id
}

output "name" {
value = azurerm_api_management_api.this.name
}
116 changes: 116 additions & 0 deletions api_management_api/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
variable "resource_group_name" {
type = string
}

variable "name" {
type = string
}

variable "api_management_name" {
type = string
}

variable "display_name" {
type = string
}

variable "description" {
type = string
}

variable "service_url" {
type = string
}

variable "revision" {
type = string
default = "1"
}

variable "revision_description" {
type = string
default = null
}

variable "api_type" {
type = string
default = "http"
description = "(Optional) Type of API. Possible values are graphql, http, soap, and websocket. Defaults to http."
}

variable "oauth2_authorization" {
type = object({
authorization_server_name = string
}
)
default = {
authorization_server_name = null
}
}

variable "path" {
type = string
}

variable "protocols" {
type = list(string)
}

variable "subscription_required" {
type = bool
default = false
description = "Should this API require a subscription key?"
}

variable "content_format" {
type = string
description = "The format of the content from which the API Definition should be imported."
default = "swagger-json"
}

variable "content_value" {
type = string
description = "The Content from which the API Definition should be imported."
}

variable "xml_content" {
type = string
description = "The XML Content for this Policy as a string"
default = null
}

variable "product_ids" {
type = list(string)
default = []
}

variable "api_operation_policies" {
type = list(object({
operation_id = string
xml_content = string
}
))
default = []
description = "List of api policy for given operation."
}

variable "api_version" {
type = string
description = "The Version number of this API, if this API is versioned."
default = null
}

variable "version_set_id" {
type = string
description = "The ID of the Version Set which this API is associated with."
default = null
}

variable "subscription_key_names" {
type = object({
header = string
query = string
})
description = "Override the default name of the header and query string containing the subscription key header"
default = null
}
10 changes: 10 additions & 0 deletions api_management_api/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.9.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4"
}
}
}
74 changes: 74 additions & 0 deletions api_management_product/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# api management product

This module allow the creation of api management product, and associate to a groups and create policy if requested

## Architecture

![This is an image](./docs/module-arch.drawio.png)

## How to use it

```ts
module "apim_product_devopslab" {
source = "git::https://github.com/pagopa/terraform-azurerm-v4.git//api_management_product?ref=v1.0.0"

product_id = "devopslab"
display_name = "DevOpsLab Program"
description = "Product for DevOpsLab backend"

api_management_name = module.apim.name
resource_group_name = module.apim.resource_group_name

published = true
subscription_required = true
approval_required = false

policy_xml = file("./api_product/devopslab/_base_policy.xml")
}

```

<!-- markdownlint-disable -->
<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.9.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~> 4 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_api_management_product.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_product) | resource |
| [azurerm_api_management_product_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_product_group) | resource |
| [azurerm_api_management_product_policy.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_product_policy) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_api_management_name"></a> [api\_management\_name](#input\_api\_management\_name) | The name of the API Management Service. | `string` | n/a | yes |
| <a name="input_approval_required"></a> [approval\_required](#input\_approval\_required) | Do subscribers need to be approved prior to being able to use the Product? | `bool` | n/a | yes |
| <a name="input_description"></a> [description](#input\_description) | A description of this Product, which may include HTML formatting tags. | `string` | n/a | yes |
| <a name="input_display_name"></a> [display\_name](#input\_display\_name) | The Display Name for this API Management Product. | `string` | n/a | yes |
| <a name="input_groups"></a> [groups](#input\_groups) | (Optional) The groups where the product is included | `set(string)` | `[]` | no |
| <a name="input_policy_xml"></a> [policy\_xml](#input\_policy\_xml) | (Optional) The XML Content for this Product Policy. | `string` | `null` | no |
| <a name="input_product_id"></a> [product\_id](#input\_product\_id) | The Identifier for this Product, which must be unique within the API Management Service. | `string` | n/a | yes |
| <a name="input_published"></a> [published](#input\_published) | Is this Product Published? | `bool` | n/a | yes |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | The name of the Resource Group in which the API Management Service should be exist. | `string` | n/a | yes |
| <a name="input_subscription_required"></a> [subscription\_required](#input\_subscription\_required) | Is a Subscription required to access API's included in this Product? | `bool` | n/a | yes |
| <a name="input_subscriptions_limit"></a> [subscriptions\_limit](#input\_subscriptions\_limit) | The number of subscriptions a user can have to this Product at the same time. | `number` | `null` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_id"></a> [id](#output\_id) | n/a |
| <a name="output_product_id"></a> [product\_id](#output\_product\_id) | n/a |
<!-- END_TF_DOCS -->
Loading

0 comments on commit e4bda36

Please sign in to comment.