diff --git a/.gitignore b/.gitignore
index 19dfb91..72ef14d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,16 @@ terraform.rc
# Other
.DS_Store
+todo.md
+
+# Ignore vim swap files
+*.swp
+*.swo
+
+# Irgnore meld diff files
+*.orig
+*.backup
+*.rej
+
+# Ignore values files
+*.tfvars
diff --git a/.terraform-docs.yml b/.terraform-docs.yml
index 8fa328a..0c044ad 100644
--- a/.terraform-docs.yml
+++ b/.terraform-docs.yml
@@ -1,67 +1,28 @@
-content: |-
-
-
object({| `null` | no | +| [aks\_vnet\_subnet\_id](#input\_aks\_vnet\_subnet\_id) | The ID of the subnet in which to deploy the Kubernetes Cluster. | `string` | n/a | yes | +| [clusterissuer\_email](#input\_clusterissuer\_email) | The email address to use for the cert-manager cluster issuer. | `string` | n/a | yes | +| [dns\_zone\_id](#input\_dns\_zone\_id) | The ID of the Azure DNS Zone to use. | `string` | n/a | yes | +| [dns\_zone\_name](#input\_dns\_zone\_name) | The name of the Azure DNS zone to use. | `string` | n/a | yes | +| [resource\_group\_name](#input\_resource\_group\_name) | The name of the resource group in which to create the AKS cluster. | `string` | n/a | yes | +| [user\_assigned\_identity](#input\_user\_assigned\_identity) | MSI id for AKS to run as | `string` | n/a | yes | +| [wayfinder\_domain\_name\_api](#input\_wayfinder\_domain\_name\_api) | The domain name to use for the Wayfinder API (e.g. api.wayfinder.example.com) | `string` | n/a | yes | +| [wayfinder\_domain\_name\_ui](#input\_wayfinder\_domain\_name\_ui) | The domain name to use for the Wayfinder UI (e.g. portal.wayfinder.example.com) | `string` | n/a | yes | +| [wayfinder\_instance\_id](#input\_wayfinder\_instance\_id) | The instance ID to use for Wayfinder. | `string` | n/a | yes | +| [wayfinder\_licence\_key](#input\_wayfinder\_licence\_key) | The licence key to use for Wayfinder | `string` | n/a | yes | +| [adcs](#input\_adcs) | ADCS variables required when using ADCS Issuer with Cert Manager |
url = string
username = string
ca_bundle = string
certificate_template_name = string
})
object({| `null` | no | | [adcs\_password](#input\_adcs\_password) | ADCS password required when using ADCS Issuer with Cert Manager | `string` | `""` | no | | [aks\_agents\_size](#input\_aks\_agents\_size) | The default size of the agents pool. | `string` | `"Standard_D2s_v3"` | no | -| [aks\_api\_server\_authorized\_ip\_ranges](#input\_aks\_api\_server\_authorized\_ip\_ranges) | The list of authorized IP ranges to contact the API server. | `list(string)` |
url = string
username = string
ca_bundle = string
certificate_template_name = string
})
[| no | +| [aks\_api\_server\_authorized\_ip\_ranges](#input\_aks\_api\_server\_authorized\_ip\_ranges) | The list of authorized IP ranges to contact the API server. | `list(string)` |
"0.0.0.0/0"
]
[| no | | [aks\_enable\_host\_encryption](#input\_aks\_enable\_host\_encryption) | Whether to enable host encryption. | `bool` | `false` | no | -| [aks\_maintenance\_window](#input\_aks\_maintenance\_window) | Maintenance configuration of the managed cluster. |
"0.0.0.0/0"
]
object({|
allowed = list(object({
day = string
hours = set(number)
})),
not_allowed = list(object({
end = string
start = string
})),
})
{| no | +| [aks\_maintenance\_window](#input\_aks\_maintenance\_window) | Maintenance configuration of the managed cluster. |
"allowed": [
{
"day": "Sunday",
"hours": [
22,
23
]
}
],
"not_allowed": []
}
object({|
allowed = list(object({
day = string
hours = set(number)
})),
not_allowed = list(object({
end = string
start = string
})),
})
{| no | | [aks\_rbac\_aad\_admin\_group\_object\_ids](#input\_aks\_rbac\_aad\_admin\_group\_object\_ids) | List of object IDs of the Azure AD groups that will be set as cluster admin. | `list(string)` | `[]` | no | | [aks\_sku\_tier](#input\_aks\_sku\_tier) | The SKU tier for this Kubernetes Cluster. | `string` | `"Standard"` | no | -| [aks\_vnet\_subnet\_id](#input\_aks\_vnet\_subnet\_id) | The ID of the subnet in which to deploy the Kubernetes Cluster. | `string` | n/a | yes | | [cert\_manager\_keyvault\_cert\_name](#input\_cert\_manager\_keyvault\_cert\_name) | Keyvault certificate name to use for cert-manager. Required if cluster issuer is keyvault | `string` | `null` | no | | [cert\_manager\_keyvault\_name](#input\_cert\_manager\_keyvault\_name) | Keyvault name to use for cert-manager. Required if cluster issuer is keyvault | `string` | `null` | no | | [cluster\_nodepool\_version](#input\_cluster\_nodepool\_version) | The Kubernetes version to use for the AKS cluster Nodepools. | `string` | `"1.30"` | no | | [cluster\_version](#input\_cluster\_version) | The Kubernetes version to use for the AKS cluster. | `string` | `"1.30"` | no | | [clusterissuer](#input\_clusterissuer) | Cluster Issuer name to use for certs | `string` | `"letsencrypt-prod"` | no | -| [clusterissuer\_email](#input\_clusterissuer\_email) | The email address to use for the cert-manager cluster issuer. | `string` | n/a | yes | -| [create\_duration\_delay](#input\_create\_duration\_delay) | Used to tune terraform apply when faced with errors caused by API caching or eventual consistency. Sets a custom delay period after creation of the specified resource type. |
"allowed": [
{
"day": "Sunday",
"hours": [
22,
23
]
}
],
"not_allowed": []
}
object({| `{}` | no | +| [create\_duration\_delay](#input\_create\_duration\_delay) | Used to tune terraform apply when faced with errors caused by API caching or eventual consistency. Sets a custom delay period after creation of the specified resource type. |
azurerm_role_definition = optional(string, "180s")
kubectl_manifest_cloud_identity = optional(string, "30s")
})
object({| `{}` | no | | [create\_localadmin\_user](#input\_create\_localadmin\_user) | Whether to create a localadmin user for access to the Wayfinder Portal and API | `bool` | `true` | no | -| [destroy\_duration\_delay](#input\_destroy\_duration\_delay) | Used to tune terraform destroy when faced with errors caused by API caching or eventual consistency. Sets a custom delay period after destruction of the specified resource type. |
azurerm_role_definition = optional(string, "180s")
kubectl_manifest_cloud_identity = optional(string, "30s")
})
object({| `{}` | no | +| [destroy\_duration\_delay](#input\_destroy\_duration\_delay) | Used to tune terraform destroy when faced with errors caused by API caching or eventual consistency. Sets a custom delay period after destruction of the specified resource type. |
azurerm_role_definition = optional(string, "0s")
kubectl_manifest_cloud_identity = optional(string, "60s")
})
object({| `{}` | no | | [disable\_internet\_access](#input\_disable\_internet\_access) | Whether to disable internet access for AKS and the Wayfinder ingress controller | `bool` | `false` | no | | [disable\_local\_login](#input\_disable\_local\_login) | Whether to disable local login for Wayfinder. Note: An IDP must be configured within Wayfinder, otherwise you will not be able to log in. | `bool` | `false` | no | | [dns\_provider](#input\_dns\_provider) | DNS provider for External DNS | `string` | `"azure"` | no | | [dns\_resource\_group\_id](#input\_dns\_resource\_group\_id) | The ID of the resource group where the DNS Zone exists, if different to Wayfinder's resource group. | `string` | `""` | no | -| [dns\_zone\_id](#input\_dns\_zone\_id) | The ID of the Azure DNS Zone to use. | `string` | n/a | yes | -| [dns\_zone\_name](#input\_dns\_zone\_name) | The name of the Azure DNS zone to use. | `string` | n/a | yes | | [enable\_cross\_tenant\_access](#input\_enable\_cross\_tenant\_access) | Whether to enable cross-tenant access for Wayfinder. Will create a suitable Enterprise Application with federated credential for Wayfinder to use. | `bool` | `false` | no | | [enable\_k8s\_resources](#input\_enable\_k8s\_resources) | Whether to enable the creation of Kubernetes resources for Wayfinder (helm and kubectl manifest deployments) | `bool` | `true` | no | | [enable\_wf\_cloudaccess](#input\_enable\_wf\_cloudaccess) | Whether to configure CloudIdentity and admin CloudAccessConfig resources in Wayfinder once installed (requires enable\_k8s\_resources) | `bool` | `true` | no | @@ -100,18 +123,12 @@ The `terraform-docs` utility is used to generate this README. Follow the below s | [location](#input\_location) | The Azure region to use. | `string` | `"uksouth"` | no | | [private\_dns\_zone\_id](#input\_private\_dns\_zone\_id) | Private DNS zone to use for private clusters | `string` | `null` | no | | [private\_link\_resourcegroup](#input\_private\_link\_resourcegroup) | The name of the resource group in which to create central private link resources for each AKS cluster. | `string` | `""` | no | -| [resource\_group\_name](#input\_resource\_group\_name) | The name of the resource group in which to create the AKS cluster. | `string` | n/a | yes | | [tags](#input\_tags) | A mapping of tags to assign to resources. | `map(string)` | `{}` | no | -| [user\_assigned\_identity](#input\_user\_assigned\_identity) | MSI id for AKS to run as | `string` | n/a | yes | | [venafi\_apikey](#input\_venafi\_apikey) | Venafi API key - required if using Venafi cluster issuer | `string` | `""` | no | | [venafi\_zone](#input\_venafi\_zone) | Venafi zone - required if using Venafi cluster issuer | `string` | `""` | no | -| [wayfinder\_domain\_name\_api](#input\_wayfinder\_domain\_name\_api) | The domain name to use for the Wayfinder API (e.g. api.wayfinder.example.com) | `string` | n/a | yes | -| [wayfinder\_domain\_name\_ui](#input\_wayfinder\_domain\_name\_ui) | The domain name to use for the Wayfinder UI (e.g. portal.wayfinder.example.com) | `string` | n/a | yes | -| [wayfinder\_idp\_details](#input\_wayfinder\_idp\_details) | The IDP details to use for Wayfinder to enable SSO |
azurerm_role_definition = optional(string, "0s")
kubectl_manifest_cloud_identity = optional(string, "60s")
})
object({|
type = string
clientId = optional(string)
clientSecret = optional(string)
serverUrl = optional(string)
azureTenantId = optional(string)
})
{| no | -| [wayfinder\_instance\_id](#input\_wayfinder\_instance\_id) | The instance ID to use for Wayfinder. | `string` | n/a | yes | -| [wayfinder\_licence\_key](#input\_wayfinder\_licence\_key) | The licence key to use for Wayfinder | `string` | n/a | yes | +| [wayfinder\_idp\_details](#input\_wayfinder\_idp\_details) | The IDP details to use for Wayfinder to enable SSO |
"azureTenantId": "",
"clientId": null,
"clientSecret": null,
"serverUrl": "",
"type": "none"
}
object({|
type = string
clientId = optional(string)
clientSecret = optional(string)
serverUrl = optional(string)
azureTenantId = optional(string)
})
{| no | | [wayfinder\_release\_channel](#input\_wayfinder\_release\_channel) | The release channel to use for Wayfinder | `string` | `"wayfinder-releases"` | no | -| [wayfinder\_version](#input\_wayfinder\_version) | The version to use for Wayfinder | `string` | `"v2.8.6"` | no | +| [wayfinder\_version](#input\_wayfinder\_version) | The version to use for Wayfinder | `string` | `"v2.9.6"` | no | ## Outputs @@ -130,4 +147,5 @@ The `terraform-docs` utility is used to generate this README. Follow the below s | [wayfinder\_cross\_tenant\_identity\_client\_id](#output\_wayfinder\_cross\_tenant\_identity\_client\_id) | The client ID for the cross-tenant identity. | | [wayfinder\_instance\_id](#output\_wayfinder\_instance\_id) | The unique identifier for the Wayfinder instance. | | [wayfinder\_ui\_url](#output\_wayfinder\_ui\_url) | The URL for the Wayfinder UI. | - \ No newline at end of file + + diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..862d78d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Please contact security@appvia.io on discovery of a vulnerability or security issue. diff --git a/examples/complete/.terraform-docs.yml b/examples/complete/.terraform-docs.yml deleted file mode 100644 index 4dd28c2..0000000 --- a/examples/complete/.terraform-docs.yml +++ /dev/null @@ -1,21 +0,0 @@ -content: |- - # Example: Complete (includes pre-configured Wayfinder SSO) - - ## Deployment - - 1. Create a Resource Group for Wayfinder to be installed within. - 2. Create a DNS Zone in Azure and ensure the domain is delegated to the Azure DNS nameservers. - 3. Copy the `terraform.tfvars.example` file to `terraform.tfvars` and update with your values. - 4. Run `terraform init -upgrade` - 5. Run `terraform apply` - - ## Updating Docs - - The `terraform-docs` utility is used to generate this README. Follow the below steps to update: - 1. Make changes to the `.terraform-docs.yml` file - 2. Fetch the `terraform-docs` binary (https://terraform-docs.io/user-guide/installation/) - 3. Run `terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .` - - {{ .Inputs }} - - {{ .Outputs }} diff --git a/examples/complete/README.md b/examples/complete/README.md index 25466ee..3d73d07 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -1,4 +1,3 @@ - # Example: Complete (includes pre-configured Wayfinder SSO) ## Deployment @@ -12,15 +11,68 @@ ## Updating Docs The `terraform-docs` utility is used to generate this README. Follow the below steps to update: + 1. Make changes to the `.terraform-docs.yml` file 2. Fetch the `terraform-docs` binary (https://terraform-docs.io/user-guide/installation/) 3. Run `terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3 | +| [azapi](#requirement\_azapi) | >= 1.8.0 | +| [azurerm](#requirement\_azurerm) | ~> 3.84 | +| [helm](#requirement\_helm) | ~> 2.9.0 | +| [kubectl](#requirement\_kubectl) | ~> 2.0 | +| [kubernetes](#requirement\_kubernetes) | ~> 2.23.0 | +| [random](#requirement\_random) | ~> 3.5 | +| [time](#requirement\_time) | ~> 0.9.0 | + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | 3.116.0 | +| [random](#provider\_random) | 3.6.3 | +| [tls](#provider\_tls) | 4.0.6 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [wayfinder](#module\_wayfinder) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [azurerm_key_vault.kv](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) | resource | +| [azurerm_key_vault_certificate.root](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_certificate) | resource | +| [azurerm_key_vault_certificate.signing](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_certificate) | resource | +| [azurerm_private_endpoint.kv](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) | resource | +| [azurerm_role_assignment.kv](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | +| [azurerm_role_assignment.private_dns](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | +| [azurerm_subnet.aks_nodes](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) | resource | +| [azurerm_user_assigned_identity.aks_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | +| [azurerm_virtual_network.wayfinder](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) | resource | +| [random_id.kv](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [tls_cert_request.signing](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/cert_request) | resource | +| [tls_locally_signed_cert.signing](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/locally_signed_cert) | resource | +| [tls_private_key.root](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key) | resource | +| [tls_private_key.signing](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key) | resource | +| [tls_self_signed_cert.root](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/self_signed_cert) | resource | +| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source | +| [azurerm_dns_zone.wayfinder](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/dns_zone) | data source | +| [azurerm_private_dns_zone.wayfinder](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/private_dns_zone) | data source | +| [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [aks\_api\_server\_authorized\_ip\_ranges](#input\_aks\_api\_server\_authorized\_ip\_ranges) | The list of authorized IP ranges to contact the Wayfinder Management AKS Cluster API server. | `list(string)` |
"azureTenantId": "",
"clientId": null,
"clientSecret": null,
"serverUrl": "",
"type": "none"
}
[| no | +| [aks\_api\_server\_authorized\_ip\_ranges](#input\_aks\_api\_server\_authorized\_ip\_ranges) | The list of authorized IP ranges to contact the Wayfinder Management AKS Cluster API server. | `list(string)` |
"0.0.0.0/0"
]
[| no | | [aks\_rbac\_aad\_admin\_groups](#input\_aks\_rbac\_aad\_admin\_groups) | Map of Azure AD Groups and their Object IDs that will be set as cluster admin. | `map(string)` | n/a | yes | | [aks\_vnet\_subnet\_id](#input\_aks\_vnet\_subnet\_id) | The ID of the subnet in which to deploy the Kubernetes Cluster. | `string` | `null` | no | | [ca\_org\_name](#input\_ca\_org\_name) | The organisation name to use for the CA. Required if using keyvault cluster issuer. | `string` | `null` | no | @@ -43,7 +95,7 @@ The `terraform-docs` utility is used to generate this README. Follow the below s | [user\_assigned\_identity](#input\_user\_assigned\_identity) | MSI id for AKS to run as | `string` | `null` | no | | [venafi\_apikey](#input\_venafi\_apikey) | Venafi API key - required if using Venafi cluster issuer | `string` | `""` | no | | [venafi\_zone](#input\_venafi\_zone) | Venafi zone - required if using Venafi cluster issuer | `string` | `""` | no | -| [wayfinder\_idp\_details](#input\_wayfinder\_idp\_details) | The IDP details to use for Wayfinder to enable SSO. |
"0.0.0.0/0"
]
object({| n/a | yes | +| [wayfinder\_idp\_details](#input\_wayfinder\_idp\_details) | The IDP details to use for Wayfinder to enable SSO. |
type = string
clientId = string
clientSecret = string
serverUrl = optional(string)
azureTenantId = optional(string)
})
object({| n/a | yes | | [wayfinder\_instance\_id](#input\_wayfinder\_instance\_id) | The instance ID to use for Wayfinder. | `string` | n/a | yes | | [wayfinder\_licence\_key](#input\_wayfinder\_licence\_key) | The licence key to use for Wayfinder. | `string` | n/a | yes | @@ -55,4 +107,5 @@ The `terraform-docs` utility is used to generate this README. Follow the below s | [wayfinder\_api\_url](#output\_wayfinder\_api\_url) | The URL for the Wayfinder API | | [wayfinder\_instance\_id](#output\_wayfinder\_instance\_id) | The unique identifier for the Wayfinder instance | | [wayfinder\_ui\_url](#output\_wayfinder\_ui\_url) | The URL for the Wayfinder UI | - \ No newline at end of file + + diff --git a/examples/quickstart/.terraform-docs.yml b/examples/quickstart/.terraform-docs.yml deleted file mode 100644 index 8573b97..0000000 --- a/examples/quickstart/.terraform-docs.yml +++ /dev/null @@ -1,27 +0,0 @@ -content: |- - # Example: Quickstart - - **Notes:** - * Wayfinder will start up with an initial local administrator user (not configured to use an IDP). - * Any sensitive values (e.g. licence key) are passed directly as a variable to the module. - - This example should be used for product testing and evaluation only. For a more production-ready deployment, please see the [complete example](../complete). - - ## Deployment - - 1. Create a Resource Group for Wayfinder to be installed within. - 2. Create a DNS Zone in Azure and ensure the domain is delegated to the Azure DNS nameservers. - 3. Copy the `terraform.tfvars.example` file to `terraform.tfvars` and update with your values. - 4. Run `terraform init -upgrade` - 5. Run `terraform apply` - - ## Updating Docs - - The `terraform-docs` utility is used to generate this README. Follow the below steps to update: - 1. Make changes to the `.terraform-docs.yml` file - 2. Fetch the `terraform-docs` binary (https://terraform-docs.io/user-guide/installation/) - 3. Run `terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .` - - {{ .Inputs }} - - {{ .Outputs }} diff --git a/examples/quickstart/README.md b/examples/quickstart/README.md index d20912e..115d5a5 100644 --- a/examples/quickstart/README.md +++ b/examples/quickstart/README.md @@ -1,9 +1,9 @@ - # Example: Quickstart **Notes:** -* Wayfinder will start up with an initial local administrator user (not configured to use an IDP). -* Any sensitive values (e.g. licence key) are passed directly as a variable to the module. + +- Wayfinder will start up with an initial local administrator user (not configured to use an IDP). +- Any sensitive values (e.g. licence key) are passed directly as a variable to the module. This example should be used for product testing and evaluation only. For a more production-ready deployment, please see the [complete example](../complete). @@ -18,15 +18,50 @@ This example should be used for product testing and evaluation only. For a more ## Updating Docs The `terraform-docs` utility is used to generate this README. Follow the below steps to update: + 1. Make changes to the `.terraform-docs.yml` file 2. Fetch the `terraform-docs` binary (https://terraform-docs.io/user-guide/installation/) 3. Run `terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3 | +| [azurerm](#requirement\_azurerm) | ~> 3.84 | +| [helm](#requirement\_helm) | ~> 2.9.0 | +| [kubectl](#requirement\_kubectl) | ~> 2.0 | +| [kubernetes](#requirement\_kubernetes) | ~> 2.23.0 | +| [random](#requirement\_random) | ~> 3.5 | +| [time](#requirement\_time) | ~> 0.9.0 | + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | 3.116.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [wayfinder](#module\_wayfinder) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [azurerm_subnet.aks_nodes](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) | resource | +| [azurerm_user_assigned_identity.aks_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | +| [azurerm_virtual_network.wayfinder](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) | resource | +| [azurerm_dns_zone.wayfinder](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/dns_zone) | data source | + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [aks\_api\_server\_authorized\_ip\_ranges](#input\_aks\_api\_server\_authorized\_ip\_ranges) | The list of authorized IP ranges to contact the Wayfinder Management AKS Cluster API server. | `list(string)` |
type = string
clientId = string
clientSecret = string
serverUrl = optional(string)
azureTenantId = optional(string)
})
[| no | +| [aks\_api\_server\_authorized\_ip\_ranges](#input\_aks\_api\_server\_authorized\_ip\_ranges) | The list of authorized IP ranges to contact the Wayfinder Management AKS Cluster API server. | `list(string)` |
"0.0.0.0/0"
]
[| no | | [aks\_rbac\_aad\_admin\_groups](#input\_aks\_rbac\_aad\_admin\_groups) | Map of Azure AD Groups and their Object IDs that will be set as cluster admin. | `map(string)` | n/a | yes | | [clusterissuer\_email](#input\_clusterissuer\_email) | The email address to use for the cert-manager cluster issuer. | `string` | n/a | yes | | [disable\_internet\_access](#input\_disable\_internet\_access) | Whether to disable internet access for AKS and the Wayfinder ingress controller. | `bool` | `false` | no | @@ -51,4 +86,5 @@ The `terraform-docs` utility is used to generate this README. Follow the below s | [wayfinder\_api\_url](#output\_wayfinder\_api\_url) | The URL for the Wayfinder API | | [wayfinder\_instance\_id](#output\_wayfinder\_instance\_id) | The unique identifier for the Wayfinder instance | | [wayfinder\_ui\_url](#output\_wayfinder\_ui\_url) | The URL for the Wayfinder UI | - \ No newline at end of file + + diff --git a/external-dns.tf b/external-dns.tf index bad7e42..696d974 100644 --- a/external-dns.tf +++ b/external-dns.tf @@ -39,7 +39,7 @@ resource "helm_release" "external_dns" { name = "external-dns" repository = "https://kubernetes-sigs.github.io/external-dns" chart = "external-dns" - version = "1.14.4" + version = "1.15.0" max_history = 5 values = [ diff --git a/ingress.tf b/ingress.tf index edfdebd..f97ac7f 100644 --- a/ingress.tf +++ b/ingress.tf @@ -22,7 +22,7 @@ resource "helm_release" "ingress" { name = "ingress-nginx" repository = "https://kubernetes.github.io/ingress-nginx" chart = "ingress-nginx" - version = "4.10.1" + version = "4.11.2" max_history = 5 values = [ diff --git a/modules/cloudaccess/.terraform-docs.yml b/modules/cloudaccess/.terraform-docs.yml deleted file mode 100644 index 6559290..0000000 --- a/modules/cloudaccess/.terraform-docs.yml +++ /dev/null @@ -1,23 +0,0 @@ -content: |- - # Terraform Module: Cloud Access for Wayfinder on Azure - - This Terraform Module can be used to associate Roles to Wayfinder's Azure Identity, for creating resources within an Azure Subscription. - - **Notes:** - * You must set `var.wayfinder_identity_azure_principal_id` to the Azure Principal ID of the Wayfinder Identity. - * `var.resource_suffix` is an optional suffix to use on created objects. We recommend using workspace key + stage if you wish to have multiple workspaces sharing the same AWS account, allowing independent roles to be provisioned for each. - - ## Deployment - - Please see the [examples](./examples) directory to see how to deploy this module. - - {{ .Inputs }} - - {{ .Outputs }} - - ## Updating Docs - - The `terraform-docs` utility is used to generate this README. Follow the below steps to update: - 1. Make changes to the `.terraform-docs.yml` file - 2. Fetch the `terraform-docs` binary (https://terraform-docs.io/user-guide/installation/) - 3. Run `terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .` diff --git a/modules/cloudaccess/README.md b/modules/cloudaccess/README.md index bdab843..49e6165 100644 --- a/modules/cloudaccess/README.md +++ b/modules/cloudaccess/README.md @@ -1,22 +1,30 @@ - # Terraform Module: Cloud Access for Wayfinder on Azure This Terraform Module can be used to associate Roles to Wayfinder's Azure Identity, for creating resources within an Azure Subscription. **Notes:** -* You must set `var.wayfinder_identity_azure_principal_id` to the Azure Principal ID of the Wayfinder Identity. -* `var.resource_suffix` is an optional suffix to use on created objects. We recommend using workspace key + stage if you wish to have multiple workspaces sharing the same AWS account, allowing independent roles to be provisioned for each. + +- You must set `var.wayfinder_identity_azure_principal_id` to the Azure Principal ID of the Wayfinder Identity. +- `var.resource_suffix` is an optional suffix to use on created objects. We recommend using workspace key + stage if you wish to have multiple workspaces sharing the same AWS account, allowing independent roles to be provisioned for each. ## Deployment Please see the [examples](./examples) directory to see how to deploy this module. + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | >=3.74.0 | +| [time](#provider\_time) | >= 0.9.0 | + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [create\_duration\_delay](#input\_create\_duration\_delay) | Used to tune terraform apply when faced with errors caused by API caching or eventual consistency. Sets a custom delay period after creation of the specified resource type. |
"0.0.0.0/0"
]
object({| `{}` | no | -| [destroy\_duration\_delay](#input\_destroy\_duration\_delay) | Used to tune terraform destroy when faced with errors caused by API caching or eventual consistency. Sets a custom delay period after destruction of the specified resource type. |
azurerm_role_definition = optional(string, "30s")
})
object({| `{}` | no | +| [create\_duration\_delay](#input\_create\_duration\_delay) | Used to tune terraform apply when faced with errors caused by API caching or eventual consistency. Sets a custom delay period after creation of the specified resource type. |
azurerm_role_definition = optional(string, "0s")
})
object({| `{}` | no | +| [destroy\_duration\_delay](#input\_destroy\_duration\_delay) | Used to tune terraform destroy when faced with errors caused by API caching or eventual consistency. Sets a custom delay period after destruction of the specified resource type. |
azurerm_role_definition = optional(string, "30s")
})
object({| `{}` | no | | [enable\_cloud\_info](#input\_enable\_cloud\_info) | Whether to create the Cloud Info IAM Role | `bool` | `false` | no | | [enable\_cluster\_manager](#input\_enable\_cluster\_manager) | Whether to create the Cluster Manager IAM Role | `bool` | `false` | no | | [enable\_dns\_zone\_manager](#input\_enable\_dns\_zone\_manager) | Whether to create the DNS Zone Manager IAM Role | `bool` | `false` | no | @@ -39,11 +47,5 @@ Please see the [examples](./examples) directory to see how to deploy this module |------|-------------| | [managed\_identity\_client\_id](#output\_managed\_identity\_client\_id) | The client ID of the created managed identity to use as spec.azure.clientID in your cloud access configuration | | [managed\_identity\_tenant\_id](#output\_managed\_identity\_tenant\_id) | The tenant ID in which the managed identity exists, to use as spec.azure.tenantID in your cloud access configuration | + -## Updating Docs - -The `terraform-docs` utility is used to generate this README. Follow the below steps to update: -1. Make changes to the `.terraform-docs.yml` file -2. Fetch the `terraform-docs` binary (https://terraform-docs.io/user-guide/installation/) -3. Run `terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .` - \ No newline at end of file diff --git a/modules/cloudaccess/examples/complete/.terraform.lock.hcl b/modules/cloudaccess/examples/complete/.terraform.lock.hcl new file mode 100644 index 0000000..460a48c --- /dev/null +++ b/modules/cloudaccess/examples/complete/.terraform.lock.hcl @@ -0,0 +1,42 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "4.6.0" + constraints = ">= 3.74.0" + hashes = [ + "h1:dnb4t07g8JX1xNSW5Rsx9VTriKKst0bsquJNmvtqEN0=", + "zh:13107f35a7060efa62570e3482285003092ead0afa0fa9fa1b0dda4f70080cb9", + "zh:22703b9f318adbda7e75d50e76b345651cbf371bce227566a8b8532c9c4f0880", + "zh:601d1eb1c056e4de649561764056e3dc21b837d104d15fee31f9aaaacb292046", + "zh:6572232f9b0d20b149e8b5cf161fada6d8122ee1fea732c2f1e9402fe4d3375f", + "zh:6c19ab78c6cf7eb04b8db978daa611db04598fd490c90b85889d08726da1d095", + "zh:7f6eae5fa14def221422fdd34ea122ea0263d0c3c67eb0fd7870d664d7d7a360", + "zh:8530912ffcc8a92dd5c186ecd08a9c2f1282838a3ad5a71786c2866402c71da7", + "zh:a6b110c6cff0ed8c1a8969bd86583db1d5b4f3100f89ce0a0e0350b1ad8cd47b", + "zh:bd67b5d92e06bc44b166f4cabab189de5cc06506333283ac88b4ce21707b8c6b", + "zh:c472fdcafbca86a0a5b515378409d0bbddff6a6abb0bd0ecf438c610944b1e98", + "zh:ca4bb3797ddf20062995134211b50e313242c8a81aa5da63cc51a47e42f494c4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/time" { + version = "0.12.1" + constraints = ">= 0.9.0" + hashes = [ + "h1:JzYsPugN8Fb7C4NlfLoFu7BBPuRVT2/fCOdCaxshveI=", + "zh:090023137df8effe8804e81c65f636dadf8f9d35b79c3afff282d39367ba44b2", + "zh:26f1e458358ba55f6558613f1427dcfa6ae2be5119b722d0b3adb27cd001efea", + "zh:272ccc73a03384b72b964918c7afeb22c2e6be22460d92b150aaf28f29a7d511", + "zh:438b8c74f5ed62fe921bd1078abe628a6675e44912933100ea4fa26863e340e9", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:85c8bd8eefc4afc33445de2ee7fbf33a7807bc34eb3734b8eefa4e98e4cddf38", + "zh:98bbe309c9ff5b2352de6a047e0ec6c7e3764b4ed3dfd370839c4be2fbfff869", + "zh:9c7bf8c56da1b124e0e2f3210a1915e778bab2be924481af684695b52672891e", + "zh:d2200f7f6ab8ecb8373cda796b864ad4867f5c255cff9d3b032f666e4c78f625", + "zh:d8c7926feaddfdc08d5ebb41b03445166df8c125417b28d64712dccd9feef136", + "zh:e2412a192fc340c61b373d6c20c9d805d7d3dee6c720c34db23c2a8ff0abd71b", + "zh:e6ac6bba391afe728a099df344dbd6481425b06d61697522017b8f7a59957d44", + ] +} diff --git a/modules/cloudaccess/examples/complete/README.md b/modules/cloudaccess/examples/complete/README.md new file mode 100644 index 0000000..7d1f109 --- /dev/null +++ b/modules/cloudaccess/examples/complete/README.md @@ -0,0 +1,31 @@ + +## Providers + +No providers. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [region](#input\_region) | The region used for created resources (where required) | `string` | n/a | yes | +| [enable\_cloud\_info](#input\_enable\_cloud\_info) | Whether to create the Cloud Info IAM Role | `bool` | `false` | no | +| [enable\_cluster\_manager](#input\_enable\_cluster\_manager) | Whether to create the Cluster Manager IAM Role | `bool` | `true` | no | +| [enable\_dns\_zone\_manager](#input\_enable\_dns\_zone\_manager) | Whether to create the DNS Zone Manager IAM Role | `bool` | `true` | no | +| [enable\_network\_manager](#input\_enable\_network\_manager) | Whether to create the Network Manager IAM Role | `bool` | `true` | no | +| [enable\_peering\_acceptor](#input\_enable\_peering\_acceptor) | Whether to create the Peering Acceptor IAM Role | `bool` | `false` | no | +| [from\_aws](#input\_from\_aws) | Whether Wayfinder is running on AWS. | `bool` | `false` | no | +| [from\_azure](#input\_from\_azure) | Whether Wayfinder is running on Azure. | `bool` | `true` | no | +| [from\_gcp](#input\_from\_gcp) | Whether Wayfinder is running on GCP. | `bool` | `false` | no | +| [resource\_suffix](#input\_resource\_suffix) | Suffix to apply to all generated resources. We recommend using workspace key + stage. | `string` | `""` | no | +| [wayfinder\_identity\_aws\_issuer](#input\_wayfinder\_identity\_aws\_issuer) | Issuer URL to trust to verify Wayfinder's AWS identity. Populate when Wayfinder is running on AWS with IRSA. | `string` | `""` | no | +| [wayfinder\_identity\_aws\_subject](#input\_wayfinder\_identity\_aws\_subject) | Subject to trust to verify Wayfinder's AWS identity. Populate when Wayfinder is running on AWS with IRSA. | `string` | `""` | no | +| [wayfinder\_identity\_azure\_principal\_id](#input\_wayfinder\_identity\_azure\_principal\_id) | Principal ID of Wayfinder's Azure AD managed identity to give access to. Populate when Wayfinder is running on Azure with AzureAD Workload Identity or when using a credential-based Azure identity. | `string` | `""` | no | +| [wayfinder\_identity\_gcp\_service\_account\_id](#input\_wayfinder\_identity\_gcp\_service\_account\_id) | Numerical ID of Wayfinder's GCP service account to give access to. Populate when Wayfinder is running on GCP with Workload Identity. | `string` | `""` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [managed\_identity\_client\_id](#output\_managed\_identity\_client\_id) | n/a | +| [managed\_identity\_tenant\_id](#output\_managed\_identity\_tenant\_id) | n/a | + \ No newline at end of file diff --git a/modules/cloudaccess/wf_cloud_info.tf b/modules/cloudaccess/wf_cloud_info.tf index eb5dc0e..8f6618c 100644 --- a/modules/cloudaccess/wf_cloud_info.tf +++ b/modules/cloudaccess/wf_cloud_info.tf @@ -30,9 +30,9 @@ resource "time_sleep" "after_azurerm_role_definition_cloudinfo" { resource "azurerm_role_assignment" "cloudinfo" { count = var.enable_cloud_info && var.from_azure ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.cloudinfo[0].name - principal_id = var.wayfinder_identity_azure_principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.cloudinfo[0].id + principal_id = var.wayfinder_identity_azure_principal_id depends_on = [ time_sleep.after_azurerm_role_definition_cloudinfo[0], @@ -43,9 +43,9 @@ resource "azurerm_role_assignment" "cloudinfo" { resource "azurerm_role_assignment" "cloudinfo_federated" { count = var.enable_cloud_info && (var.from_aws || var.from_gcp) ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.cloudinfo[0].name - principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.cloudinfo[0].id + principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id depends_on = [ time_sleep.after_azurerm_role_definition_cloudinfo[0], diff --git a/modules/cloudaccess/wf_cluster_manager.tf b/modules/cloudaccess/wf_cluster_manager.tf index 99a2cad..a6662a3 100644 --- a/modules/cloudaccess/wf_cluster_manager.tf +++ b/modules/cloudaccess/wf_cluster_manager.tf @@ -30,9 +30,9 @@ resource "time_sleep" "after_azurerm_role_definition_clustermanager" { resource "azurerm_role_assignment" "clustermanager" { count = var.enable_cluster_manager && var.from_azure ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.clustermanager[0].name - principal_id = var.wayfinder_identity_azure_principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.clustermanager[0].role_definition_resource_id + principal_id = var.wayfinder_identity_azure_principal_id depends_on = [ time_sleep.after_azurerm_role_definition_clustermanager[0], @@ -43,9 +43,9 @@ resource "azurerm_role_assignment" "clustermanager" { resource "azurerm_role_assignment" "clustermanager_federated" { count = var.enable_cluster_manager && (var.from_aws || var.from_gcp) ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.clustermanager[0].name - principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.clustermanager[0].role_definition_resource_id + principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id depends_on = [ time_sleep.after_azurerm_role_definition_clustermanager[0], diff --git a/modules/cloudaccess/wf_dnszone_manager.tf b/modules/cloudaccess/wf_dnszone_manager.tf index 3860d86..b96e02a 100644 --- a/modules/cloudaccess/wf_dnszone_manager.tf +++ b/modules/cloudaccess/wf_dnszone_manager.tf @@ -30,9 +30,9 @@ resource "time_sleep" "after_azurerm_role_definition_dnszonemanager" { resource "azurerm_role_assignment" "dnszonemanager" { count = var.enable_dns_zone_manager && var.from_azure ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.dnszonemanager[0].name - principal_id = var.wayfinder_identity_azure_principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.dnszonemanager[0].role_definition_resource_id + principal_id = var.wayfinder_identity_azure_principal_id depends_on = [ time_sleep.after_azurerm_role_definition_dnszonemanager[0], @@ -43,9 +43,9 @@ resource "azurerm_role_assignment" "dnszonemanager" { resource "azurerm_role_assignment" "dnszonemanager_federated" { count = var.enable_dns_zone_manager && (var.from_aws || var.from_gcp) ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.dnszonemanager[0].name - principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.dnszonemanager[0].role_definition_resource_id + principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id depends_on = [ time_sleep.after_azurerm_role_definition_dnszonemanager[0], diff --git a/modules/cloudaccess/wf_network_manager.tf b/modules/cloudaccess/wf_network_manager.tf index 7087e2b..1f08fa6 100644 --- a/modules/cloudaccess/wf_network_manager.tf +++ b/modules/cloudaccess/wf_network_manager.tf @@ -30,9 +30,9 @@ resource "time_sleep" "after_azurerm_role_definition_networkmanager" { resource "azurerm_role_assignment" "networkmanager" { count = var.enable_network_manager && var.from_azure ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.networkmanager[0].name - principal_id = var.wayfinder_identity_azure_principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.networkmanager[0].role_definition_resource_id + principal_id = var.wayfinder_identity_azure_principal_id depends_on = [ time_sleep.after_azurerm_role_definition_networkmanager[0], @@ -43,9 +43,9 @@ resource "azurerm_role_assignment" "networkmanager" { resource "azurerm_role_assignment" "networkmanager_federated" { count = var.enable_network_manager && (var.from_aws || var.from_gcp) ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.networkmanager[0].name - principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.networkmanager[0].role_definition_resource_id + principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id depends_on = [ time_sleep.after_azurerm_role_definition_networkmanager[0], diff --git a/modules/cloudaccess/wf_peering_acceptor.tf b/modules/cloudaccess/wf_peering_acceptor.tf index b441442..cc47a5c 100644 --- a/modules/cloudaccess/wf_peering_acceptor.tf +++ b/modules/cloudaccess/wf_peering_acceptor.tf @@ -30,9 +30,9 @@ resource "time_sleep" "after_azurerm_role_definition_peeringacceptor" { resource "azurerm_role_assignment" "peeringacceptor" { count = var.enable_peering_acceptor && var.from_azure ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.peeringacceptor[0].name - principal_id = var.wayfinder_identity_azure_principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.peeringacceptor[0].role_definition_resource_id + principal_id = var.wayfinder_identity_azure_principal_id depends_on = [ time_sleep.after_azurerm_role_definition_peeringacceptor[0], @@ -43,9 +43,9 @@ resource "azurerm_role_assignment" "peeringacceptor" { resource "azurerm_role_assignment" "peeringacceptor_federated" { count = var.enable_peering_acceptor && (var.from_aws || var.from_gcp) ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.peeringacceptor[0].name - principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.peeringacceptor[0].role_definition_resource_id + principal_id = azurerm_user_assigned_identity.federated_identity[0].principal_id depends_on = [ time_sleep.after_azurerm_role_definition_peeringacceptor[0], diff --git a/modules/cloudaccess/wf_privatelink_manager.tf b/modules/cloudaccess/wf_privatelink_manager.tf index de894d6..eb50685 100644 --- a/modules/cloudaccess/wf_privatelink_manager.tf +++ b/modules/cloudaccess/wf_privatelink_manager.tf @@ -30,9 +30,9 @@ resource "time_sleep" "after_azurerm_role_definition_privatelinkmanager" { resource "azurerm_role_assignment" "privatelinkmanager" { count = var.enable_private_link_manager && var.from_azure ? 1 : 0 - scope = data.azurerm_subscription.primary.id - role_definition_name = azurerm_role_definition.privatelinkmanager[0].name - principal_id = var.wayfinder_identity_azure_principal_id + scope = data.azurerm_subscription.primary.id + role_definition_id = azurerm_role_definition.privatelinkmanager[0].role_definition_resource_id + principal_id = var.wayfinder_identity_azure_principal_id depends_on = [ time_sleep.after_azurerm_role_definition_privatelinkmanager[0], diff --git a/versions.tf b/terraform.tf similarity index 86% rename from versions.tf rename to terraform.tf index acadbe0..d03ccef 100644 --- a/versions.tf +++ b/terraform.tf @@ -22,10 +22,6 @@ terraform { source = "hashicorp/time" version = ">= 0.9.0" } - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.23.0" - } random = { source = "hashicorp/random" version = ">= 3.5" diff --git a/variables.tf b/variables.tf index 94f4664..09cb4a3 100644 --- a/variables.tf +++ b/variables.tf @@ -336,5 +336,5 @@ variable "wayfinder_release_channel" { variable "wayfinder_version" { description = "The version to use for Wayfinder" type = string - default = "v2.8.6" + default = "v2.9.6" }
azurerm_role_definition = optional(string, "0s")
})