Skip to content

Commit fe94eda

Browse files
committed
Refactor module
- align variable names - conditional creation - remove all inputs from the example
1 parent 7710b16 commit fe94eda

File tree

16 files changed

+525
-320
lines changed

16 files changed

+525
-320
lines changed

integrations/terraform-modules/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ docs: $(README_FILES) ;
2121
terraform-docs markdown table --config .terraform-docs.yml $*
2222

2323
.PHONY: check
24-
check:
24+
check: clean
2525
git ls-files -- . \
2626
| xargs pre-commit run --hook-stage=manual --verbose --files
2727

integrations/terraform-modules/teleport/discovery/azure/README.md

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This Terraform module creates the Azure and Teleport cluster resources necessary for a Teleport cluster to discover Azure virtual machines:
44

5-
- **Azure user-assigned managed identity**: Used by the Teleport Discovery Service to authenticate to Azure APIs for scanning and managing VMs in the specified resource groups.
5+
- **Azure user-assigned managed identity**: Used by the Teleport Discovery Service to authenticate to Azure APIs for scanning and managing VMs in matching Azure resource groups.
66
- **Azure federated identity credential**: Establishes trust between Azure and your Teleport cluster by allowing the managed identity to authenticate using OIDC tokens issued by your Teleport proxy.
77
- **Azure custom role definition and assignment**: Grants the managed identity the minimum required permissions to discover VMs and run installation commands on them.
88
- **Teleport `discovery_config` cluster resource**: Configures the discovery parameters (subscriptions, resource groups, tags) that determine which Azure VMs will be discovered and enrolled.
@@ -12,7 +12,7 @@ This Terraform module creates the Azure and Teleport cluster resources necessary
1212
## Prerequisites
1313

