Skip to content

Commit

Permalink
DOM-54281 Add support for shared access signatures (#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
pocheung1 authored Mar 29, 2024
1 parent 683a7c6 commit 78bfa99
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 92 deletions.
33 changes: 20 additions & 13 deletions modules/flyte/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,34 @@ No modules.

| Name | Type |
|------|------|
| [azuread_group.flyte_data_access](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group) | resource |
| [azuread_group.flyte_metadata_access](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group) | resource |
| [azuread_group.flyte_data](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group) | resource |
| [azuread_group.flyte_metadata](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group) | resource |
| [azuread_group.flyte_sas](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group) | resource |
| [azurerm_federated_identity_credential.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource |
| [azurerm_role_assignment.flyte_data_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.flyte_metadata_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_definition.flyte_storage_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
| [azurerm_role_assignment.flyte_data](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.flyte_metadata](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.flyte_sas](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_definition.flyte_data](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
| [azurerm_role_definition.flyte_metadata](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
| [azurerm_role_definition.flyte_sas](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
| [azurerm_storage_account.flyte](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account) | resource |
| [azurerm_storage_container.flyte_data](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container) | resource |
| [azurerm_storage_container.flyte_metadata](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container) | resource |
| [azurerm_user_assigned_identity.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azurerm_user_assigned_identity.flyte_controlplane](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azurerm_user_assigned_identity.flyte_dataplane](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_azurerm_kubernetes_cluster_oidc_issuer_url"></a> [azurerm\_kubernetes\_cluster\_oidc\_issuer\_url](#input\_azurerm\_kubernetes\_cluster\_oidc\_issuer\_url) | AzureRM Kubernetes Cluster OIDC issuer url | `string` | n/a | yes |
| <a name="input_azurerm_resource_group_location"></a> [azurerm\_resource\_group\_location](#input\_azurerm\_resource\_group\_location) | AzureRM Resource Group location | `string` | n/a | yes |
| <a name="input_azurerm_resource_group_name"></a> [azurerm\_resource\_group\_name](#input\_azurerm\_resource\_group\_name) | AzureRM Resource Group name | `string` | n/a | yes |
| <a name="input_azurerm_storage_account_name"></a> [azurerm\_storage\_account\_name](#input\_azurerm\_storage\_account\_name) | AzureRM Storage Account name | `string` | n/a | yes |
| <a name="input_deploy_id"></a> [deploy\_id](#input\_deploy\_id) | Domino deployment ID | `string` | n/a | yes |
| <a name="input_namespaces"></a> [namespaces](#input\_namespaces) | Namespaces for generating service account bindings | <pre>object({<br> compute = optional(string, "domino-compute")<br> platform = optional(string, "domino-platform")<br> })</pre> | `{}` | no |
| <a name="input_serviceaccount_names"></a> [serviceaccount\_names](#input\_serviceaccount\_names) | Service account names for Flyte | <pre>object({<br> datacatalog = optional(string, "datacatalog")<br> flyteadmin = optional(string, "flyteadmin")<br> flytepropeller = optional(string, "flytepropeller")<br> })</pre> | `{}` | no |
| <a name="input_deploy_id"></a> [deploy\_id](#input\_deploy\_id) | Domino deployment id | `string` | n/a | yes |
| <a name="input_namespaces"></a> [namespaces](#input\_namespaces) | Namespaces for workload identity federation | <pre>object({<br> compute = optional(string, "domino-compute")<br> platform = optional(string, "domino-platform")<br> })</pre> | `{}` | no |
| <a name="input_oidc_issuer_url"></a> [oidc\_issuer\_url](#input\_oidc\_issuer\_url) | OIDC issuer url | `string` | n/a | yes |
| <a name="input_resource_group_location"></a> [resource\_group\_location](#input\_resource\_group\_location) | Resource group location | `string` | n/a | yes |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Resource group name | `string` | n/a | yes |
| <a name="input_service_account_names"></a> [service\_account\_names](#input\_service\_account\_names) | Service account names for workload identity federation | <pre>object({<br> datacatalog = optional(string, "datacatalog")<br> flyteadmin = optional(string, "flyteadmin")<br> flytepropeller = optional(string, "flytepropeller")<br> nucleus = optional(string, "nucleus")<br> })</pre> | `{}` | no |
| <a name="input_storage_account_replication_type"></a> [storage\_account\_replication\_type](#input\_storage\_account\_replication\_type) | Storage account replication type | `string` | `"LRS"` | no |
| <a name="input_storage_account_tier"></a> [storage\_account\_tier](#input\_storage\_account\_tier) | Storage account tier | `string` | `"Standard"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to apply to resources | `map(string)` | `{}` | no |

## Outputs
Expand Down
22 changes: 15 additions & 7 deletions modules/flyte/groups.tf
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
resource "azuread_group" "flyte_metadata_access" {
display_name = "Flyte metadata access"
resource "azuread_group" "flyte_metadata" {
display_name = "${var.deploy_id}-flyte-metadata-group"
security_enabled = true
members = [
azurerm_user_assigned_identity.this["flyte_controlplane"].principal_id,
azurerm_user_assigned_identity.this["flyte_dataplane"].principal_id,
azurerm_user_assigned_identity.flyte_controlplane.principal_id,
azurerm_user_assigned_identity.flyte_dataplane.principal_id,
]
}

resource "azuread_group" "flyte_data_access" {
display_name = "Flyte data access"
resource "azuread_group" "flyte_data" {
display_name = "${var.deploy_id}-flyte-data-group"
security_enabled = true
members = [
azurerm_user_assigned_identity.this["flyte_dataplane"].principal_id,
azurerm_user_assigned_identity.flyte_dataplane.principal_id,
]
}

resource "azuread_group" "flyte_sas" {
display_name = "${var.deploy_id}-flyte-sas-group"
security_enabled = true
members = [
azurerm_user_assigned_identity.flyte_dataplane.principal_id,
]
}
37 changes: 22 additions & 15 deletions modules/flyte/identities.tf
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
locals {
# Kubernetes service account to user-assigned managed identity mapping
mapping = {
flyteadmin = "flyte_dataplane"
flytepropeller = "flyte_controlplane"
datacatalog = "flyte_controlplane"
federated_identity_mapping = {
flyteadmin = azurerm_user_assigned_identity.flyte_controlplane.id
flytepropeller = azurerm_user_assigned_identity.flyte_controlplane.id
datacatalog = azurerm_user_assigned_identity.flyte_controlplane.id
nucleus = azurerm_user_assigned_identity.flyte_dataplane.id
}
}

resource "azurerm_user_assigned_identity" "this" {
for_each = toset(values(local.mapping))
name = each.key
location = var.azurerm_resource_group_location
resource_group_name = var.azurerm_resource_group_name
resource "azurerm_user_assigned_identity" "flyte_controlplane" {
name = "${var.deploy_id}-flyte-controlplane"
location = var.resource_group_location
resource_group_name = var.resource_group_name
tags = var.tags
}

resource "azurerm_user_assigned_identity" "flyte_dataplane" {
name = "${var.deploy_id}-flyte-dataplane"
location = var.resource_group_location
resource_group_name = var.resource_group_name
tags = var.tags
}

resource "azurerm_federated_identity_credential" "this" {
for_each = local.mapping
name = each.key
resource_group_name = var.azurerm_resource_group_name
for_each = local.federated_identity_mapping
name = "${var.deploy_id}-${each.key}"
resource_group_name = var.resource_group_name
audience = ["api://AzureADTokenExchange"]
issuer = var.azurerm_kubernetes_cluster_oidc_issuer_url
parent_id = azurerm_user_assigned_identity.this[each.value].id
subject = "system:serviceaccount:${var.namespaces.platform}:${var.serviceaccount_names[each.key]}"
issuer = var.oidc_issuer_url
parent_id = each.value
subject = "system:serviceaccount:${var.namespaces.platform}:${var.service_account_names[each.key]}"
}
4 changes: 2 additions & 2 deletions modules/flyte/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ output "data_container_name" {
}

output "controlplane_client_id" {
value = azurerm_user_assigned_identity.this["flyte_controlplane"].client_id
value = azurerm_user_assigned_identity.flyte_controlplane.client_id
description = "Flyte controlplane client id"
}

output "dataplane_client_id" {
value = azurerm_user_assigned_identity.this["flyte_dataplane"].client_id
value = azurerm_user_assigned_identity.flyte_dataplane.client_id
description = "Flyte dataplane client id"
}
56 changes: 41 additions & 15 deletions modules/flyte/roles.tf
Original file line number Diff line number Diff line change
@@ -1,30 +1,56 @@
resource "azurerm_role_definition" "flyte_storage_access" {
name = "${var.deploy_id}-flyte-storage-access"
resource "azurerm_role_definition" "flyte_metadata" {
name = "${var.deploy_id}-flyte-metadata-role"
scope = azurerm_storage_container.flyte_metadata.resource_manager_id
permissions {
actions = [
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
"Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey/action"
data_actions = [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/add/action",
]
}
}

resource "azurerm_role_definition" "flyte_data" {
name = "${var.deploy_id}-flyte-data-role"
scope = azurerm_storage_container.flyte_data.resource_manager_id
permissions {
data_actions = [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/add/action",
]
}
assignable_scopes = [
azurerm_storage_container.flyte_metadata.resource_manager_id,
azurerm_storage_container.flyte_data.resource_manager_id,
]
}

resource "azurerm_role_assignment" "flyte_metadata_access" {
# Because the Get User Delegation Key operation acts at the level of the storage account, the
# Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey action must be scoped at the level
# of the storage account, the resource group, or the subscription.
# https://learn.microsoft.com/en-us/rest/api/storageservices/get-user-delegation-key
#
resource "azurerm_role_definition" "flyte_sas" {
name = "${var.deploy_id}-flyte-sas-role"
scope = azurerm_storage_account.flyte.id
permissions {
actions = [
"Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey/action",
]
}
}

resource "azurerm_role_assignment" "flyte_metadata" {
scope = azurerm_storage_container.flyte_metadata.resource_manager_id
role_definition_id = azurerm_role_definition.flyte_storage_access.role_definition_resource_id
principal_id = azuread_group.flyte_metadata_access.object_id
role_definition_id = azurerm_role_definition.flyte_metadata.role_definition_resource_id
principal_id = azuread_group.flyte_metadata.object_id
}

resource "azurerm_role_assignment" "flyte_data_access" {
resource "azurerm_role_assignment" "flyte_data" {
scope = azurerm_storage_container.flyte_data.resource_manager_id
role_definition_id = azurerm_role_definition.flyte_storage_access.role_definition_resource_id
principal_id = azuread_group.flyte_data_access.object_id
role_definition_id = azurerm_role_definition.flyte_data.role_definition_resource_id
principal_id = azuread_group.flyte_data.object_id
}

resource "azurerm_role_assignment" "flyte_sas" {
scope = azurerm_storage_account.flyte.id
role_definition_id = azurerm_role_definition.flyte_sas.role_definition_resource_id
principal_id = azuread_group.flyte_sas.object_id
}
23 changes: 21 additions & 2 deletions modules/flyte/storage.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
resource "azurerm_storage_account" "flyte" {
name = join("", [replace(var.deploy_id, "/[_-]/", ""), "flyte"])
location = var.resource_group_location
resource_group_name = var.resource_group_name
account_kind = "StorageV2"
account_tier = var.storage_account_tier
account_replication_type = var.storage_account_replication_type
access_tier = "Hot"
min_tls_version = "TLS1_2"
tags = var.tags
is_hns_enabled = true

lifecycle {
ignore_changes = [
tags
]
}
}

resource "azurerm_storage_container" "flyte_metadata" {
name = "${var.deploy_id}-flyte-metadata"
storage_account_name = var.azurerm_storage_account_name
storage_account_name = azurerm_storage_account.flyte.name
container_access_type = "private"
}

resource "azurerm_storage_container" "flyte_data" {
name = "${var.deploy_id}-flyte-data"
storage_account_name = var.azurerm_storage_account_name
storage_account_name = azurerm_storage_account.flyte.name
container_access_type = "private"
}
31 changes: 20 additions & 11 deletions modules/flyte/tests/identities.tftest.hcl
Original file line number Diff line number Diff line change
@@ -1,56 +1,65 @@
mock_provider "azuread" {}
mock_provider "azurerm" {}

run "test_identities" {
command = plan

assert {
condition = azurerm_user_assigned_identity.this["flyte_controlplane"].name == "flyte_controlplane"
condition = azurerm_user_assigned_identity.flyte_controlplane.name == "${var.deploy_id}-flyte-controlplane"
error_message = "Incorrect user-assigned identity name for flyte_controlplane"
}

assert {
condition = azurerm_user_assigned_identity.this["flyte_controlplane"].resource_group_name == var.azurerm_resource_group_name
condition = azurerm_user_assigned_identity.flyte_controlplane.resource_group_name == var.resource_group_name
error_message = "Incorrect user-assigned identity resource group name for flyte_controlplane"
}

assert {
condition = azurerm_user_assigned_identity.this["flyte_dataplane"].name == "flyte_dataplane"
condition = azurerm_user_assigned_identity.flyte_dataplane.name == "${var.deploy_id}-flyte-dataplane"
error_message = "Incorrect user-assigned identity name for flyte_dataplane"
}

assert {
condition = azurerm_user_assigned_identity.this["flyte_dataplane"].resource_group_name == var.azurerm_resource_group_name
condition = azurerm_user_assigned_identity.flyte_dataplane.resource_group_name == var.resource_group_name
error_message = "Incorrect user-assigned identity resource group name for flyte_dataplane"
}

assert {
condition = azurerm_federated_identity_credential.this["flyteadmin"].name == "flyteadmin"
condition = azurerm_federated_identity_credential.this["flyteadmin"].name == "${var.deploy_id}-flyteadmin"
error_message = "Incorrect federated identity credential name for flyteadmin"
}

assert {
condition = azurerm_federated_identity_credential.this["flyteadmin"].subject == "system:serviceaccount:${var.namespaces.platform}:${var.serviceaccount_names["flyteadmin"]}"
condition = azurerm_federated_identity_credential.this["flyteadmin"].subject == "system:serviceaccount:${var.namespaces.platform}:${var.service_account_names.flyteadmin}"
error_message = "Incorrect federated identity credential subject for flyteadmin"
}

assert {
condition = azurerm_federated_identity_credential.this["flytepropeller"].name == "flytepropeller"
condition = azurerm_federated_identity_credential.this["flytepropeller"].name == "${var.deploy_id}-flytepropeller"
error_message = "Incorrect federated identity credential name for flytepropeller"
}

assert {
condition = azurerm_federated_identity_credential.this["flytepropeller"].subject == "system:serviceaccount:${var.namespaces.platform}:${var.serviceaccount_names["flytepropeller"]}"
condition = azurerm_federated_identity_credential.this["flytepropeller"].subject == "system:serviceaccount:${var.namespaces.platform}:${var.service_account_names.flytepropeller}"
error_message = "Incorrect federated identity credential subject for flytepropeller"
}

assert {
condition = azurerm_federated_identity_credential.this["datacatalog"].name == "datacatalog"
condition = azurerm_federated_identity_credential.this["datacatalog"].name == "${var.deploy_id}-datacatalog"
error_message = "Incorrect federated identity credential name for datacatalog"
}

assert {
condition = azurerm_federated_identity_credential.this["datacatalog"].subject == "system:serviceaccount:${var.namespaces.platform}:${var.serviceaccount_names["datacatalog"]}"
condition = azurerm_federated_identity_credential.this["datacatalog"].subject == "system:serviceaccount:${var.namespaces.platform}:${var.service_account_names.datacatalog}"
error_message = "Incorrect federated identity credential subject for datacatalog"
}

assert {
condition = azurerm_federated_identity_credential.this["nucleus"].name == "${var.deploy_id}-nucleus"
error_message = "Incorrect federated identity credential name for nucleus"
}

assert {
condition = azurerm_federated_identity_credential.this["nucleus"].subject == "system:serviceaccount:${var.namespaces.platform}:${var.service_account_names.nucleus}"
error_message = "Incorrect federated identity credential subject for nucleus"
}
}
5 changes: 2 additions & 3 deletions modules/flyte/tests/outputs.tftest.hcl
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
mock_provider "azuread" {}
mock_provider "azurerm" {}

run "test_outputs" {
command = plan

assert {
condition = output.flyte_metadata_container_name == azurerm_storage_container.flyte_metadata.name
condition = output.metadata_container_name == azurerm_storage_container.flyte_metadata.name
error_message = "Incorrect Flyte metadata container name output"
}

assert {
condition = output.flyte_data_container_name == azurerm_storage_container.flyte_data.name
condition = output.data_container_name == azurerm_storage_container.flyte_data.name
error_message = "Incorrect Flyte data container name output"
}
}
Loading

0 comments on commit 78bfa99

Please sign in to comment.