Skip to content

Commit

Permalink
feat: Add Access control block
Browse files Browse the repository at this point in the history
  • Loading branch information
fdmsantos committed May 6, 2024
1 parent cde22f9 commit 0920184
Show file tree
Hide file tree
Showing 20 changed files with 397 additions and 15 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Dynamic Terraform module, which creates a Logic App and others resources.
* [Module versioning rule](README.md#module-versioning-rule)
* [How to Use](README.md#how-to-use)
* [Basic](README.md#basic)
* [Disable SAS Scheme](README.md#disable-sas-scheme)
* [Examples](README.md#examples)
* [Requirements](README.md#requirements)
* [Providers](README.md#providers)
Expand Down Expand Up @@ -67,9 +68,17 @@ module "logic_app" {
}
```

### Disable SAS Scheme

* Configuring `authentication_policies` doesn't disable the Shared Access Signature (SAS) Scheme.
* To Disable the SAS scheme it's necessary create condition on http trigger. When `disable_sas_auth_schema` set it to true, will create this condition on http trigger.
* Due `azurerm_logic_app_workflow` resource limitations, this is only supported in http and webhook triggers configured using `custom_triggers`. Please check the following [example](https://github.com/fdmsantos/terraform-azurerm-logicapp/tree/main/examples/disable_sas_scheme) to more info.

## Examples

- [complete](https://github.com/fdmsantos/terraform-azurerm-logicapp/tree/main/examples/complete) - Creates Logic App with all supported features.
- [Complete](https://github.com/fdmsantos/terraform-azurerm-logicapp/tree/main/examples/complete) - Creates Logic App with all supported features.
- [Basic](https://github.com/fdmsantos/terraform-azurerm-logicapp/tree/main/examples/basic) - Creates Simple Logic App.
- [Disable SAS Scheme](https://github.com/fdmsantos/terraform-azurerm-logicapp/tree/main/examples/disable_sas_scheme) - Create Logic App with Microsoft Entra ID OAuth as the only option to call a request endpoint.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
Expand Down Expand Up @@ -103,9 +112,13 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_actions_allowed_caller_ip_address_range"></a> [actions\_allowed\_caller\_ip\_address\_range](#input\_actions\_allowed\_caller\_ip\_address\_range) | Restrict calls to triggers in this logic app to the provided IP ranges. IP addresses can be either IPv4 or IPv6 and accepts range and bitmask range formats. | `list(string)` | `[]` | no |
| <a name="input_authentication_policies"></a> [authentication\_policies](#input\_authentication\_policies) | Map of authentication policies to apply in this Logic app. | <pre>map(list(object({<br> claim_name = string<br> claim_value = string<br> })))</pre> | `{}` | no |
| <a name="input_connections_parameters"></a> [connections\_parameters](#input\_connections\_parameters) | Parameters related with API Connections. | `list(map(any))` | `[]` | no |
| <a name="input_contents_allowed_caller_ip_address_range"></a> [contents\_allowed\_caller\_ip\_address\_range](#input\_contents\_allowed\_caller\_ip\_address\_range) | Restrict calls to get input and output messages from run history to the provided IP ranges. IP addresses can be either IPv4 or IPv6 and accepts range and bitmask range formats. | `list(string)` | `[]` | no |
| <a name="input_custom_actions"></a> [custom\_actions](#input\_custom\_actions) | Map of Logic App Custom Actions. | `map(string)` | `{}` | no |
| <a name="input_custom_triggers"></a> [custom\_triggers](#input\_custom\_triggers) | Map of Custom Triggers. | <pre>map(object({<br> body = string<br> }))</pre> | `{}` | no |
| <a name="input_disable_sas_auth_schema"></a> [disable\_sas\_auth\_schema](#input\_disable\_sas\_auth\_schema) | This will create an condition on Http Triggers to enable the request be only from Microsoft Entra ID. Only Supports HTTP Triggers Configured via Custom Triggers and only makes sense when authentication\_policies are configured. | `bool` | `false` | no |
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Is the Logic App enabled? Defaults to true | `bool` | `true` | no |
| <a name="input_http_triggers"></a> [http\_triggers](#input\_http\_triggers) | Map of Logic App HTTP Triggers. | <pre>map(object({<br> schema = string<br> method = optional(string, null)<br> relative_path = optional(string, null)<br> }))</pre> | `{}` | no |
| <a name="input_identity_ids"></a> [identity\_ids](#input\_identity\_ids) | Specifies a list of User Assigned Managed Identity IDs to be assigned to this Logic App. | `list(string)` | `[]` | no |
Expand All @@ -118,7 +131,9 @@ No modules.
| <a name="input_recurrence_triggers"></a> [recurrence\_triggers](#input\_recurrence\_triggers) | Map of Logic App Recurrence Triggers. | <pre>map(object({<br> frequency = string<br> interval = number<br> start_time = optional(string, null)<br> time_zone = optional(string, null)<br> at_these_minutes = optional(list(number), [])<br> at_these_hours = optional(list(number), [])<br> on_these_days = optional(list(string), [])<br> }))</pre> | `{}` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Specifies the name of the Resource Group where the logic should exists. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to assign to resources. | `map(string)` | `{}` | no |
| <a name="input_workflow_parameters"></a> [workflow\_parameters](#input\_workflow\_parameters) | Specifies a map of Key-Value pairs of the Parameter Definitions to use for this Logic App Workflow. The key is the parameter name, and the value is a JSON encoded string of the parameter definition (see: https://docs.microsoft.com/azure/logic-apps/logic-apps-workflow-definition-language#parameters). | <pre>map(object({<br> type = string<br> defaultValue = any<br> allowedValues = optional(list(string), null)<br> metadata = optional(object({<br> description = string<br> }))<br> }))</pre> | `{}` | no |
| <a name="input_triggers_allowed_caller_ip_address_range"></a> [triggers\_allowed\_caller\_ip\_address\_range](#input\_triggers\_allowed\_caller\_ip\_address\_range) | Restrict calls to triggers in this logic app to the provided IP ranges. IP addresses can be either IPv4 or IPv6 and accepts range and bitmask range formats. | `list(string)` | `[]` | no |
| <a name="input_workflow_management_allowed_caller_ip_address_range"></a> [workflow\_management\_allowed\_caller\_ip\_address\_range](#input\_workflow\_management\_allowed\_caller\_ip\_address\_range) | Restrict workflow management in this logic app to the provided IP ranges. IP addresses can be either IPv4 or IPv6 and accepts range and bitmask range formats. | `list(string)` | `[]` | no |
| <a name="input_workflow_parameters"></a> [workflow\_parameters](#input\_workflow\_parameters) | Specifies a map of Key-Value pairs of the Parameter Definitions to use for this Logic App Workflow. The key is the parameter name, and the value is a JSON encoded string of the parameter definition (see: https://docs.microsoft.com/azure/logic-apps/logic-apps-workflow-definition-language#parameters). | <pre>map(object({<br> type = string<br> defaultValue = any<br> allowedValues = optional(list(string), [])<br> metadata = optional(object({<br> description = optional(string, null)<br> }), {})<br> }))</pre> | `{}` | no |
| <a name="input_workflow_schema"></a> [workflow\_schema](#input\_workflow\_schema) | Specifies the Schema to use for this Logic App Workflow. Defaults to https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json# | `string` | `"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#"` | no |
| <a name="input_workflow_version"></a> [workflow\_version](#input\_workflow\_version) | Specifies the version of the Schema used for this Logic App Workflow. Defaults to 1.0.0.0. Changing this forces a new resource to be created. | `string` | `"1.0.0.0"` | no |

Expand Down
33 changes: 33 additions & 0 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
resource "azurerm_resource_group" "this" {
name = "RG-${title(var.name)}"
location = var.location
}

module "logic_app" {
source = "../../"
name = var.name
location = var.location
resource_group_name = azurerm_resource_group.this.name
identity_type = "SystemAssigned"
workflow_parameters = {
storage_account_name : {
type : "String",
defaultValue : "storageaccountname"
}
}
recurrence_triggers = {
run-every-day = {
frequency = "Day"
interval = 1
time_zone = "GMT Standard Time"
at_these_minutes = [0, 30]
at_these_hours = [0, 12]
}
}
custom_actions = {
"Initialize_variable" : file("${path.module}/templates/actions/initialize_variable.json")
}
tags = {
env : "dev"
}
}
19 changes: 19 additions & 0 deletions examples/basic/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output "logic_app_id" {
description = "The Logic App ID."
value = module.logic_app.id
}

output "http_triggers" {
description = "Http Triggers."
value = module.logic_app.http_triggers
}

output "recurrence_triggers" {
description = "Recurrence Triggers."
value = module.logic_app.recurrence_triggers
}

output "custom_triggers" {
description = "Custom Triggers."
value = module.logic_app.custom_triggers
}
5 changes: 5 additions & 0 deletions examples/basic/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
provider "azurerm" {
skip_provider_registration = true
subscription_id = var.subscription_id
features {}
}
12 changes: 12 additions & 0 deletions examples/basic/templates/actions/initialize_variable.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"inputs": {
"variables": [
{
"name": "ProcessedFiles",
"type": "array"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
}
16 changes: 16 additions & 0 deletions examples/basic/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
variable "name" {
description = "Specifies the name of resource group."
type = string
default = "logic-app-demo"
}

variable "location" {
description = "Specifies the Azure Region where the logic app should exists. Changing this forces a new resource to be created."
type = string
default = "westeurope"
}

variable "subscription_id" {
description = "Specifies the subscription id should be used for this demo."
type = string
}
9 changes: 9 additions & 0 deletions examples/basic/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 0.13.1"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.22"
}
}
}
38 changes: 30 additions & 8 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
data "http" "myip" {
url = "https://ipv4.icanhazip.com"
}

data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "this" {
name = "RG-${title(var.name)}"
location = var.location
Expand All @@ -19,6 +25,22 @@ module "logic_app" {
defaultValue : "storageaccountname"
}
}
actions_allowed_caller_ip_address_range = ["${chomp(data.http.myip.response_body)}/32"]
triggers_allowed_caller_ip_address_range = ["${chomp(data.http.myip.response_body)}/32"]
contents_allowed_caller_ip_address_range = ["${chomp(data.http.myip.response_body)}/32"]
workflow_management_allowed_caller_ip_address_range = ["${chomp(data.http.myip.response_body)}/32"]
authentication_policies = {
test-policy : [
{
claim_name : "Issuer",
claim_value : "https://sts.windows.net/${data.azurerm_client_config.current.tenant_id}"
},
{
claim_name : "DummyClaim",
claim_value : "Dummy Value"
},
]
}
http_triggers = {
"HTTP_Trigger" = {
method = "POST",
Expand All @@ -37,14 +59,14 @@ module "logic_app" {
custom_triggers = {
custom = {
body = <<BODY
{
"recurrence": {
"frequency": "Day",
"interval": 1
},
"type": "Recurrence"
}
BODY
{
"recurrence": {
"frequency": "Day",
"interval": 1
},
"type": "Recurrence"
}
BODY
}
}
custom_actions = {
Expand Down
4 changes: 4 additions & 0 deletions examples/complete/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ terraform {
source = "hashicorp/azurerm"
version = ">= 3.22"
}
http = {
source = "hashicorp/http"
version = ">= 3.4"
}
}
}
45 changes: 45 additions & 0 deletions examples/disable_sas_scheme/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "this" {
name = "RG-${title(var.name)}"
location = var.location
}

module "logic_app" {
source = "../../"
name = var.name
location = var.location
resource_group_name = azurerm_resource_group.this.name
identity_type = "SystemAssigned"
workflow_parameters = {
storage_account_name : {
type : "String",
defaultValue : "storageaccountname"
}
}
disable_sas_auth_schema = true
authentication_policies = {
test-policy : [
{
claim_name : "Issuer",
claim_value : "https://sts.windows.net/${data.azurerm_client_config.current.tenant_id}"
},
{
claim_name : "DummyClaim",
claim_value : "Dummy Value"
},
]
}
custom_triggers = {
HTTP_Trigger = {
body = file("${path.module}/templates/triggers/http_trigger.json")
}
}
custom_actions = {
"Initialize_variable" : file("${path.module}/templates/actions/initialize_variable.json")
"Response" : file("${path.module}/templates/actions/response.json")
}
tags = {
env : "dev"
}
}
19 changes: 19 additions & 0 deletions examples/disable_sas_scheme/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output "logic_app_id" {
description = "The Logic App ID."
value = module.logic_app.id
}

output "http_triggers" {
description = "Http Triggers."
value = module.logic_app.http_triggers
}

output "recurrence_triggers" {
description = "Recurrence Triggers."
value = module.logic_app.recurrence_triggers
}

output "custom_triggers" {
description = "Custom Triggers."
value = module.logic_app.custom_triggers
}
5 changes: 5 additions & 0 deletions examples/disable_sas_scheme/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
provider "azurerm" {
skip_provider_registration = true
subscription_id = var.subscription_id
features {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"inputs": {
"variables": [
{
"name": "ProcessedFiles",
"type": "array"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
}
15 changes: 15 additions & 0 deletions examples/disable_sas_scheme/templates/actions/response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"inputs": {
"body": {
"processed_files": "@variables('ProcessedFiles')"
},
"statusCode": 201
},
"kind": "Http",
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "Response"
}
18 changes: 18 additions & 0 deletions examples/disable_sas_scheme/templates/triggers/http_trigger.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"inputs" : {
"method" : "POST",
"schema" : {
"properties" : {
"month" : {
"type" : "integer"
},
"year" : {
"type" : "integer"
}
},
"type" : "object"
}
},
"kind" : "Http",
"type" : "Request"
}
16 changes: 16 additions & 0 deletions examples/disable_sas_scheme/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
variable "name" {
description = "Specifies the name of resource group."
type = string
default = "logic-app-demo"
}

variable "location" {
description = "Specifies the Azure Region where the logic app should exists. Changing this forces a new resource to be created."
type = string
default = "westeurope"
}

variable "subscription_id" {
description = "Specifies the subscription id should be used for this demo."
type = string
}
9 changes: 9 additions & 0 deletions examples/disable_sas_scheme/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 0.13.1"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.22"
}
}
}
30 changes: 30 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,34 @@ locals {
{ for parameter, content in var.workflow_parameters : parameter => jsonencode(content) },
length(var.connections_parameters) > 0 ? { "$connections" = jsonencode({ "defaultValue" = {}, "type" = "Object" }) } : {}
)

standard_claims = {
Issuer : "iss"
Audience : "aud"
Subject : "sub"
"JWT ID" : "jti"
}

### Add condition because enable_entra_id_only_option_call_request ###
custom_triggers_non_http = { for name, trigger in var.custom_triggers : name => trigger if lookup(jsondecode(trigger["body"]), "type", "None") != "Request" && lookup(jsondecode(trigger["body"]), "type", "None") != "HttpWebhook" }
custom_triggers_http = { for name, trigger in var.custom_triggers : name => trigger if lookup(jsondecode(trigger["body"]), "type", "None") == "Request" || lookup(jsondecode(trigger["body"]), "type", "None") == "HttpWebhook" }
custom_triggers_http_entra_id_condition = {
for name, trigger in local.custom_triggers_http :
name => {
body : jsonencode(merge(jsondecode(trigger["body"]), !contains(keys(jsondecode(trigger["body"])), "conditions") ? tomap({
"conditions" : [{
"expression" : "@startsWith(triggerOutputs()?['headers']?['Authorization'], 'Bearer')"
}] }) : tomap({ "conditions" : concat(jsondecode(trigger["body"])["conditions"], [{
"expression" : "@startsWith(triggerOutputs()?['headers']?['Authorization'], 'Bearer')"
}]) })
)) } }
custom_triggers_http_entra_id_operation_options = {
for name, trigger in local.custom_triggers_http_entra_id_condition :
name => {
body : jsonencode(merge(jsondecode(trigger["body"]), {
"operationOptions" : "IncludeAuthorizationHeadersInOutputs",
}))
}
}
custom_triggers = !var.disable_sas_auth_schema ? merge(local.custom_triggers_non_http, local.custom_triggers_http) : merge(local.custom_triggers_non_http, local.custom_triggers_http_entra_id_operation_options)
}
Loading

0 comments on commit 0920184

Please sign in to comment.