1414
- [Install Teleport Terraform Provider](https://goteleport.com/docs/zero-trust-access/infrastructure-as-code/terraform-provider/)
15-
- Every Azure VM to be discovered must have a managed identity assigned to it with at least the Microsoft.Compute/virtualMachines/read permission. [Read more](https://goteleport.com/docs/enroll-resources/auto-discovery/servers/azure-discovery/#step-35-set-up-managed-identities-for-discovered-nodes)
15+
- Every Azure VM to be discovered must have a managed identity assigned to it with at least the Microsoft.Compute/virtualMachines/read permission. [Read more](https://goteleport.com/docs/enroll-resources/auto-discovery/servers/azure-discovery/#step-35-set-up-managed-identities-for-discovered-nodes)
1616

1717
## Examples
1818

@@ -29,16 +29,18 @@ For bugs related to this code, please [open an issue](https://github.com/gravita
2929

3030
| Name | Version |
3131
|------|---------|
32-
| <a name="requirement_terraform"></a> [terraform](#requirement_terraform) | >= 1.6.0 |
33-
| <a name="requirement_azurerm"></a> [azurerm](#requirement_azurerm) | ~> 4.0 |
34-
| <a name="requirement_teleport"></a> [teleport](#requirement_teleport) | ~> 18.7 |
32+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
33+
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >= 4.0 |
34+
| <a name="requirement_http"></a> [http](#requirement\_http) | >= 3.0 |
35+
| <a name="requirement_teleport"></a> [teleport](#requirement\_teleport) | >= 18.5.1 |
3536

3637
## Providers
3738

3839
| Name | Version |
3940
|------|---------|
40-
| <a name="provider_azurerm"></a> [azurerm](#provider_azurerm) | ~> 4.0 |
41-
| <a name="provider_teleport"></a> [teleport](#provider_teleport) | ~> 18.7 |
41+
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >= 4.0 |
42+
| <a name="provider_http"></a> [http](#provider\_http) | >= 3.0 |
43+
| <a name="provider_teleport"></a> [teleport](#provider\_teleport) | >= 18.5.1 |
4244

4345
## Modules
4446

@@ -48,41 +50,51 @@ No modules.
4850

4951
| Name | Type |
5052
|------|------|
51-
| [azurerm_federated_identity_credential.teleport](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource |
52-
| [azurerm_role_assignment.teleport_discovery_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
53+
| [azurerm_federated_identity_credential.teleport_discovery_service](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource |
54+
| [azurerm_role_assignment.teleport_discovery](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
5355
| [azurerm_role_definition.teleport_discovery](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
54-
| [azurerm_user_assigned_identity.teleport](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
55-
| teleport_discovery_config.azure_teleport | resource |
56+
| [azurerm_user_assigned_identity.teleport_discovery_service](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
57+
| teleport_discovery_config.azure | resource |
5658
| teleport_integration.azure_oidc | resource |
57-
| teleport_provision_token.azure_token | resource |
59+
| teleport_provision_token.azure | resource |
60+
| [azurerm_client_config.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source |
61+
| [http_http.teleport_ping](https://registry.terraform.io/providers/hashicorp/http/latest/docs/data-sources/http) | data source |
5862

5963
## Inputs
6064

6165
| Name | Description | Type | Default | Required |
6266
|------|-------------|------|---------|:--------:|
63-
| <a name="input_discovery_group_name"></a> [discovery_group_name](#input_discovery_group_name) | Teleport discovery group name. | `string` | `"cloud-discovery-group"` | no |
64-
| <a name="input_discovery_resource_group_names"></a> [discovery_resource_group_names](#input_discovery_resource_group_names) | Resource groups to scan for VMs. | `list(string)` | n/a | yes |
65-
| <a name="input_discovery_tags"></a> [discovery_tags](#input_discovery_tags) | Tag filters for VM discovery; matches VMs with these tags. | `map(list(string))` | <pre>{<br/> "*": [<br/> "*"<br/> ]<br/>}</pre> | no |
66-
| <a name="input_identity_resource_group_name"></a> [identity_resource_group_name](#input_identity_resource_group_name) | Resource group to place identity resources; defaults to first discovery RG when empty. | `string` | `""` | no |
67-
| <a name="input_integration_name_override"></a> [integration_name_override](#input_integration_name_override) | Override for Teleport integration name; empty to derive from prefix. | `string` | `""` | no |
68-
| <a name="input_installer_script_name"></a> [installer_script_name](#input_installer_script_name) | Name of the Teleport installer script to use. | `string` | `"default-installer"` | no |
69-
| <a name="input_prefix"></a> [prefix](#input_prefix) | Name prefix for created resources. | `string` | `"teleport"` | no |
70-
| <a name="input_proxy_addr"></a> [proxy_addr](#input_proxy_addr) | Teleport proxy address (host:port). | `string` | n/a | yes |
71-
| <a name="input_region"></a> [region](#input_region) | Azure region for created resources (identities). | `string` | n/a | yes |
72-
| <a name="input_subscription_id"></a> [subscription_id](#input_subscription_id) | Azure subscription ID for discovery scope. | `string` | n/a | yes |
73-
| <a name="input_tags"></a> [tags](#input_tags) | Tags applied to Azure resources created by the module. | `map(string)` | `{}` | no |
74-
| <a name="input_tenant_id"></a> [tenant_id](#input_tenant_id) | Azure AD tenant ID. | `string` | n/a | yes |
75-
| <a name="input_token_name_override"></a> [token_name_override](#input_token_name_override) | Override for Teleport provision token name; empty to derive from prefix. | `string` | `""` | no |
67+
| <a name="input_apply_azure_tags"></a> [apply\_azure\_tags](#input\_apply\_azure\_tags) | Additional Azure tags to apply to all created Azure resources. | `map(string)` | `{}` | no |
68+
| <a name="input_apply_teleport_resource_labels"></a> [apply\_teleport\_resource\_labels](#input\_apply\_teleport\_resource\_labels) | Additional Teleport resource labels to apply to all created Teleport resources. | `map(string)` | `{}` | no |
69+
| <a name="input_azure_federated_identity_credential_name"></a> [azure\_federated\_identity\_credential\_name](#input\_azure\_federated\_identity\_credential\_name) | Name of the Azure federated identity credential created for workload identity federation. | `string` | `"teleport-federation"` | no |
70+
| <a name="input_azure_managed_identity_location"></a> [azure\_managed\_identity\_location](#input\_azure\_managed\_identity\_location) | Azure region (location) where the managed identity will be created (e.g., "westus"). | `string` | n/a | yes |
71+
| <a name="input_azure_managed_identity_name"></a> [azure\_managed\_identity\_name](#input\_azure\_managed\_identity\_name) | Name of the Azure user-assigned managed identity created for Teleport Discovery. | `string` | `"discovery-identity"` | no |
72+
| <a name="input_azure_resource_group_name"></a> [azure\_resource\_group\_name](#input\_azure\_resource\_group\_name) | Name of an existing Azure Resource Group where Azure resources will be created. | `string` | n/a | yes |
73+
| <a name="input_azure_role_definition_name"></a> [azure\_role\_definition\_name](#input\_azure\_role\_definition\_name) | Name for the Azure custom role definition created for Teleport Discovery. | `string` | `"teleport-discovery"` | no |
74+
| <a name="input_create"></a> [create](#input\_create) | Toggle creation of all resources. | `bool` | `true` | no |
75+
| <a name="input_match_azure_regions"></a> [match\_azure\_regions](#input\_match\_azure\_regions) | Azure regions to discover. Defaults to ["*"] which matches all regions. Region names should be the programmatic region name, e.g., "westus". | `list(string)` | <pre>[<br/> "*"<br/>]</pre> | no |
76+
| <a name="input_match_azure_resource_groups"></a> [match\_azure\_resource\_groups](#input\_match\_azure\_resource\_groups) | Azure resource groups to scan for VMs. Defaults to ["*"] which matches all resource groups. | `list(string)` | <pre>[<br/> "*"<br/>]</pre> | no |
77+
| <a name="input_match_azure_tags"></a> [match\_azure\_tags](#input\_match\_azure\_tags) | Tag filters for VM discovery; matches VMs with these tags. Defaults to {"*" = ["*"]} which matches all tags. | `map(list(string))` | <pre>{<br/> "*": [<br/> "*"<br/> ]<br/>}</pre> | no |
78+
| <a name="input_teleport_discovery_config_name"></a> [teleport\_discovery\_config\_name](#input\_teleport\_discovery\_config\_name) | Name for the `teleport_discovery_config` resource. | `string` | `"discovery"` | no |
79+
| <a name="input_teleport_discovery_config_use_name_prefix"></a> [teleport\_discovery\_config\_use\_name\_prefix](#input\_teleport\_discovery\_config\_use\_name\_prefix) | Whether `teleport_discovery_config_name` is used as a name prefix (true) or as the exact name (false). | `bool` | `true` | no |
80+
| <a name="input_teleport_discovery_group_name"></a> [teleport\_discovery\_group\_name](#input\_teleport\_discovery\_group\_name) | Teleport discovery group to use. For discovery configuration to apply, this name must match at least one Teleport Discovery Service instance's configured `discovery_group`. For Teleport Cloud clusters, use "cloud-discovery-group". | `string` | n/a | yes |
81+
| <a name="input_teleport_installer_script_name"></a> [teleport\_installer\_script\_name](#input\_teleport\_installer\_script\_name) | Name of an existing Teleport installer script to use. | `string` | `"default-installer"` | no |
82+
| <a name="input_teleport_integration_name"></a> [teleport\_integration\_name](#input\_teleport\_integration\_name) | Name for the `teleport_integration` resource. | `string` | `"discovery"` | no |
83+
| <a name="input_teleport_integration_use_name_prefix"></a> [teleport\_integration\_use\_name\_prefix](#input\_teleport\_integration\_use\_name\_prefix) | Whether `teleport_integration_name` is used as a name prefix (true) or as the exact name (false). | `bool` | `true` | no |
84+
| <a name="input_teleport_provision_token_name"></a> [teleport\_provision\_token\_name](#input\_teleport\_provision\_token\_name) | Name for the `teleport_provision_token` resource. | `string` | `"discovery"` | no |
85+
| <a name="input_teleport_provision_token_use_name_prefix"></a> [teleport\_provision\_token\_use\_name\_prefix](#input\_teleport\_provision\_token\_use\_name\_prefix) | Whether `teleport_provision_token_name` is used as a name prefix (true) or as the exact name (false). | `bool` | `true` | no |
86+
| <a name="input_teleport_proxy_public_addr"></a> [teleport\_proxy\_public\_addr](#input\_teleport\_proxy\_public\_addr) | Teleport cluster proxy public address in the form <host:port> (no URL scheme). | `string` | n/a | yes |
7687

7788
## Outputs
7889

7990
| Name | Description |
8091
|------|-------------|
81-
| <a name="output_client_id"></a> [client_id](#output_client_id) | Client ID used by the Teleport Azure OIDC integration. |
82-
| <a name="output_integration_name"></a> [integration_name](#output_integration_name) | Teleport integration resource name. |
83-
| <a name="output_managed_identity_id"></a> [managed_identity_id](#output_managed_identity_id) | Managed identity resource ID. |
84-
| <a name="output_principal_id"></a> [principal_id](#output_principal_id) | Principal ID used for role assignment. |
85-
| <a name="output_role_assignment_id"></a> [role_assignment_id](#output_role_assignment_id) | ID of the role assignment granting discovery permissions. |
86-
| <a name="output_role_definition_id"></a> [role_definition_id](#output_role_definition_id) | ID of the custom role definition. |
87-
| <a name="output_token_name"></a> [token_name](#output_token_name) | Teleport provision token name. |
92+
| <a name="output_azure_managed_identity_client_id"></a> [azure\_managed\_identity\_client\_id](#output\_azure\_managed\_identity\_client\_id) | Client ID used by the Teleport Azure OIDC integration. |
93+
| <a name="output_azure_managed_identity_id"></a> [azure\_managed\_identity\_id](#output\_azure\_managed\_identity\_id) | Managed identity resource ID. |
94+
| <a name="output_azure_managed_identity_principal_id"></a> [azure\_managed\_identity\_principal\_id](#output\_azure\_managed\_identity\_principal\_id) | Principal ID used for role assignment. |
95+
| <a name="output_azure_role_assignment_id"></a> [azure\_role\_assignment\_id](#output\_azure\_role\_assignment\_id) | ID of the role assignment granting discovery permissions. |
96+
| <a name="output_azure_role_definition_id"></a> [azure\_role\_definition\_id](#output\_azure\_role\_definition\_id) | ID of the discovery role definition. |
97+
| <a name="output_teleport_discovery_config_name"></a> [teleport\_discovery\_config\_name](#output\_teleport\_discovery\_config\_name) | Name of the Teleport dynamic `discovery_config`. Configuration details can be viewed with `tctl get discovery_config/<name>`. Teleport Discovery Service instances will use this `discovery_config` if they are in the same discovery group as the `discovery_config`. |
98+
| <a name="output_teleport_integration_name"></a> [teleport\_integration\_name](#output\_teleport\_integration\_name) | Name of the Teleport `integration` resource. The integration resource configures Teleport Discovery Service instances to assume an Azure managed identity for discovery using Azure OIDC federation. Integration details can be viewed with `tctl get integrations/<name>` or by visiting the Teleport web UI under 'Zero Trust Access' > 'Integrations'. |
99+
| <a name="output_teleport_provision_token_name"></a> [teleport\_provision\_token\_name](#output\_teleport\_provision\_token\_name) | Name of the Teleport provision `token` that allows Teleport nodes to join the Teleport cluster using Azure credentials. Token details can be viewed with `tctl get token/<name>`. |
88100
<!-- END_TF_DOCS -->
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
################################################################################
2+
# Managed identity + federation
3+
################################################################################
4+
5+
# User-assigned managed identity for discovery
6+
resource "azurerm_user_assigned_identity" "teleport_discovery_service" {
7+
count = local.create ? 1 : 0
8+
9+
location = var.azure_managed_identity_location
10+
name = var.azure_managed_identity_name
11+
resource_group_name = var.azure_resource_group_name
12+
tags = local.apply_azure_tags
13+
}
14+
15+
# Federated identity credential for the managed identity (trust Teleport proxy issuer)
16+
resource "azurerm_federated_identity_credential" "teleport_discovery_service" {
17+
count = local.create ? 1 : 0
18+
19+
audience = ["api://AzureADTokenExchange"]
20+
# Extract the host from proxy_addr (format: host:port) to construct the OIDC issuer URL
21+
issuer = replace(local.teleport_proxy_public_url, "/:[0-9]+.*/", "")
22+
name = var.azure_federated_identity_credential_name
23+
parent_id = one(azurerm_user_assigned_identity.teleport_discovery_service[*].id)
24+
resource_group_name = var.azure_resource_group_name
25+
subject = "teleport-azure"
26+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
################################################################################
2+
# Azure role for Teleport Discovery Service
3+
################################################################################
4+
5+
# Custom role for discovery permissions
6+
resource "azurerm_role_definition" "teleport_discovery" {
7+
count = local.create ? 1 : 0
8+
9+
assignable_scopes = ["/subscriptions/${local.azure_subscription_id}"]
10+
description = "Azure role that allows a Teleport Discovery Service to discover VMs."
11+
name = var.azure_role_definition_name
12+
scope = "/subscriptions/${local.azure_subscription_id}"
13+
14+
permissions {
15+
actions = [
16+
"Microsoft.Compute/virtualMachines/read",
17+
"Microsoft.Compute/virtualMachines/runCommand/action",
18+
"Microsoft.Compute/virtualMachines/runCommands/write",
19+
"Microsoft.Compute/virtualMachines/runCommands/read",
20+
"Microsoft.Compute/virtualMachines/runCommands/delete",
21+
]
22+
not_actions = []
23+
}
24+
}
25+
26+
# Assign the custom role to the managed identity principal
27+
resource "azurerm_role_assignment" "teleport_discovery" {
28+
count = local.create ? 1 : 0
29+
30+
principal_id = one(azurerm_user_assigned_identity.teleport_discovery_service[*].principal_id)
31+
role_definition_id = one(azurerm_role_definition.teleport_discovery[*].role_definition_resource_id)
32+
scope = "/subscriptions/${local.azure_subscription_id}"
33+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!-- BEGIN_TF_DOCS -->
2+
## Requirements
3+
4+
| Name | Version |
5+
|------|---------|
6+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
7+
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >= 4.0 |
8+
| <a name="requirement_http"></a> [http](#requirement\_http) | >= 3.0 |
9+
| <a name="requirement_teleport"></a> [teleport](#requirement\_teleport) | >= 18.5.1 |
10+
11+
## Providers
12+
13+
| Name | Version |
14+
|------|---------|
15+
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >= 4.0 |
16+
| <a name="provider_teleport"></a> [teleport](#provider\_teleport) | >= 18.5.1 |
17+
18+
## Modules
19+
20+
| Name | Source | Version |
21+
|------|--------|---------|
22+
| <a name="module_azure_discovery"></a> [azure\_discovery](#module\_azure\_discovery) | ../.. | n/a |
23+
24+
## Resources
25+
26+
| Name | Type |
27+
|------|------|
28+
| [azurerm_resource_group.example](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
29+
| teleport_installer.example | resource |
30+
31+
## Inputs
32+
33+
No inputs.
34+
35+
## Outputs
36+
37+
| Name | Description |
38+
|------|-------------|
39+
| <a name="output_azure_discovery"></a> [azure\_discovery](#output\_azure\_discovery) | n/a |
40+
<!-- END_TF_DOCS -->

0 commit comments

Comments
 (0)