diff --git a/.gitignore b/.gitignore
index 199e14b..a938d80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,7 @@ crash.log
# version control.
#
# example.tfvars
-admin.tfvars
+*.tfvars
# Ignore override files as they are usually used to override resources locally and so
# are not checked in
diff --git a/LICENSE b/LICENSE
index 0e6df15..f596f91 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2021 Godson Fortil
+Copyright (c) 2023 HPCC Systems®
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 56a040f..5d5d780 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,18 @@
# Azure - Storage Account for HPCC Systems
-
-
-# ** DO NOT USE IN PRODUCTION **
-
-
-
-## Introduction
-
-This module will deploy a storage account for the HPCC Systems cloud native platform.
## Providers
| Name | Version |
| ------- | --------- |
-| azurerm | >= 2.57.0 |
-| random | ~>3.1.0 |
+| azurerm | >= 3.63.0 |
+| random | >= 3.3.0 |
+| azuread | >= 2.42.0 |
-### The `admin` block:
+### The `owner` block
+
This block contains information on the user who is deploying the cluster. This is used as tags and part of some resource names to identify who deployed a given resource and how to contact that user. This block is required.
| Name | Description | Type | Default | Required |
@@ -31,14 +24,15 @@ This block contains information on the user who is deploying the cluster. This i
Usage Example:
- admin = {
- name = "Example"
- email = "example@hpccdemo.com"
+ owner = {
+ name = "demo"
+ email = "demo@lexisnexisrisk.com"
}
-### The `disable_naming_conventions` block:
+### The `disable_naming_conventions` block
+
When set to `true`, this attribute drops the naming conventions set forth by the python module. This attribute is optional.
| Name | Description | Type | Default | Required |
@@ -46,7 +40,8 @@ When set to `true`, this attribute drops the naming conventions set forth by the
| disable_naming_conventions | Disable naming conventions. | bool | `false` | no |
-### The `metadata` block:
+### The `metadata` block
+
TThe arguments in this block are used as tags and part of resources’ names. This block can be omitted when disable_naming_conventions is set to `true`.
| Name | Description | Type | Default | Required |
@@ -79,105 +74,360 @@ Usage Example:
-### The `tags` argument:
-The tag attribute can be used for additional tags. The tags must be key value pairs. This block is optional.
-
- | Name | Description | Type | Default | Required |
- | ---- | ------------------------- | ----------- | ------- | :------: |
- | tags | Additional resource tags. | map(string) | admin | no |
-
+### The `virtual_network` block
-### The `resource_group` block:
-This block creates a resource group (like a folder) for your resources. This block is required.
+This block imports metadata of a virtual network deployed outside of this project. This block is optional.
- | Name | Description | Type | Default | Required |
- | ----------- | ----------------------------------------------------------------- | ------ | ------- | :------: |
- | unique_name | Will concatenate a number at the end of your resource group name. | bool | `true` | yes |
- | location | Cloud region in which to deploy the cluster resources. | string | null | yes |
+ | Name | Description | Type | Default | Required |
+ | ------------------- | ----------------------------------------------- | ----------- | ------- | :------: |
+ | name | The name of the private subnet. | string | - | yes |
+ | resource_group_name | The name of the virtual network resource group. | string | - | yes |
+ | subnet_ids | The IDs of the subnets to authorize access to. | map(string) | - | yes |
+ | location | The location of the virtual network | string | - | yes |
Usage Example:
- resource_group = {
- unique_name = true
- location = "canadacentral"
+ virtual_network = {
+ location = "value"
+ name = "value"
+ resource_group_name = "value"
+ subnet_ids = {
+ "name" = "value"
+ }
}
-### The `storage` block:
-This block deploys the HPCC persistent volumes. This block is required.
-
- | Name | Description | Type | Default | Valid Options | Required |
- | ----------------------- | ------------------------------------------------------------------------------------------------------ | ------ | ----------- | ------------------------------------------------------------------------ | :------: |
- | access_tier | Defines the access tier for `BlobStorage`, `FileStorage`, `Storage2` accounts. | string | Hot | `Cool`, `Hot` | yes |
- | account_kind | Defines the Kind of account. Changing this will destroy your data. | string | `StorageV2` | `BlobStorage`. `BlockBlobStorage`, `FileStorage`, `Storage`, `StorageV2` | yes |
- | account_tier | Defines the Tier to use for this storage account. Changing this will destroy your data. | string | `Premium` | `Standard`, `Premium` | yes |
- | enable_large_file_share | Enable Large File Share. | bool | `false` | `false`, `true` | yes |
- | replication_type | Defines the type of replication to use for this storage account. Changing this will destroy your data. | string | `LRS` | `LRS`, `GRS`, `RAGRS`, `ZRS`, `GZRS`, `RAGZRS` | yes |
-
+### The `storage_accounts` block
+
+This block deploys the storage accounts for HPCC-Platform data planes. This block is required.
+
+ | Name | Description | Type | Default | Valid Options | Required |
+ | ------------------------------------ | ----------------------------------------------------------------------------------- | -------------- | ------- | ----------------------- | :------: |
+ | delete_protection | Should deletion be prevented? | bool | true | `true`, `false` | no |
+ | storage_account_name_prefix | The prefix name for the storage account. It must be the storage account object key. | string | - | - | yes |
+ | storage_type | The storage account type. | string | - | `azurefiles`, `blobnfs` | yes |
+ | authorized_ip_ranges | Group of IPs to authorize access to the storage account. | Object(string) | `{}` | - | no |
+ | replication_type |
+ | subnet_ids |
+ | file_share_retention_days |
+ | access_tier |
+ | account_kind |
+ | account_tier |
+ | blob_soft_delete_retention_days |
+ | container_soft_delete_retention_days |
+
+
+#### The `var.storage_accounts.planes` block
+
+ | Name | Description | Type | Default | Valid Options | Required |
+ | -------- | ------------------------------------------------------ | ------ | ------- | --------------- | :------: |
+ | size | The size of the share or HPCC data plane | number | - | - | yes |
+ | rwmany | The set of permissions for the plane | bool | true | `true`, `false` | yes |
+ | protocol | The network file sharing protocol to use for the share | string | `NFS` | `SMB`, `NFS` | yes |
+ | sub_path | The sub path for the HPCC data plane | string | - | - | yes |
+ | category | The category for the HPCC data plane | string | - | - | yes |
+ | plane_name | The name of the plane | string | - | - | yes |
+ | sku | The sku for the plane | string | - | - | no |
+
Usage Example:
- storage = {
- access_tier = "Hot"
- account_kind = "StorageV2"
- account_tier = "Standard"
- account_replication_type = "LRS"
-
- quotas = {
- dali = 3
- data = 2
- dll = 2
- lz = 2
- sasha = 5
+ storage_accounts = {
+ adminsvc1 = {
+ delete_protection = true //Set to false to allow deletion
+ storage_account_name_prefix = "adminsvc1"
+ storage_type = "azurefiles"
+ authorized_ip_ranges = {}
+ replication_type = "ZRS"
+ subnet_ids = {}
+ file_share_retention_days = 7
+ access_tier = "Hot"
+ account_kind = "FileStorage"
+ account_tier = "Premium"
+
+ planes = {
+ dali = {
+ category = "dali"
+ plane_name = "dali"
+ sub_path = "dalistorage"
+ size = 100
+ sku = ""
+ rwmany = true
+ protocol = "nfs"
+ }
+ }
}
- }
-
-
-
-## Usage
-
--
-
-Clone this repo: `git clone https://github.com/gfortil/terraform-azurerm-hpcc-storage.git`.
-- Linux and MacOS
-
--
+ adminsvc2 = {
+ delete_protection = true //Set to false to allow deletion
+ storage_account_name_prefix = "adminsvc2"
+ storage_type = "blobnfs"
+ authorized_ip_ranges = {}
+ replication_type = "ZRS"
+ subnet_ids = {}
+ blob_soft_delete_retention_days = 7
+ container_soft_delete_retention_days = 7
+ access_tier = "Hot"
+ account_kind = "StorageV2"
+ account_tier = "Standard"
+
+ planes = {
+ dll = {
+ category = "dll"
+ plane_name = "dll"
+ sub_path = "queries"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+
+ lz = {
+ category = "lz"
+ plane_name = "mydropzone"
+ sub_path = "dropzone"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+
+ sasha = {
+ category = "sasha"
+ plane_name = "sasha"
+ sub_path = "sashastorage"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+
+ debug = {
+ category = "debug"
+ plane_name = "debug"
+ sub_path = "debug"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+ }
+ }
-Change directory to terraform-azurerm-hpcc-storage: `cd terraform-azurerm-hpcc-storage`
--
+ data1 = {
+ delete_protection = true //Set to false to allow deletion
+ storage_account_name_prefix = "data1"
+ storage_type = "blobnfs"
+ authorized_ip_ranges = {}
+ replication_type = "ZRS"
+ subnet_ids = {}
+ blob_soft_delete_retention_days = 7
+ container_soft_delete_retention_days = 7
+ access_tier = "Hot"
+ account_kind = "StorageV2"
+ account_tier = "Standard"
+
+ planes = {
+ data = {
+ category = "data"
+ plane_name = "data"
+ sub_path = "hpcc-data"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+ }
+ }
-Copy examples/admin.tfvars to terraform-azurerm-hpcc-storage: `cp examples/admin.tfvars`
-
-- Windows OS
-
--
-
-Change directory to terraform-azurerm-hpcc-storage: `cd terraform-azurerm-hpcc-storage`
--
+ data2 = {
+ delete_protection = true //Set to false to allow deletion
+ storage_account_name_prefix = "data2"
+ storage_type = "blobnfs"
+ authorized_ip_ranges = {}
+ replication_type = "ZRS"
+ subnet_ids = {}
+ blob_soft_delete_retention_days = 7
+ container_soft_delete_retention_days = 7
+ access_tier = "Hot"
+ account_kind = "StorageV2"
+ account_tier = "Standard"
+
+ planes = {
+ data = {
+ category = "data"
+ plane_name = "data"
+ sub_path = "hpcc-data"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+ }
+ }
+ }
+
-Copy examples/admin.tfvars to terraform-azurerm-hpcc-storage: `copy examples/admin.tfvars`
-
--
+## Usage
-Open `terraform-azurerm-hpcc-storage/admin.tfvars` file.
--
+ module "storage" {
+ source = "../../../terraform-azurerm-hpcc-storage"
-Set attributes to your preferred values.
--
+ owner = {
+ name = "demo"
+ email = "demo@lexisnexisrisk.com"
+ }
-Save `terraform-azurerm-hpcc-storage/admin.tfvars` file.
--
+ disable_naming_conventions = false
+
+ metadata = {
+ project = "hpccplatform"
+ product_name = "hpccplatform"
+ business_unit = "commercial"
+ environment = "sandbox"
+ market = "us"
+ product_group = "hpcc"
+ resource_group_type = "app"
+ sre_team = "hpccplatform"
+ subscription_type = "dev"
+ additional_tags = { "justification" = "testing" }
+ location = "eastus" # Acceptable values: eastus, centralus
+ }
-Run `terraform init`. This step is only required before your first `terraform apply`.
--
+ virtual_network = {
+ location = "value"
+ name = "value"
+ resource_group_name = "value"
+ subnet_ids = {
+ "name" = "value"
+ }
+ }
+
+ storage_accounts = {
+ adminsvc1 = {
+ delete_protection = false //Set to false to allow deletion
+ storage_account_name_prefix = "adminsvc1"
+ storage_type = "azurefiles"
+ replication_type = "ZRS"
+ subnet_ids = {}
+ file_share_retention_days = 7
+ access_tier = "Hot"
+ account_kind = "FileStorage"
+ account_tier = "Premium"
+
+ planes = {
+ dali = {
+ category = "dali"
+ plane_name = "dali"
+ sub_path = "dalistorage"
+ size = 100
+ sku = ""
+ rwmany = true
+ protocol = "smb"
+ }
+ }
+ }
+
+ adminsvc2 = {
+ delete_protection = false //Set to false to allow deletion
+ storage_account_name_prefix = "adminsvc2"
+ storage_type = "blob"
+ replication_type = "ZRS"
+ subnet_ids = {}
+ blob_soft_delete_retention_days = 7
+ container_soft_delete_retention_days = 7
+ access_tier = "Hot"
+ account_kind = "StorageV2"
+ account_tier = "Standard"
+
+ planes = {
+ dll = {
+ category = "dll"
+ plane_name = "dll"
+ sub_path = "queries"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+
+ lz = {
+ category = "lz"
+ plane_name = "mydropzone"
+ sub_path = "dropzone"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+
+ sasha = {
+ category = "sasha"
+ plane_name = "sasha"
+ sub_path = "sashastorage"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+
+ debug = {
+ category = "debug"
+ plane_name = "debug"
+ sub_path = "debug"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+ }
+ }
+
+ data1 = {
+ delete_protection = false //Set to false to allow deletion
+ storage_account_name_prefix = "data1"
+ storage_type = "blob"
+ replication_type = "ZRS"
+ subnet_ids = {}
+ blob_soft_delete_retention_days = 7
+ container_soft_delete_retention_days = 7
+ access_tier = "Hot"
+ account_kind = "StorageV2"
+ account_tier = "Standard"
+
+ planes = {
+ data = {
+ category = "data"
+ plane_name = "data"
+ sub_path = "hpcc-data"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+ }
+ }
+
+ data2 = {
+ delete_protection = false //Set to false to allow deletion
+ storage_account_name_prefix = "data2"
+ storage_type = "blob"
+ replication_type = "ZRS"
+ subnet_ids = {}
+ blob_soft_delete_retention_days = 7
+ container_soft_delete_retention_days = 7
+ access_tier = "Hot"
+ account_kind = "StorageV2"
+ account_tier = "Standard"
+
+ planes = {
+ data = {
+ category = "data"
+ plane_name = "data"
+ sub_path = "hpcc-data"
+ size = 100
+ sku = ""
+ rwmany = true
+ }
+ }
+ }
+ }
-Run `terraform apply -var-file=admin.tfvars` or `terraform apply -var-file=admin.tfvars -auto-approve`.
--
+ authorized_ip_ranges = {
+ "ip_1" = ""
+ }
-Type `yes` if you didn't pass the flag `-auto-approve`.
-
\ No newline at end of file
+ }
diff --git a/data.tf b/data.tf
index 7d8d741..08682c8 100644
--- a/data.tf
+++ b/data.tf
@@ -1,6 +1,9 @@
data "http" "host_ip" {
- url = "http://ipv4.icanhazip.com"
+ url = "https://api.ipify.org"
}
data "azurerm_subscription" "current" {
}
+
+data "azurerm_client_config" "current" {
+}
diff --git a/examples/admin.tfvars b/examples/admin.tfvars
deleted file mode 100644
index 546a2a8..0000000
--- a/examples/admin.tfvars
+++ /dev/null
@@ -1,40 +0,0 @@
-admin = {
- name = "hpccdemo"
- email = "hpccdemo@example.com"
-}
-
-metadata = {
- project = "hpccdemo"
- product_name = "storageaccount"
- business_unit = "commercial"
- environment = "sandbox"
- market = "us"
- product_group = "contoso"
- resource_group_type = "app"
- sre_team = "hpccplatform"
- subscription_type = "dev"
-}
-
-tags = { "justification" = "testing" }
-
-resource_group = {
- unique_name = true
- location = "eastus2"
-}
-
-storage = {
- access_tier = "Hot"
- account_kind = "StorageV2"
- account_tier = "Standard"
- account_replication_type = "LRS"
-
- quotas = {
- dali = 1
- data = 3
- dll = 1
- lz = 1
- sasha = 3
- }
-}
-
-# disable_naming_conventions = false # true will enforce all the arguments of the metadata block above
diff --git a/examples/providers.tf b/examples/providers.tf
new file mode 100644
index 0000000..e609c7e
--- /dev/null
+++ b/examples/providers.tf
@@ -0,0 +1,7 @@
+provider "azurerm" {
+ features {}
+ use_cli = true
+ storage_use_azuread = true
+}
+
+provider "azuread" {}
diff --git a/locals.tf b/locals.tf
index 56af3d5..498bf8d 100644
--- a/locals.tf
+++ b/locals.tf
@@ -3,7 +3,7 @@ locals {
{
business_unit = var.metadata.business_unit
environment = var.metadata.environment
- location = var.storage.location
+ location = var.metadata.location
market = var.metadata.market
subscription_type = var.metadata.subscription_type
},
@@ -12,8 +12,80 @@ locals {
var.metadata.resource_group_type != "" ? { resource_group_type = var.metadata.resource_group_type } : {}
) : module.metadata.names
- tags = var.disable_naming_conventions ? merge(var.tags, { "admin" = var.admin.name, "email" = var.admin.email, "workspace" = terraform.workspace }) : merge(module.metadata.tags, { "admin" = var.admin.name, "email" = var.admin.email, "workspace" = terraform.workspace }, try(var.tags))
+ tags = merge(var.metadata.additional_tags, { "owner" = var.owner.name, "owner_email" = var.owner.email })
- storage_shares = { "dalishare" = var.storage.quotas.dali, "dllsshare" = var.storage.quotas.dll, "sashashare" = var.storage.quotas.sasha,
- "datashare" = var.storage.quotas.data, "lzshare" = var.storage.quotas.lz }
+ location = var.metadata.location
+
+ resource_groups = {
+ storage_accounts = {
+ tags = { "enclosed resource" = "OSS storage accounts" }
+ }
+ }
+
+ azure_files_pv_protocol = "nfs"
+
+ planes = flatten([
+ for k, v in var.storage_accounts :
+ [
+ for x, y in v.planes : {
+ "container_name" : "${y.plane_name}"
+ "plane_name" : "${y.plane_name}"
+ "category" : "${y.category}"
+ "path" : "${y.sub_path}"
+ "size" : "${y.size}"
+ "storage_account_name" : v.storage_type == "azurefiles" ? "${v.storage_account_name_prefix}${random_string.random.result}af" : "${v.storage_account_name_prefix}${random_string.random.result}blob"
+ "storage_account_name_prefix" : v.storage_account_name_prefix
+ "resource_group" : "${module.resource_groups["storage_accounts"].name}"
+ "storage_type" : "${v.storage_type}"
+ "protocol" : v.storage_type == "azurefiles" ? "${upper(y.protocol)}" : null
+ "access_tier" : "${v.access_tier}"
+ "account_kind" : "${v.account_kind}"
+ "account_tier" : "${v.account_tier}"
+ "replication_type" : "${v.replication_type}"
+ "authorized_ip_ranges" : "${tomap(merge(var.authorized_ip_ranges, { host_ip = data.http.host_ip.response_body }))}"
+ "subnet_ids" : "${var.subnet_ids}"
+ "file_share_retention_days" : v.storage_type == "azurefiles" ? "${v.file_share_retention_days}" : null
+ }
+ ]
+ ])
+
+ azurefile_storage_accounts_args = {
+ for k, v in var.storage_accounts : k => merge({ storage_account_name = "${v.storage_account_name_prefix}${random_string.random.result}af" }, v, { "resource_group_name" = module.resource_groups["storage_accounts"].name }) if v.storage_type == "azurefiles"
+ }
+
+ blob_storage_accounts_args = {
+ for k, v in var.storage_accounts : k => merge({ storage_account_name = "${v.storage_account_name_prefix}${random_string.random.result}blob" }, v, { "resource_group_name" = module.resource_groups["storage_accounts"].name }) if v.storage_type == "blobnfs"
+ }
+
+ azurefile_planes = {
+ for k, v in local.planes : k => v if v.storage_type == "azurefiles"
+ }
+
+ blob_planes = {
+ for k, v in local.planes : k => v if v.storage_type == "blobnfs"
+ }
+
+ azurefile_storage_accounts_attrs = {
+ for k, v in azurerm_storage_account.azurefiles : k => {
+ storage_account_name = v.name
+ resource_group_name = v.resource_group_name
+ id = v.id
+ account_replication_type = v.account_replication_type
+ account_tier = v.account_tier
+ primary_access_key = v.primary_access_key
+ primary_location = v.primary_location
+ }
+ }
+
+ blob_storage_accounts_attrs = {
+ for k, v in azurerm_storage_account.blobnfs : k => {
+ storage_account_name = v.name
+ resource_group_name = v.resource_group_name
+ id = v.id
+ account_replication_type = v.account_replication_type
+ account_tier = v.account_tier
+ primary_access_key = v.primary_access_key
+ primary_location = v.primary_location
+ }
+ }
}
diff --git a/main.tf b/main.tf
index 959074f..ad90f64 100644
--- a/main.tf
+++ b/main.tf
@@ -1,13 +1,8 @@
-resource "random_integer" "random" {
- min = 1
- max = 3
-}
-
resource "random_string" "random" {
- length = 43
- upper = false
- number = false
+ length = 4
special = false
+ numeric = false
+ upper = false
}
module "subscription" {
@@ -25,7 +20,7 @@ module "metadata" {
naming_rules = module.naming.yaml
market = var.metadata.market
- location = var.resource_group.location
+ location = local.location
sre_team = var.metadata.sre_team
environment = var.metadata.environment
product_name = var.metadata.product_name
@@ -33,42 +28,17 @@ module "metadata" {
product_group = var.metadata.product_group
subscription_type = var.metadata.subscription_type
resource_group_type = var.metadata.resource_group_type
- subscription_id = data.azurerm_subscription.current.id
+ subscription_id = module.subscription.output.subscription_id
project = var.metadata.project
}
-module "resource_group" {
- source = "github.com/Azure-Terraform/terraform-azurerm-resource-group.git?ref=v2.0.0"
-
- unique_name = var.resource_group.unique_name
- location = var.resource_group.location
- names = local.names
- tags = local.tags
-}
-
-resource "azurerm_storage_account" "storage_account" {
-
- name = lower(try("${var.admin.name}hpccsa${random_integer.random.result}", "hpccsa${random_integer.random.result}404"))
- resource_group_name = module.resource_group.name
- location = module.resource_group.location
- account_tier = var.storage.account_tier
- account_replication_type = var.storage.account_replication_type
- min_tls_version = "TLS1_2"
- tags = local.tags
-}
-
-resource "azurerm_storage_share" "storage_shares" {
- for_each = local.storage_shares
-
- name = each.key
- storage_account_name = azurerm_storage_account.storage_account.name
- quota = each.value
+module "resource_groups" {
+ source = "github.com/Azure-Terraform/terraform-azurerm-resource-group.git?ref=v2.1.0"
- acl {
- id = random_string.random.result
+ for_each = local.resource_groups
- access_policy {
- permissions = "rwdl"
- }
- }
+ unique_name = true
+ location = module.metadata.location
+ names = module.metadata.names
+ tags = merge(local.tags, each.value.tags)
}
diff --git a/output.tf b/output.tf
deleted file mode 100644
index de140e8..0000000
--- a/output.tf
+++ /dev/null
@@ -1,15 +0,0 @@
-output "resource_group_name" {
- value = module.resource_group.name
-}
-
-output "subscription_id" {
- value = data.azurerm_subscription.current.subscription_id
-}
-
-output "storage_account_name" {
- value = azurerm_storage_account.storage_account.name
-}
-
-output "location" {
- value = module.resource_group.location
-}
diff --git a/outputs.tf b/outputs.tf
new file mode 100644
index 0000000..935a73a
--- /dev/null
+++ b/outputs.tf
@@ -0,0 +1,19 @@
+output "azurefile_storage_accounts_attrs" {
+ value = local.azurefile_storage_accounts_attrs
+}
+
+output "blob_storage_accounts_attrs" {
+ value = local.blob_storage_accounts_attrs
+}
+
+output "storage_planes" {
+ value = local.planes
+}
+
+output "azurefile_planes" {
+ value = local.azurefile_planes
+}
+
+output "blob_planes" {
+ value = local.blob_planes
+}
diff --git a/storage.tf b/storage.tf
new file mode 100644
index 0000000..d15344a
--- /dev/null
+++ b/storage.tf
@@ -0,0 +1,106 @@
+resource "azurerm_management_lock" "protect_azurefile_storage_accounts" {
+ for_each = {
+ for k, v in var.storage_accounts : k => v if v.storage_type == "azurefiles" && v.delete_protection
+ }
+
+ name = "protect-storage-${azurerm_storage_account.azurefiles[each.key].name}"
+ scope = azurerm_storage_account.azurefiles[each.key].id
+ lock_level = "CanNotDelete"
+}
+
+resource "azurerm_management_lock" "protect_blobnfs_storage_accounts" {
+ for_each = {
+ for k, v in var.storage_accounts : k => v if v.storage_type == "blobnfs" && v.delete_protection
+ }
+
+ name = "protect-storage-${azurerm_storage_account.blobnfs[each.key].name}"
+ scope = azurerm_storage_account.blobnfs[each.key].id
+ lock_level = "CanNotDelete"
+}
+
+resource "azurerm_storage_account" "azurefiles" {
+ for_each = local.azurefile_storage_accounts_args
+
+ name = each.value.storage_account_name
+ resource_group_name = module.resource_groups["storage_accounts"].name
+ location = local.location
+ tags = local.tags
+
+ access_tier = each.value.access_tier
+ account_kind = each.value.account_kind
+ account_tier = each.value.account_tier
+ allow_nested_items_to_be_public = false
+ min_tls_version = "TLS1_2"
+ shared_access_key_enabled = true
+ https_traffic_only_enabled = false
+ account_replication_type = each.value.replication_type
+
+ network_rules {
+ default_action = "Deny"
+ ip_rules = var.use_authorized_ip_ranges_only ? values(var.authorized_ip_ranges) : values(merge(var.authorized_ip_ranges, { host_ip = data.http.host_ip.response_body }))
+ virtual_network_subnet_ids = var.subnet_ids //values(each.value.subnet_ids)
+ bypass = ["AzureServices"]
+ }
+ share_properties {
+ retention_policy {
+ days = each.value.file_share_retention_days
+ }
+ }
+
+ depends_on = [random_string.random]
+}
+
+resource "azurerm_storage_account" "blobnfs" {
+ for_each = local.blob_storage_accounts_args
+
+ name = each.value.storage_account_name
+ resource_group_name = module.resource_groups["storage_accounts"].name
+ location = local.location
+ tags = local.tags
+
+ access_tier = each.value.access_tier
+ account_kind = each.value.account_kind
+ account_tier = each.value.account_tier
+ allow_nested_items_to_be_public = false
+ is_hns_enabled = true
+ min_tls_version = "TLS1_2"
+ shared_access_key_enabled = true
+ nfsv3_enabled = true
+ https_traffic_only_enabled = true
+ account_replication_type = each.value.replication_type
+
+ network_rules {
+ default_action = "Deny"
+ ip_rules = var.use_authorized_ip_ranges_only ? values(var.authorized_ip_ranges) : values(merge(var.authorized_ip_ranges, { host_ip = data.http.host_ip.response_body }))
+ virtual_network_subnet_ids = var.subnet_ids //values(each.value.subnet_ids)
+ bypass = ["AzureServices"]
+ }
+
+ blob_properties {
+ delete_retention_policy {
+ days = each.value.blob_soft_delete_retention_days
+ }
+ container_delete_retention_policy {
+ days = each.value.container_soft_delete_retention_days
+ }
+ }
+
+ depends_on = [random_string.random]
+}
+
+resource "azurerm_storage_share" "azurefiles" {
+ for_each = local.azurefile_planes
+
+ name = each.value.container_name
+ storage_account_name = azurerm_storage_account.azurefiles[each.value.storage_account_name_prefix].name
+ quota = each.value.size
+ enabled_protocol = each.value.protocol
+}
+
+resource "azurerm_storage_container" "blobnfs" {
+ for_each = local.blob_planes
+
+ name = each.value.container_name
+ storage_account_name = azurerm_storage_account.blobnfs[each.value.storage_account_name_prefix].name
+ container_access_type = "private"
+}
diff --git a/variables.tf b/variables.tf
index e6af1c5..615fb9c 100644
--- a/variables.tf
+++ b/variables.tf
@@ -1,9 +1,20 @@
-variable "admin" {
+variable "owner" {
description = "Information for the user who administers the deployment."
type = object({
name = string
email = string
})
+
+ validation {
+ condition = try(
+ regex("hpccdemo", var.owner.name) != "hpccdemo", true
+ ) && try(
+ regex("hpccdemo", var.owner.email) != "hpccdemo", true
+ ) && try(
+ regex("@example.com", var.owner.email) != "@example.com", true
+ )
+ error_message = "Your name and email are required in the owner block and must not contain hpccdemo or @example.com."
+ }
}
variable "disable_naming_conventions" {
@@ -13,27 +24,76 @@ variable "disable_naming_conventions" {
}
variable "metadata" {
- description = "Names"
- type = map(string)
-}
-
-variable "resource_group" {
- description = "Resource group module variables."
- type = any
+ description = "Metadata module variables."
+ type = object({
+ market = string
+ sre_team = string
+ environment = string
+ product_name = string
+ business_unit = string
+ product_group = string
+ subscription_type = string
+ resource_group_type = string
+ project = string
+ additional_tags = map(string)
+ location = string
+ })
default = {
- unique_name = true
- location = null
+ business_unit = ""
+ environment = ""
+ market = ""
+ product_group = ""
+ product_name = "hpcc"
+ project = ""
+ resource_group_type = ""
+ sre_team = ""
+ subscription_type = ""
+ additional_tags = {}
+ location = ""
}
}
-variable "storage" {
- description = "HPCC Helm chart variables."
- type = any
- default = { default = {} }
+variable "subnet_ids" {
+ description = "Subnet IDs"
+ type = list(string)
+ default = null
}
-variable "tags" {
- description = "Tags"
+variable "storage_accounts" {
+ type = map(object({
+ delete_protection = optional(bool)
+ storage_account_name_prefix = string
+ storage_type = string
+ replication_type = optional(string, "ZRS")
+ subnet_ids = optional(map(string))
+ file_share_retention_days = optional(number, 7)
+ access_tier = optional(string, "Hot")
+ account_kind = string
+ account_tier = string
+ blob_soft_delete_retention_days = optional(number, 7)
+ container_soft_delete_retention_days = optional(number, 7)
+
+ planes = map(object({
+ category = string
+ plane_name = string
+ sub_path = string
+ size = number
+ sku = optional(string)
+ rwmany = bool
+ protocol = optional(string, "nfs")
+ }))
+ }))
+}
+
+variable "authorized_ip_ranges" {
+ description = "Authorized IP ranges"
type = map(string)
+ default = {}
}
+
+variable "use_authorized_ip_ranges_only" {
+ description = "Should Terraform only use the provided IPs for authorization?"
+ type = bool
+ default = false
+}
\ No newline at end of file
diff --git a/providers.tf b/versions.tf
similarity index 58%
rename from providers.tf
rename to versions.tf
index 616d95c..5252b15 100644
--- a/providers.tf
+++ b/versions.tf
@@ -1,21 +1,14 @@
terraform {
- required_providers {
- random = {
- source = "hashicorp/random"
- version = "3.1.0"
- }
+ required_version = ">= 1.4.6"
+ required_providers {
azurerm = {
source = "hashicorp/azurerm"
- version = "2.74.0"
+ version = ">= 3.63.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = ">= 3.3.0"
}
}
}
-
-provider "random" {
-}
-
-provider "azurerm" {
- features {}
-}
-