From 7b1c91ea985c871f324167c72ea758d4de83c63e Mon Sep 17 00:00:00 2001 From: Adrian Bednarz <38663291+bottaio@users.noreply.github.com> Date: Sun, 14 May 2023 11:07:15 +0200 Subject: [PATCH] feat: Configure SFTP local user accounts (#13) * feature: Configure SFTP local user accounts * update the docs * lint * terraform-docs: automated action * review --------- Co-authored-by: github-actions[bot] --- README.md | 8 ++++++-- locals.tf | 2 ++ main.tf | 24 ++++++++++++++++++++++++ outputs.tf | 20 ++++++++++++++++++++ variables.tf | 15 +++++++++++++++ versions.tf | 2 +- 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 086c771..f81dbca 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ module "storage_account" { | [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | | [last\_access\_time\_enabled](#input\_last\_access\_time\_enabled) | Is the last access time based tracking enabled? Default to `false` | `bool` | `false` | no | | [lifecycles](#input\_lifecycles) | Configure Azure Storage lifecycles | `list(object({ prefix_match = set(string), tier_to_cool_after_days = number, tier_to_archive_after_days = number, delete_after_days = number, snapshot_delete_after_days = number }))` | `[]` | no | +| [local\_users](#input\_local\_users) | List of SFTP users. |
list(object({
name = string
home_directory = optional(string)
ssh_password_enabled = optional(bool)
permissions = list(object({
container = string
service = optional(string, "blob")
permissions = optional(list(string), ["All"])
}))
}))
| `[]` | no | | [location](#input\_location) | Azure datacenter location, where resources will be deployed | `string` | `null` | no | | [managed\_identity\_ids](#input\_managed\_identity\_ids) | A list of User Managed Identity ID's which should be assigned to the Linux Virtual Machine | `list(string)` | `null` | no | | [managed\_identity\_type](#input\_managed\_identity\_type) | The type of Managed Identity which should be assigned to the Linux Virtual Machine. Possible values are `SystemAssigned`, `UserAssigned` and `SystemAssigned, UserAssigned` | `string` | `null` | no | @@ -128,6 +129,8 @@ module "storage_account" { |------|-------------| | [containers](#output\_containers) | Map of containers | | [file\_shares](#output\_file\_shares) | Map of Storage SMB file shares | +| [local\_users](#output\_local\_users) | Map of created sftp users. | +| [local\_users\_credentials](#output\_local\_users\_credentials) | Map of created sftp users credentials. | | [queues](#output\_queues) | Map of Storage SMB file shares | | [resource\_group\_id](#output\_resource\_group\_id) | The id of the resource group in which resources are created | | [resource\_group\_location](#output\_resource\_group\_location) | The location of the resource group in which resources are created | @@ -147,14 +150,14 @@ module "storage_account" { | Name | Version | |------|---------| -| [azurerm](#provider\_azurerm) | >= 3.0 | +| [azurerm](#provider\_azurerm) | >= 3.39 | ## Requirements | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 0.13 | -| [azurerm](#requirement\_azurerm) | >= 3.0 | +| [azurerm](#requirement\_azurerm) | >= 3.39 | ## Resources @@ -163,6 +166,7 @@ module "storage_account" { | [azurerm_private_endpoint.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) | resource | | [azurerm_role_assignment.storage_blob_data_readers](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | | [azurerm_role_assignment.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | +| [azurerm_storage_account_local_user.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account_local_user) | resource | ## CONTRIBUTING diff --git a/locals.tf b/locals.tf index eb31cbd..b84fce1 100644 --- a/locals.tf +++ b/locals.tf @@ -13,4 +13,6 @@ locals { storage_account_id = one(module.storage[*].storage_account_id) storage_account_name = one(module.storage[*].storage_account_name) + + local_users = { for user in var.local_users : user.name => user } } diff --git a/main.tf b/main.tf index a870be6..4c98dcc 100644 --- a/main.tf +++ b/main.tf @@ -106,3 +106,27 @@ resource "azurerm_private_endpoint" "this" { tags = module.this.tags } + +resource "azurerm_storage_account_local_user" "this" { + for_each = local.local_users + + name = each.value.name + storage_account_id = local.storage_account_id + ssh_password_enabled = each.value.ssh_password_enabled + home_directory = each.value.home_directory + + dynamic "permission_scope" { + for_each = each.value.permissions + content { + service = permission_scope.value.service + resource_name = permission_scope.value.container + permissions { + read = contains(permission_scope.value.permissions, "All") || contains(permission_scope.value.permissions, "Read") + write = contains(permission_scope.value.permissions, "All") || contains(permission_scope.value.permissions, "Write") + delete = contains(permission_scope.value.permissions, "All") || contains(permission_scope.value.permissions, "Delete") + list = contains(permission_scope.value.permissions, "All") || contains(permission_scope.value.permissions, "List") + create = contains(permission_scope.value.permissions, "All") || contains(permission_scope.value.permissions, "Create") + } + } + } +} diff --git a/outputs.tf b/outputs.tf index 8f2ce09..cca8348 100644 --- a/outputs.tf +++ b/outputs.tf @@ -80,3 +80,23 @@ output "queues" { description = "Map of Storage SMB file shares" value = one(module.storage[*].queues) } + +output "local_users" { + description = "Map of created sftp users." + value = { + for user_name, user in azurerm_storage_account_local_user.this : user_name => { + id = user.id + name = user.name + } + } +} + +output "local_users_credentials" { + description = "Map of created sftp users credentials." + value = { + for user_name, user in azurerm_storage_account_local_user.this : user_name => { + password = user.password + } + } + sensitive = true +} diff --git a/variables.tf b/variables.tf index e38935d..4be0cd4 100644 --- a/variables.tf +++ b/variables.tf @@ -199,3 +199,18 @@ variable "descriptor_name" { type = string default = "storage-account" #For backward compatibility reasons } + +variable "local_users" { + description = "List of SFTP users." + type = list(object({ + name = string + home_directory = optional(string) + ssh_password_enabled = optional(bool) + permissions = list(object({ + container = string + service = optional(string, "blob") + permissions = optional(list(string), ["All"]) + })) + })) + default = [] +} diff --git a/versions.tf b/versions.tf index aa56aea..67b8d24 100644 --- a/versions.tf +++ b/versions.tf @@ -6,7 +6,7 @@ terraform { # tflint-ignore: terraform_unused_required_providers azurerm = { source = "hashicorp/azurerm" - version = ">= 3.0" + version = ">= 3.39" } } }