diff --git a/infra/modules/.cursor/rules/terraform-module.mdc b/infra/modules/.cursor/rules/terraform-module.mdc deleted file mode 100644 index 69654a5af8a3bba99898f8a0eacdfccc16dce2e8..0000000000000000000000000000000000000000 --- a/infra/modules/.cursor/rules/terraform-module.mdc +++ /dev/null @@ -1,355 +0,0 @@ ---- -description: This rule defines how osdu rules are created. -globs: ---- -# Terraform Module Development Guidelines - -This document outlines the standards and patterns for developing Terraform modules in our infrastructure codebase. - -## Module Structure - -``` -module-name/ -├── README.md # Module documentation -├── main.tf # Main module configuration -├── variables.tf # Input variable definitions -├── outputs.tf # Output definitions -├── test.sh # Test execution script -├── testing/ # Basic test configuration -│ ├── main.tf # Test implementation -│ └── unit_test.go # Basic unit tests -└── tests/ # Extended test suite - ├── .env.testing.template # Environment variables template - ├── tf_options.go # Common test configuration - ├── unit/ # Extended unit tests - │ └── *_test.go - └── integration/ # Integration tests - └── *_test.go -``` - -## Code Organization - -### 1. Main Configuration (main.tf) -- Start with required provider configuration -- Include copyright header -- Group resources logically -- Use data sources for existing resources -- Implement resource configurations -- Use dynamic blocks for optional features - -```hcl -terraform { - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "=3.90.0" # Pin to specific version - } - } -} - -provider "azurerm" { - features {} -} - -data "azurerm_resource_group" "main" { - name = var.resource_group_name -} - -resource "azurerm_example" "main" { - name = var.name - resource_group_name = data.azurerm_resource_group.main.name - location = data.azurerm_resource_group.main.location - - dynamic "optional_block" { - for_each = var.optional_feature_enabled ? [1] : [] - content { - // Configuration - } - } -} -``` - -### 2. Variables (variables.tf) -- Group variables by purpose -- Include clear descriptions -- Provide type constraints -- Set defaults where appropriate -- Mark sensitive variables - -```hcl -variable "name" { - description = "The name of the resource" - type = string -} - -variable "resource_tags" { - description = "Map of tags to apply to resources" - type = map(string) - default = {} -} -``` - -### 3. Outputs (outputs.tf) -- Include essential resource information -- Mark sensitive outputs -- Group related outputs -- Use maps for collections -- Include resource IDs and names - -```hcl -output "id" { - description = "The ID of the created resource" - value = azurerm_example.main.id -} - -output "properties" { - description = "Properties of the deployed resource" - value = { - id = azurerm_example.main.id - name = azurerm_example.main.name - } - sensitive = true -} -``` - -## Testing Framework - -### 1. Common Test Functions Library (test-functions.sh) -The common test functions library provides essential functionality for all module tests. Key functions include: - -Note: The `test-functions.sh` script should be sourced into test scripts using the relative path `../test-functions.sh`. - -``` - -### 2. Test Script Implementation (test.sh) -Each module must implement these required components: - -1. **Required Variables** -```bash -COMMON_LIB="../test-functions.sh" # Path to common functions -SCRIPT_DIR # Current script directory -RESOURCE_GROUP_PREFIX # Prefix for resource group names -DEFAULT_LOCATION # Default Azure region -RESOURCE_NAME # Module-specific resource name -``` - -2. **Required Functions** -```bash -setup_configuration() { - # Must implement: - # 1. Call setup_base_configuration - # 2. Generate resource names if needed - # 3. Export variables for Go tests -} - -create_tfvars_files() { - # Must implement: - # 1. Define tfvars content - # 2. Call create_base_tfvars_files -} - -validate_variables() { - # Should implement: - # 1. Call validate_base_variables - # 2. Validate module-specific variables -} - -print_help() { - # Should implement: - # 1. Call print_common_help - # 2. Add module-specific help info -} -``` - -3. **Standard Error Handling** -```bash -# Required error handling patterns -set -e # Exit on any error -trap 'cleanup' EXIT # Ensure cleanup on exit -validate_azure_credentials # Check Azure authentication - -# Error checking examples -if [ ! -f "$COMMON_LIB" ]; then - echo "Error: Common library not found" - exit 1 -fi - -if [ -z "$REQUIRED_VAR" ]; then - log "Error: Required variable not set" 1 - exit 1 -fi -``` - -### 3. Testing Directory Structure -Explanation of required test files and their purposes: - -``` -module-name/ -├── testing/ # Basic test configuration -│ ├── main.tf # Basic test implementation -│ │ # Required sections: -│ │ # - Provider configuration -│ │ # - Resource group module -│ │ # - Module under test -│ │ # - Required variables -│ │ -│ └── unit_test.go # Basic unit tests -│ # Required tests: -│ # - Resource count validation -│ # - Basic attribute validation -│ # - Required tag validation -│ -└── tests/ # Extended test suite - ├── tf_options.go # Test configuration - │ # Required configuration: - │ # - TF_VAR environment variables - │ # - Terraform options - │ # - Test fixtures - │ - ├── unit/ # Extended unit tests - │ └── *_test.go # Specific resource tests - │ # Should include: - │ # - Detailed attribute validation - │ # - Configuration variants - │ # - Error cases - │ - └── integration/ # Integration tests - └── *_test.go # Live resource tests - # Should include: - # - Resource creation verification - # - Resource update testing - # - Resource deletion testing -``` - -### 4. Common Test Patterns - -1. **Resource Name Generation** -```bash -# Standard pattern for resource names -generate_unique_name() { - local prefix="$1" - local resource_type="$2" - echo "${prefix}${resource_type}${RANDOM}" -} - -# Usage example -STORAGE_ACCOUNT_NAME=$(generate_unique_name "" "sa") -LOG_ANALYTICS_NAME=$(generate_unique_name "" "logs") -``` - -2. **Variable Validation** -```bash -validate_variables() { - validate_base_variables - - # Resource name validation - if [[ ! "$RESOURCE_NAME" =~ ^[a-z0-9]+$ ]]; then - log "Error: Resource name must be lowercase alphanumeric" 1 - exit 1 - fi - - # Location validation - if [[ ! "$LOCATION" =~ ^[a-z]+[a-z0-9]+$ ]]; then - log "Error: Invalid location format" 1 - exit 1 - fi -} -``` - -3. **Terraform Variable File Creation** -```bash -create_tfvars_files() { - # Standard format for tfvars content - local tfvars_content=" -name = \"$RESOURCE_NAME\" -resource_group_name = \"$RESOURCE_GROUP_NAME\" -location = \"$LOCATION\" - -# Optional configurations -tags = { - environment = \"testing\" - module = \"example\" -} - -# Resource-specific configurations -specific_setting = \"value\" -" - create_base_tfvars_files "$tfvars_content" -} -``` - -## Documentation - -### 1. README.md -- Module description -- Usage examples -- Input variables table -- Output variables table -- License information - -### 2. Code Comments -- Include copyright header -- Document non-obvious logic -- Explain variable purposes -- Detail resource configurations - -## Best Practices - -1. **Resource Naming** -- Use consistent resource names -- Prefix resources appropriately -- Follow Azure naming conventions - -2. **Security** -- Enable HTTPS by default -- Use latest TLS versions -- Implement proper access controls -- Mark sensitive outputs - -3. **Resource Management** -- Implement proper cleanup -- Use resource locks where needed -- Handle dependencies correctly - -4. **Testing** -- Implement both unit and integration tests -- Use meaningful test names -- Clean up test resources -- Validate all configurations - -## Continuous Integration - -1. **Pre-commit Checks** -- Run terraform fmt -- Validate configurations -- Check for sensitive data - -2. **Automated Testing** -- Execute unit tests -- Run integration tests -- Verify outputs - -3. **Documentation Updates** -- Keep README current -- Update examples -- Document changes - -## License and Copyright - -All terraform and go files must include the Apache 2.0 license header: - -```hcl -// Copyright © Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -``` \ No newline at end of file diff --git a/infra/modules/providers/azure/README.md b/infra/modules/providers/azure/README.md index 9f3165aa8abbbcf0ab742c8ea38f0c66ef8a2ad8..e60928d03d2fea73729ba3e82e4786072999cdfe 100755 --- a/infra/modules/providers/azure/README.md +++ b/infra/modules/providers/azure/README.md @@ -1,16 +1,138 @@ +## Azure Provider Modules Testing Guide +This guide explains how to test and validate the Azure provider modules using Mage as the primary task runner. -## License -Copyright © Microsoft Corporation +### Initial Setup -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at +#### Prerequisites +- Go 1.16 or later +- [Mage](https://magefile.org/) installed + ```bash + go install github.com/magefile/mage@latest + ``` +- Azure CLI installed and configured +- Required Environment Variables: + ```bash + # Required + export ARM_SUBSCRIPTION_ID="your-subscription-id" + + # Optional (with defaults) + export RESOURCE_GROUP_NAME="osdu-testing" # Default value + export LOCATION="eastus2" # Default value + ``` -[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) +### Development Workflow -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file +#### 1. Code Quality Checks +Before running tests, ensure your code meets the quality standards: + +```bash +# Run all code quality checks +mage check + +# Individual checks +mage lintTF # Check Terraform formatting +mage lintGO # Check Go formatting +``` + +To fix formatting issues: +```bash +# Fix Terraform formatting +terraform fmt + +# Fix Go formatting +go fmt ./... +``` + +#### 2. Clean Environment +Clean up any leftover state from previous runs: + +```bash +mage clean +``` + +This removes: +- `.terraform` directories +- `terraform.tfstate.d` directories +- State files (`terraform.tfstate`, `terraform.tfplan`, etc.) +- Lock files (`.terraform.lock.hcl`) + +#### 3. Running Tests + +##### Option A: Test Individual Module +Best for focused development on a specific module: +```bash +mage test <module_name> + +# Examples +mage test keyvault +mage test storage-account +mage test aks +``` + +##### Option B: Test All Modules +Best for comprehensive validation: +```bash +# Run all tests +mage testModules + +# Or use the all command which includes tests and validations +mage all +``` + +### Test Execution Process + +When you run tests, the following happens: + +1. **Preparation** + - Code quality checks are performed + - Environment is cleaned + - Azure credentials are validated + +2. **Resource Creation** + - Resource group is created in your Azure subscription + - Required Azure resources are deployed + +3. **Test Execution** + - Unit tests are run + - Integration tests are executed + - Results are reported with detailed logging + +4. **Cleanup** + - All created resources are automatically removed + - Test artifacts are cleaned up + +### Advanced Usage + +#### Direct Module Testing +While Mage is the recommended approach, you can also run tests directly within specific module directories. This is useful for: +- Debugging specific module issues +- Developing new module features +- Running tests with custom parameters +- Troubleshooting test failures + +To run tests directly: + +1. Navigate to the module directory: +```bash +cd providers/azure/<module_name> +# Example: cd providers/azure/keyvault +``` + +2. Run the test script: +```bash +./test.sh +``` + +The test.sh script provides: +- Detailed logging of each test step +- Direct access to test output +- Immediate feedback on failures +- Local control over test execution + +Note: When running tests directly, ensure you're in the correct module directory and have the required environment variables set: +```bash +export ARM_SUBSCRIPTION_ID="your-subscription-id" +export RESOURCE_GROUP_NAME="your-test-rg" # Optional +export LOCATION="your-location" # Optional +``` diff --git a/infra/modules/providers/azure/aks/main.tf b/infra/modules/providers/azure/aks/main.tf index b1d077ba164cc3d0d74bee71bcd2346a813029fe..7dc5ff5cc8ed16d23f56f4158ec5e6b7fd27c429 100644 --- a/infra/modules/providers/azure/aks/main.tf +++ b/infra/modules/providers/azure/aks/main.tf @@ -12,6 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=4.0.0" + } + } +} + +provider "azurerm" { + features {} +} // Need to be able to query the identityProfile to get kubelet client information. id, resourceid and client_id diff --git a/infra/modules/providers/azure/aks/test.sh b/infra/modules/providers/azure/aks/test.sh new file mode 100755 index 0000000000000000000000000000000000000000..66face859caec63a039f353980e4b09bc31abf38 --- /dev/null +++ b/infra/modules/providers/azure/aks/test.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +# Exit on error +set -e + +############################### +# Source Common Functions +############################### +COMMON_LIB="../test-functions.sh" +if [ ! -f "$COMMON_LIB" ]; then + echo "Error: Common library not found at $COMMON_LIB" + exit 1 +fi +source "$COMMON_LIB" + + +############################### +# Script Configuration +############################### +SCRIPT_DIR=$(get_script_dir) +setup_test_directories "$SCRIPT_DIR" + + +############################### +# Required Environment Variables +############################### +validate_azure_credentials + + +############################### +# Optional Variables +############################### +# These can be overridden by setting them before running the script +RESOURCE_GROUP_PREFIX=${RESOURCE_GROUP_PREFIX:-"terraform-test"} +DEFAULT_LOCATION="eastus2" +CLUSTER_NAME=${CLUSTER_NAME:-""} # Will be auto-generated if not provided +MAX_SURGE=${MAX_SURGE:-"5"} + + +############################### +# Help Documentation +############################### +print_help() { + print_common_help "AKS" "\n- Uses existing test configuration in testing directory\n- Creates required network infrastructure automatically\n- Generates SSH keys automatically" +} + + +############################### +# Required Module Functions +############################### +setup_configuration() { + # Setup base configuration first + setup_base_configuration "$RESOURCE_GROUP_PREFIX" "$DEFAULT_LOCATION" "$@" + + # Generate temporary name if not provided + if [ -z "$CLUSTER_NAME" ]; then + CLUSTER_NAME=$(generate_unique_name "aks" "temp") + fi + + # Export additional variables for Go tests + export CLUSTER_NAME +} + +create_tfvars_files() { + local tfvars_content="name = \"$CLUSTER_NAME\"\nresource_group_name = \"$RESOURCE_GROUP_NAME\"" + create_base_tfvars_files "$tfvars_content" +} + + +############################### +# Optional Module Functions +############################### +validate_variables() { + validate_base_variables + log "Using CLUSTER: $CLUSTER_NAME" 6 +} + + +############################### +# Main Execution +############################### +main() { + # Trap cleanup on exit + trap 'cleanup; cleanup_resource_group "$RESOURCE_GROUP_NAME" "$ARM_SUBSCRIPTION_ID"' EXIT + + # Setup configuration + setup_configuration "$@" + + # Validate variables + validate_variables + + # Setup + setup_azure_with_rg + create_tfvars_files + + # Run all tests + run_standard_test_sequence +} + +# Check for help flag +case "$1" in + -h|--help) + print_help + exit 0 + ;; +esac + +# Execute main function +main "$@" \ No newline at end of file diff --git a/infra/modules/providers/azure/aks/testing/main.tf b/infra/modules/providers/azure/aks/testing/main.tf index 123c82577d36d826669a8360629b6505bd60a8f2..c55c456e372d7ce465f65dff33e7e7b7db36e8dc 100644 --- a/infra/modules/providers/azure/aks/testing/main.tf +++ b/infra/modules/providers/azure/aks/testing/main.tf @@ -16,24 +16,23 @@ provider "azurerm" { features {} } -module "resource_group" { - source = "../../resource-group" - name = "osdu-module" - location = "eastus2" -} - module "network" { - source = "../../network" - depends_on = [module.resource_group] + source = "../../network" - name = format("osdu-module-vnet-%s", module.resource_group.random) - resource_group_name = module.resource_group.name + name = format("osdu-module-vnet-%s", random_string.unique.result) + resource_group_name = var.resource_group_name address_space = "10.10.0.0/16" dns_servers = ["8.8.8.8"] subnet_prefixes = ["10.10.1.0/24"] subnet_names = ["Cluster-Subnet"] } +resource "random_string" "unique" { + length = 8 + special = false + upper = false +} + resource "tls_private_key" "key" { algorithm = "RSA" } @@ -55,22 +54,100 @@ resource "null_resource" "save-key" { data "azurerm_client_config" "current" {} module "aks" { - source = "../" - depends_on = [module.resource_group] + source = "../" - name = format("osdu-module-cluster-%s", module.resource_group.random) - resource_group_name = module.resource_group.name - dns_prefix = format("osdu-module-cluster-%s", module.resource_group.random) + name = var.name + resource_group_name = var.resource_group_name + dns_prefix = format("osdu-module-cluster-%s", random_string.unique.result) ssh_public_key = "${trimspace(tls_private_key.key.public_key_openssh)} k8sadmin" vnet_subnet_id = module.network.subnets.0 - msi_enabled = true - kubeconfig_to_disk = false - oms_agent_enabled = true - azure_policy_enabled = false - max_surge = var.max_surge + # Node pool configuration + agent_vm_count = 2 + temporary_name_for_rotation = "rotation" + + default_node_pool_config = { + node_count = 2 + max_count = null + min_count = null + } + + # Specify Kubernetes version + aks_version_prefix = "1.30" + resource_tags = { osdu = "module" } +} + +# Base Variables +variable "name" { + type = string + description = "The name of the AKS cluster" +} + +variable "resource_group_name" { + type = string + description = "The name of the resource group" +} + +variable "location" { + type = string + description = "The location of the cluster" + default = "eastus2" +} + +# Outputs +output "id" { + value = module.aks.id +} + +output "name" { + value = module.aks.name +} + +output "kube_config" { + value = module.aks.kube_config + sensitive = true +} + +output "kube_config_block" { + value = module.aks.kube_config_block + sensitive = true +} + +output "kubeconfig_done" { + value = module.aks.kubeconfig_done +} + +output "principal_id" { + value = module.aks.principal_id +} + +output "kubelet_identity_id" { + value = module.aks.kubelet_identity_id +} + +output "kubelet_object_id" { + value = module.aks.kubelet_object_id +} + +output "kubelet_client_id" { + value = module.aks.kubelet_client_id +} + +output "node_resource_group" { + value = module.aks.node_resource_group +} + +output "aks_egress_ip_address" { + value = module.aks.aks_egress_ip_address +} + +output "kubernetes_version" { + value = module.aks.kubernetes_version +} +output "aks_os_sku" { + value = module.aks.aks_os_sku } diff --git a/infra/modules/providers/azure/aks/testing/unit_test.go b/infra/modules/providers/azure/aks/testing/unit_test.go index 8789051561acc5d22cc9c2b28556d03913dfbfa8..9245f4604c344599e38827ff65e9290711cbf7e2 100644 --- a/infra/modules/providers/azure/aks/testing/unit_test.go +++ b/infra/modules/providers/azure/aks/testing/unit_test.go @@ -15,6 +15,7 @@ package test import ( "encoding/json" + "os" "testing" "github.com/gruntwork-io/terratest/modules/random" @@ -23,13 +24,7 @@ import ( ) var name = "cluster-" -var location = "eastus" -var count = 13 - -var tfOptions = &terraform.Options{ - TerraformDir: "./", - Upgrade: true, -} +var count = 12 func asMap(t *testing.T, jsonString string) map[string]interface{} { var theMap map[string]interface{} @@ -40,15 +35,42 @@ func asMap(t *testing.T, jsonString string) map[string]interface{} { } func TestTemplate(t *testing.T) { + // Get location from environment variable or use default + location := os.Getenv("LOCATION") + if location == "" { + location = "eastus2" + } + + // Get resource group name from environment or generate it + resourceGroupName := os.Getenv("RESOURCE_GROUP_NAME") + if resourceGroupName == "" { + uniqueID := random.UniqueId() + resourceGroupName = "terraform-test-" + uniqueID + } + + // Generate unique names for resources + uniqueID := random.UniqueId() + workspace := name + uniqueID + clusterName := "tftest" + uniqueID + "aks" + + tfOptions := &terraform.Options{ + TerraformDir: "./", + Upgrade: true, + Vars: map[string]interface{}{ + "name": clusterName, + "resource_group_name": resourceGroupName, + "location": location, + }, + } expectedResult := asMap(t, `{ - "kubernetes_version": "1.25.5" + "kubernetes_version": "1.30.9" }`) testFixture := infratests.UnitTestFixture{ GoTest: t, TfOptions: tfOptions, - Workspace: name + random.UniqueId(), + Workspace: workspace, PlanAssertions: nil, ExpectedResourceCount: count, ExpectedResourceAttributeValues: infratests.ResourceDescription{ diff --git a/infra/modules/providers/azure/aks/variables.tf b/infra/modules/providers/azure/aks/variables.tf index 3696397dd9d7218d6b8ccc0dddfc768cb4b9652a..cf98660185479540b981f5f5ec875dc80e9ea092 100644 --- a/infra/modules/providers/azure/aks/variables.tf +++ b/infra/modules/providers/azure/aks/variables.tf @@ -75,7 +75,7 @@ variable "drain_timeout_in_minutes" { variable "aks_version_prefix" { description = "major.minor version should be supplied to this variable so that it can be used to generate the most recent patch version." type = string - default = "1.27" + default = "1.30" } diff --git a/infra/modules/providers/azure/app-insights/main.tf b/infra/modules/providers/azure/app-insights/main.tf index f520d9d99273b5cb308479bb981bceec8f759394..a61acbfc0d8ea127860aa747a876816b96ed9b19 100755 --- a/infra/modules/providers/azure/app-insights/main.tf +++ b/infra/modules/providers/azure/app-insights/main.tf @@ -16,11 +16,15 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.90.0, <=4.17.0" + version = "<5.0.0" } } } +provider "azurerm" { + features {} +} + data "azurerm_resource_group" "appinsights" { name = var.service_plan_resource_group_name } diff --git a/infra/modules/providers/azure/app-monitoring/main.tf b/infra/modules/providers/azure/app-monitoring/main.tf index b342f54cbd0194bc21b539b8b30541d28ff86074..ff776a697069f3c6e15c300c99e6c407d1e861a0 100755 --- a/infra/modules/providers/azure/app-monitoring/main.tf +++ b/infra/modules/providers/azure/app-monitoring/main.tf @@ -16,11 +16,15 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.90.0, <=4.17.0" + version = "<=5.0.0" } } } +provider "azurerm" { + features {} +} + locals { scaling_name = "Instance" scaling_operator = "Include" diff --git a/infra/modules/providers/azure/appgw/main.tf b/infra/modules/providers/azure/appgw/main.tf index 3fadd9cf97fea5e71d1edacf6704c80d7d4b749f..992b4bb2fe55564145b95aabfa2b09c9578e58f8 100644 --- a/infra/modules/providers/azure/appgw/main.tf +++ b/infra/modules/providers/azure/appgw/main.tf @@ -12,6 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + +provider "azurerm" { + features {} +} data "azurerm_client_config" "current" {} diff --git a/infra/modules/providers/azure/appgw_istio/main.tf b/infra/modules/providers/azure/appgw_istio/main.tf index bc1a42defa8c3156365728f32470e34a07f6ef26..d3c39251a2a478544705d453a2739451e950ed18 100644 --- a/infra/modules/providers/azure/appgw_istio/main.tf +++ b/infra/modules/providers/azure/appgw_istio/main.tf @@ -12,6 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + +provider "azurerm" { + features {} +} data "azurerm_client_config" "current" {} diff --git a/infra/modules/providers/azure/container-registry/main.tf b/infra/modules/providers/azure/container-registry/main.tf index a4ece597a88b8f3491090c1299205ef225643459..1ce36e1e3ed06897be5dfb933cf731e53e9bfc62 100644 --- a/infra/modules/providers/azure/container-registry/main.tf +++ b/infra/modules/providers/azure/container-registry/main.tf @@ -16,11 +16,15 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.90.0, <=4.17.0" + version = "<=5.0.0" } } } +provider "azurerm" { + features {} +} + data "azurerm_resource_group" "container_registry" { name = var.resource_group_name } diff --git a/infra/modules/providers/azure/cosmosdb/main.tf b/infra/modules/providers/azure/cosmosdb/main.tf index 1fad5da0061d6e56708c7f4ddb8a23aa579f7c7e..58615c4fc353f44d928771ae86a5c1b7080f0186 100755 --- a/infra/modules/providers/azure/cosmosdb/main.tf +++ b/infra/modules/providers/azure/cosmosdb/main.tf @@ -12,6 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=4.0.0" + } + } +} + +provider "azurerm" { + features {} +} + data "azurerm_resource_group" "cosmosdb" { name = var.resource_group_name } @@ -28,7 +41,8 @@ resource "azurerm_cosmosdb_account" "cosmosdb" { kind = var.kind tags = var.resource_tags - enable_automatic_failover = var.automatic_failover + enable_automatic_failover = var.automatic_failover + enable_multiple_write_locations = var.enable_multiple_write_locations public_network_access_enabled = var.public_network_access_enabled ip_range_filter = local.ip_range_filter diff --git a/infra/modules/providers/azure/cosmosdb/test.sh b/infra/modules/providers/azure/cosmosdb/test.sh new file mode 100755 index 0000000000000000000000000000000000000000..b99777741e442668c69bd94947332156cf32fce7 --- /dev/null +++ b/infra/modules/providers/azure/cosmosdb/test.sh @@ -0,0 +1,173 @@ +#!/bin/bash + +# Exit on error +set -e + +############################### +# Source Common Functions +############################### +COMMON_LIB="../test-functions.sh" +if [ ! -f "$COMMON_LIB" ]; then + echo "Error: Common library not found at $COMMON_LIB" + exit 1 +fi +source "$COMMON_LIB" + + +############################### +# Script Configuration +############################### +SCRIPT_DIR=$(get_script_dir) +setup_test_directories "$SCRIPT_DIR" + + +############################### +# Required Environment Variables +############################### +validate_azure_credentials + + +############################### +# Optional Variables +############################### +# These can be overridden by setting them before running the script +RESOURCE_GROUP_PREFIX=${RESOURCE_GROUP_PREFIX:-"terraform-test"} +DEFAULT_LOCATION="eastus2" +COSMOS_DB_NAME=${COSMOS_DB_NAME:-""} # Will be auto-generated if not provided +COSMOS_DB_KIND=${COSMOS_DB_KIND:-"GlobalDocumentDB"} # Default to GlobalDocumentDB +COSMOS_DB_CONSISTENCY_LEVEL=${COSMOS_DB_CONSISTENCY_LEVEL:-"Session"} # Default to Session + + +############################### +# Help Documentation +############################### +print_help() { + print_common_help "CosmosDB" "\n- If not specified, a unique CosmosDB name will be generated\n- Default kind is 'GlobalDocumentDB'\n- Default consistency level is 'Session'" +} + + +############################### +# Required Module Functions +############################### +setup_configuration() { + # Setup base configuration first + setup_base_configuration "$RESOURCE_GROUP_PREFIX" "$DEFAULT_LOCATION" "$@" + + # Generate CosmosDB name if not provided + if [ -z "$COSMOS_DB_NAME" ]; then + COSMOS_DB_NAME=$(generate_unique_name "cosmos" "" | tr '[:upper:]' '[:lower:]') + fi + + # Export additional variables for Go tests + export COSMOS_DB_NAME + export COSMOS_DB_KIND + export COSMOS_DB_CONSISTENCY_LEVEL +} + +create_tfvars_files() { + local tfvars_content=" +name = \"$COSMOS_DB_NAME\" +resource_group_name = \"$RESOURCE_GROUP_NAME\" +primary_replica_location = \"$LOCATION\" +kind = \"$COSMOS_DB_KIND\" +consistency_level = \"$COSMOS_DB_CONSISTENCY_LEVEL\" + +databases = [ + { + name = \"osdu-module-database\" + throughput = 4000 + } +] + +sql_collections = [ + { + name = \"osdu-module-container1\" + database_name = \"osdu-module-database\" + partition_key_path = \"/id\" + partition_key_version = 1 + } +] +" + create_base_tfvars_files "$tfvars_content" +} + + +############################### +# Optional Module Functions +############################### +validate_variables() { + validate_base_variables + + # Validate CosmosDB specific variables + if [[ ! "$COSMOS_DB_NAME" =~ ^[a-z0-9-]+$ ]]; then + log "Error: CosmosDB name must be lowercase alphanumeric with hyphens" 1 + exit 1 + fi + + # Validate CosmosDB kind + local valid_kinds=("GlobalDocumentDB" "MongoDB") + local kind_valid=false + for valid_kind in "${valid_kinds[@]}"; do + if [ "$COSMOS_DB_KIND" == "$valid_kind" ]; then + kind_valid=true + break + fi + done + + if [ "$kind_valid" != true ]; then + log "Error: Invalid CosmosDB kind. Must be one of: ${valid_kinds[*]}" 1 + exit 1 + fi + + # Validate consistency level + local valid_consistency_levels=("BoundedStaleness" "Eventual" "Session" "Strong" "ConsistentPrefix") + local consistency_valid=false + for valid_level in "${valid_consistency_levels[@]}"; do + if [ "$COSMOS_DB_CONSISTENCY_LEVEL" == "$valid_level" ]; then + consistency_valid=true + break + fi + done + + if [ "$consistency_valid" != true ]; then + log "Error: Invalid consistency level. Must be one of: ${valid_consistency_levels[*]}" 1 + exit 1 + fi + + log "Using CosmosDB: $COSMOS_DB_NAME" 6 + log "Using Kind: $COSMOS_DB_KIND" 6 + log "Using Consistency Level: $COSMOS_DB_CONSISTENCY_LEVEL" 6 +} + + +############################### +# Main Execution +############################### +main() { + # Trap cleanup on exit + trap 'cleanup; cleanup_resource_group "$RESOURCE_GROUP_NAME" "$ARM_SUBSCRIPTION_ID"' EXIT + + # Setup configuration + setup_configuration "$@" + + # Validate variables + validate_variables + + # Setup + setup_azure_with_rg + create_tfvars_files + + # Run all tests + run_standard_test_sequence +} + +# Check for help flag +case "$1" in + -h|--help) + print_help + exit 0 + ;; +esac + +# Execute main function +main "$@" \ No newline at end of file diff --git a/infra/modules/providers/azure/cosmosdb/testing/main.tf b/infra/modules/providers/azure/cosmosdb/testing/main.tf index 2299d3d06eba4342bd1d3d05eeeee80e944bccc6..e9ee6a0188460cce39b622c22c88059db5c407fe 100644 --- a/infra/modules/providers/azure/cosmosdb/testing/main.tf +++ b/infra/modules/providers/azure/cosmosdb/testing/main.tf @@ -2,84 +2,138 @@ provider "azurerm" { features {} } -module "resource_group" { - source = "../../resource-group" +module "cosmosdb_sql" { + source = "../" - name = "osdu-module" - location = "eastus2" -} + name = "${var.name}1" + resource_group_name = var.resource_group_name + kind = var.kind + automatic_failover = var.automatic_failover + consistency_level = var.consistency_level + primary_replica_location = var.primary_replica_location + authorized_ip_ranges = var.authorized_ip_ranges -module "cosmosdb_sql" { - source = "../" - depends_on = [module.resource_group] - - name = "osdu-module-sql-${module.resource_group.random}" - resource_group_name = module.resource_group.name - - kind = "GlobalDocumentDB" - automatic_failover = true - consistency_level = "Session" - primary_replica_location = module.resource_group.location - - databases = [ - { - name = "osdu-module-database" - throughput = 4000 # This is max throughput Minimum level is 4000 - } - ] - sql_collections = [ - { - name = "osdu-module-container1" - database_name = "osdu-module-database" - partition_key_path = "/id" - - }, - { - name = "osdu-module-container2" - database_name = "osdu-module-database" - partition_key_path = "/id" - } - ] - - resource_tags = { - source = "terraform", - } + databases = var.databases + sql_collections = var.sql_collections + resource_tags = var.resource_tags + enable_replication = false } module "cosmosdb_graph" { - source = "../" - depends_on = [module.resource_group] - - name = "osdu-module-graph-${module.resource_group.random}" - resource_group_name = module.resource_group.name - - kind = "GlobalDocumentDB" - automatic_failover = true - consistency_level = "Session" - primary_replica_location = module.resource_group.location - - graph_databases = [ - { - name = "osdu-module-database" - throughput = 4000 # This is max throughput Minimum level is 4000 - } - ] - - graphs = [ - { - name = "osdu-module-graph1" - database_name = "osdu-module-database" - partition_key_path = "/mypartition" - }, - { - name = "osdu-module-graph2" - database_name = "osdu-module-database" - partition_key_path = "/mypartition" - } - ] - - resource_tags = { - source = "terraform", - } + source = "../" + + name = "${var.name}2" + resource_group_name = var.resource_group_name + + kind = var.kind + automatic_failover = var.automatic_failover + consistency_level = var.consistency_level + primary_replica_location = var.primary_replica_location + authorized_ip_ranges = var.authorized_ip_ranges + + graph_databases = var.graph_databases + graphs = var.graphs + resource_tags = var.resource_tags + enable_replication = false +} + +# Variables +variable "name" { + type = string + description = "The name of the Cosmos DB instance" +} + +variable "resource_group_name" { + type = string + description = "The name of the resource group" } + +variable "primary_replica_location" { + type = string + description = "The primary replica location" +} + +variable "kind" { + type = string + description = "The kind of CosmosDB to create" + default = "GlobalDocumentDB" +} + +variable "automatic_failover" { + type = bool + description = "Enable automatic failover for regions" + default = true +} + +variable "consistency_level" { + type = string + description = "The consistency level for the CosmosDB Account" + default = "Session" +} + +variable "authorized_ip_ranges" { + type = list(string) + description = "The list of IP ranges to allow access to the CosmosDB account" + default = [] +} + +variable "databases" { + type = list(object({ + name = string + throughput = number + })) + description = "List of databases to create" + default = [] +} + +variable "sql_collections" { + type = list(object({ + name = string + database_name = string + partition_key_path = string + partition_key_version = number + })) + description = "List of SQL collections to create" + default = [] +} + +variable "graphs" { + type = list(object({ + name = string + database_name = string + partition_key_path = string + })) + description = "List of graphs to create" + default = [] +} + +variable "graph_databases" { + type = list(object({ + name = string + throughput = number + })) + description = "List of graph databases to create" + default = [] +} + +variable "resource_tags" { + type = map(string) + description = "Map of tags to apply to resources" + default = {} +} + +# Outputs required for integration tests +output "properties" { + value = module.cosmosdb_sql.properties + sensitive = true +} + +output "resource_group_name" { + value = var.resource_group_name +} + +output "account_name" { + value = "${var.name}1" +} + diff --git a/infra/modules/providers/azure/cosmosdb/testing/unit_test.go b/infra/modules/providers/azure/cosmosdb/testing/unit_test.go index e75df24533d916b4d7c1eb1cefc18a42bbfb8267..211f1d5d9226cd045279a08a279c4c2e38d309c9 100644 --- a/infra/modules/providers/azure/cosmosdb/testing/unit_test.go +++ b/infra/modules/providers/azure/cosmosdb/testing/unit_test.go @@ -2,6 +2,7 @@ package test import ( "encoding/json" + "os" "testing" "github.com/gruntwork-io/terratest/modules/random" @@ -9,13 +10,55 @@ import ( "github.com/microsoft/cobalt/test-harness/infratests" ) -var name = "cosmosdb-" var location = "eastus" -var count = 12 +var count = 8 var tfOptions = &terraform.Options{ TerraformDir: "./", Upgrade: true, + Vars: map[string]interface{}{ + "name": os.Getenv("COSMOS_DB_NAME"), + "resource_group_name": os.Getenv("RESOURCE_GROUP_NAME"), + "primary_replica_location": location, + "databases": []map[string]interface{}{ + { + "name": "osdu-module-database", + "throughput": 4000, + }, + }, + "sql_collections": []map[string]interface{}{ + { + "name": "osdu-module-container1", + "database_name": "osdu-module-database", + "partition_key_path": "/id", + "partition_key_version": 1, + }, + { + "name": "osdu-module-container2", + "database_name": "osdu-module-database", + "partition_key_path": "/id", + "partition_key_version": 1, + }, + }, + "graph_databases": []map[string]interface{}{ + { + "name": "osdu-module-database", + "throughput": 4000, + }, + }, + "graphs": []map[string]interface{}{ + { + "name": "osdu-module-graph1", + "database_name": "osdu-module-database", + "partition_key_path": "/mypartition", + }, + { + "name": "osdu-module-graph2", + "database_name": "osdu-module-database", + "partition_key_path": "/mypartition", + }, + }, + }, } func asMap(t *testing.T, jsonString string) map[string]interface{} { @@ -27,13 +70,14 @@ func asMap(t *testing.T, jsonString string) map[string]interface{} { } func TestTemplate(t *testing.T) { + // Add debug output for plan + terraform.InitAndPlan(t, tfOptions) expectedSqlAccountResult := asMap(t, `{ "kind": "GlobalDocumentDB", - "enable_automatic_failover": true, "enable_multiple_write_locations": false, "is_virtual_network_filter_enabled": false, - "offer_type": "Standard", + "offer_type": "Standard", "consistency_policy": [{ "consistency_level": "Session" }] @@ -41,10 +85,9 @@ func TestTemplate(t *testing.T) { expectedGraphAccountResult := asMap(t, `{ "kind": "GlobalDocumentDB", - "enable_automatic_failover": true, "enable_multiple_write_locations": false, "is_virtual_network_filter_enabled": false, - "offer_type": "Standard", + "offer_type": "Standard", "consistency_policy": [{ "consistency_level": "Session" }], @@ -75,7 +118,7 @@ func TestTemplate(t *testing.T) { testFixture := infratests.UnitTestFixture{ GoTest: t, TfOptions: tfOptions, - Workspace: name + random.UniqueId(), + Workspace: os.Getenv("COSMOS_DB_NAME") + random.UniqueId(), PlanAssertions: nil, ExpectedResourceCount: count, ExpectedResourceAttributeValues: infratests.ResourceDescription{ diff --git a/infra/modules/providers/azure/cosmosdb/tests/integration/cosmos.go b/infra/modules/providers/azure/cosmosdb/tests/integration/cosmos.go deleted file mode 100644 index 1b68cc160c1683ef2d1b4febffc8154ab849c138..0000000000000000000000000000000000000000 --- a/infra/modules/providers/azure/cosmosdb/tests/integration/cosmos.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright © Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "fmt" - "os" - "testing" - - "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" - httpClient "github.com/gruntwork-io/terratest/modules/http-helper" - "github.com/microsoft/cobalt/test-harness/infratests" - "github.com/microsoft/cobalt/test-harness/terratest-extensions/modules/azure" - "github.com/stretchr/testify/require" -) - -var subscription = os.Getenv("ARM_SUBSCRIPTION_ID") - -// validateOutputs - Asserts that expected output values are present. -func validateOutputs(t *testing.T, id string, endpoint string, primaryMasterKey string, connectionStrings []interface{}) { - require.NotEqual(t, "", id, "ID not returned.") - require.NotEmpty(t, endpoint, "Endpoint not returned.") - require.NotEmpty(t, primaryMasterKey, "Master Key missing.") - require.Equal(t, 4, len(connectionStrings), "Unexpected number of connection strings.") -} - -// healthCheck - Asserts that the deployment was successful. -func healthCheck(t *testing.T, provisionState *string) { - require.Equal(t, "Succeeded", *provisionState, "The deployment hasn't succeeded.") -} - -// validateOfferType - Asserts that the fixed offer type "Standard" has not changed. -func validateOfferType(t *testing.T, offerType documentdb.DatabaseAccountOfferType) { - require.Equal(t, documentdb.Standard, offerType, "The offer type is incorrect.") -} - -// validateFailOverPriority - Asserts that the fixed fail over priority '0' has not changed. -func validateFailOverPriority(t *testing.T, failOverPolicy documentdb.FailoverPolicy) { - require.Equal(t, int32(0), *failOverPolicy.FailoverPriority, "The fail over priority is incorrect.") -} - -// getModuleOutputs - Extracts the output variables from property map. -func getModuleOutputs(output infratests.TerraformOutput, outputName string) (id string, endpoint string, primaryMasterKey string, connectionStrings []interface{}) { - properties := output[outputName].(map[string]interface{}) - cosmosDBProperties := properties["cosmosdb"].(map[string]interface{}) - - id = cosmosDBProperties["id"].(string) - endpoint = cosmosDBProperties["endpoint"].(string) - primaryMasterKey = cosmosDBProperties["primary_key"].(string) - connectionStrings = cosmosDBProperties["connection_strings"].([]interface{}) - - return -} - -// validateServiceResponse - Attempt to perform a HTTP request to the live endpoint. -func validateServiceResponse(t *testing.T, output infratests.TerraformOutput, outputName string) { - _, endpoint, _, _ := getModuleOutputs(output, outputName) - statusCode, _ := httpClient.HttpGet(t, endpoint) - - require.Equal(t, 401, statusCode, "Service did not respond with the expected Unauthorized status code.") -} - -// InspectProvisionedCosmosDBAccount - Runs test assertions to validate that a provisioned CosmosDB Account -// is operational. -func InspectProvisionedCosmosDBAccount(resourceGroupOutputName, accountName, outputName string) func(t *testing.T, output infratests.TerraformOutput) { - return func(t *testing.T, output infratests.TerraformOutput) { - resourceGroupName := output[resourceGroupOutputName].(string) - accountName := output[accountName].(string) - t.Log(fmt.Sprintf("Cosmosdb - subscription: %s, rg: %s, cosmos: %s", subscription, resourceGroupName, accountName)) - result := azure.GetCosmosDBAccount(t, subscription, resourceGroupName, accountName) - - t.Log(fmt.Sprintf("Cosmosdb - HealthCheck - %s", *result.ProvisioningState)) - healthCheck(t, result.ProvisioningState) - - t.Log(fmt.Sprintf("Cosmosdb - Validate offer type: %s", result.DatabaseAccountOfferType)) - validateOfferType(t, result.DatabaseAccountOfferType) - - failOverPolicies := *result.FailoverPolicies - t.Log(fmt.Sprintf("Failover policies [%s]", len(failOverPolicies))) - require.Equal(t, 1, len(failOverPolicies)) - validateFailOverPriority(t, failOverPolicies[0]) - - t.Log(fmt.Sprintf("Cosmosdb - Validate Services response output from %s", outputName)) - validateServiceResponse(t, output, outputName) - } -} - -// InspectCosmosDBModuleOutputs - Runs test assertions to validate that the module outputs are valid. -func InspectCosmosDBModuleOutputs(outputName string) func(t *testing.T, output infratests.TerraformOutput) { - return func(t *testing.T, output infratests.TerraformOutput) { - id, endpoint, primaryMasterKey, connectionStrings := getModuleOutputs(output, outputName) - validateOutputs(t, id, endpoint, primaryMasterKey, connectionStrings) - } -} diff --git a/infra/modules/providers/azure/cosmosdb/tests/integration/cosmos_test.go b/infra/modules/providers/azure/cosmosdb/tests/integration/cosmos_test.go deleted file mode 100644 index b8e785f66d582212396ac8c35020ed75ed0ba1c5..0000000000000000000000000000000000000000 --- a/infra/modules/providers/azure/cosmosdb/tests/integration/cosmos_test.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright © Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "testing" - - "github.com/microsoft/cobalt/infra/modules/providers/azure/cosmosdb/tests" - "github.com/microsoft/cobalt/test-harness/infratests" -) - -func TestCosmosDeployment(t *testing.T) { - - testFixture := infratests.IntegrationTestFixture{ - GoTest: t, - TfOptions: tests.CosmosDBOptions, - ExpectedTfOutputCount: 3, - TfOutputAssertions: []infratests.TerraformOutputValidation{ - InspectCosmosDBModuleOutputs("properties"), - InspectProvisionedCosmosDBAccount("resource_group_name", "account_name", "properties"), - }, - } - infratests.RunIntegrationTests(&testFixture) -} diff --git a/infra/modules/providers/azure/cosmosdb/tests/tf_options.go b/infra/modules/providers/azure/cosmosdb/tests/tf_options.go deleted file mode 100644 index 5184e6302190ab7ce5e362f803c755c2aa2bbab7..0000000000000000000000000000000000000000 --- a/infra/modules/providers/azure/cosmosdb/tests/tf_options.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright © Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package tests - -import ( - "os" - - "github.com/gruntwork-io/terratest/modules/terraform" -) - -// CosmosDBAccountName the name of the Database account in CosmosDB -var cosmosDBAccountName = os.Getenv("COSMOSDB_ACCOUNT_NAME") - -// PrimaryReplicaLocation the Azure region for the primary replica -var primaryReplicaLocation = os.Getenv("PRIMARY_REPLICA_LOCATION") - -// ResourceGroupName the name of the resource group -var resourceGroupName = os.Getenv("RESOURCE_GROUP_NAME") - -// CosmosDBOptions terraform options used for cosmos integration testing -var CosmosDBOptions = &terraform.Options{ - TerraformDir: "../../", - Upgrade: true, - Vars: map[string]interface{}{ - "name": cosmosDBAccountName, - "resource_group_name": resourceGroupName, - "primary_replica_location": primaryReplicaLocation, - }, -} diff --git a/infra/modules/providers/azure/cosmosdb/variables.tf b/infra/modules/providers/azure/cosmosdb/variables.tf index 3b6c829f3be10d197b686aaba8c5809a9e811c50..65075f3589f9dd2abf241bb1000dc61a1fa54deb 100755 --- a/infra/modules/providers/azure/cosmosdb/variables.tf +++ b/infra/modules/providers/azure/cosmosdb/variables.tf @@ -118,3 +118,9 @@ variable "enable_replication" { default = true description = "Enable/disable geographic replication for the CosmosDB account" } + +variable "enable_multiple_write_locations" { + type = bool + default = false + description = "Enable multiple write locations for this Cosmos DB account." +} diff --git a/infra/modules/providers/azure/data-explorer/main.tf b/infra/modules/providers/azure/data-explorer/main.tf index 2acca9e84b480c090f93499612fd78d87743ade9..a5a58197cbbe4903a7a39f38f3d09361733d10fe 100644 --- a/infra/modules/providers/azure/data-explorer/main.tf +++ b/infra/modules/providers/azure/data-explorer/main.tf @@ -1,3 +1,16 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + +provider "azurerm" { + features {} +} + data "azurerm_resource_group" "main" { name = var.resource_group_name } diff --git a/infra/modules/providers/azure/event-grid/main.tf b/infra/modules/providers/azure/event-grid/main.tf index c4de8bdf3be181dbaadb14594b100e72aaf3ed40..306e43b3412a231c12c6c7154cb349e58ca42452 100644 --- a/infra/modules/providers/azure/event-grid/main.tf +++ b/infra/modules/providers/azure/event-grid/main.tf @@ -12,6 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + +provider "azurerm" { + features {} +} + locals { topics = [ diff --git a/infra/modules/providers/azure/keyvault-cert/main.tf b/infra/modules/providers/azure/keyvault-cert/main.tf index e0812910e97baa884d1f04491a8987c63690fed6..591bdbce8dfdf4be8b26a667c29371fb5e8a553e 100644 --- a/infra/modules/providers/azure/keyvault-cert/main.tf +++ b/infra/modules/providers/azure/keyvault-cert/main.tf @@ -11,6 +11,20 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + +provider "azurerm" { + features {} +} + resource "azurerm_key_vault_certificate" "kv_cert_import" { name = var.key_vault_cert_name key_vault_id = var.keyvault_id diff --git a/infra/modules/providers/azure/keyvault-policy/main.tf b/infra/modules/providers/azure/keyvault-policy/main.tf index 319214342b704286fd18f86ff0724c078517f46a..914b62e124c5cb1786e4144af009586fe604e295 100644 --- a/infra/modules/providers/azure/keyvault-policy/main.tf +++ b/infra/modules/providers/azure/keyvault-policy/main.tf @@ -12,6 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + +provider "azurerm" { + features {} +} + resource "azurerm_key_vault_access_policy" "keyvault" { count = length(var.object_ids) key_vault_id = var.vault_id diff --git a/infra/modules/providers/azure/keyvault-secret/main.tf b/infra/modules/providers/azure/keyvault-secret/main.tf index f3fcd1c30b45d11de86cfa556e6276d2def9c05f..83b7196d83788d8d62ec00600ba78ece092e8728 100644 --- a/infra/modules/providers/azure/keyvault-secret/main.tf +++ b/infra/modules/providers/azure/keyvault-secret/main.tf @@ -16,11 +16,15 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.90.0, <=4.17.0" + version = "<=5.0.0" } } } +provider "azurerm" { + features {} +} + locals { secret_names = keys(var.secrets) } diff --git a/infra/modules/providers/azure/keyvault/main.tf b/infra/modules/providers/azure/keyvault/main.tf index d3261834336ab5382b093ebcbb95fef971ec2185..bbd3d556bc1cbae658b49bbbb0bf3b5f32a8fb47 100644 --- a/infra/modules/providers/azure/keyvault/main.tf +++ b/infra/modules/providers/azure/keyvault/main.tf @@ -16,7 +16,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.90.0, <=4.17.0" + version = "<=5.0.0" } } } diff --git a/infra/modules/providers/azure/log-analytics/main.tf b/infra/modules/providers/azure/log-analytics/main.tf index 02ca3d0db6f6bc744d6953244abbe373f68a4b39..f2b3dc63defdd3bc5b369ed61bd2c3eeb9bffadf 100644 --- a/infra/modules/providers/azure/log-analytics/main.tf +++ b/infra/modules/providers/azure/log-analytics/main.tf @@ -16,11 +16,15 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.90.0, <=4.17.0" + version = "<5.0.0" } } } +provider "azurerm" { + features {} +} + data "azurerm_resource_group" "main" { name = var.resource_group_name } diff --git a/infra/modules/providers/azure/network/main.tf b/infra/modules/providers/azure/network/main.tf index bc52a809de3fa68f8ea8135e4b446ae3462156bb..8a43460775d71bdebff09069067b11e784701b76 100644 --- a/infra/modules/providers/azure/network/main.tf +++ b/infra/modules/providers/azure/network/main.tf @@ -16,11 +16,15 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.90.0, <=4.17.0" + version = "<=5.0.0" } } } +provider "azurerm" { + features {} +} + data "azurerm_resource_group" "main" { name = var.resource_group_name } diff --git a/infra/modules/providers/azure/postgreSQL/main.tf b/infra/modules/providers/azure/postgreSQL/main.tf index ae7627e9036d28a07d94852b13151746c6367488..7539e39f10a0f47f6248fbcae08f2c1d0a237b20 100644 --- a/infra/modules/providers/azure/postgreSQL/main.tf +++ b/infra/modules/providers/azure/postgreSQL/main.tf @@ -12,6 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + +provider "azurerm" { + features {} +} data "azurerm_resource_group" "main" { name = var.resource_group_name diff --git a/infra/modules/providers/azure/postgreSQL_flexible/main.tf b/infra/modules/providers/azure/postgreSQL_flexible/main.tf index aff5f1df5686906f606dd6cb092b3549be1b29ed..7601baf55ff6ec5e52aa923867389d8dc102f01a 100644 --- a/infra/modules/providers/azure/postgreSQL_flexible/main.tf +++ b/infra/modules/providers/azure/postgreSQL_flexible/main.tf @@ -12,6 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + +provider "azurerm" { + features {} +} data "azurerm_resource_group" "main" { name = var.resource_group_name diff --git a/infra/modules/providers/azure/redis-cache/main.tf b/infra/modules/providers/azure/redis-cache/main.tf index b9233ebc71d563c764a828a9dba95d6ec616bb79..e5ec73781c044366377a8ab11997fc2f91ebe3d0 100644 --- a/infra/modules/providers/azure/redis-cache/main.tf +++ b/infra/modules/providers/azure/redis-cache/main.tf @@ -12,6 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<=3.116.0" + } + } +} + data "azurerm_resource_group" "arc" { name = var.resource_group_name } diff --git a/infra/modules/providers/azure/resource-group/main.tf b/infra/modules/providers/azure/resource-group/main.tf index dd664bfc29527a73151c346ef9e211f6257daf53..316bf026b4c3a500f180b19ce237d35c6c504f33 100644 --- a/infra/modules/providers/azure/resource-group/main.tf +++ b/infra/modules/providers/azure/resource-group/main.tf @@ -16,7 +16,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.90.0, <=4.17.0" + version = "<=4.17.0" } } } diff --git a/infra/modules/providers/azure/resource-group/testing/main.tf b/infra/modules/providers/azure/resource-group/testing/main.tf index ad2163dc4506f260d0b98bf2dac1bb339bde464b..550b2bbc7070a6d246f0c7de159419ebfb070f72 100644 --- a/infra/modules/providers/azure/resource-group/testing/main.tf +++ b/infra/modules/providers/azure/resource-group/testing/main.tf @@ -12,15 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -terraform { - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "=3.90.0" - } - } -} - provider "azurerm" { features {} } diff --git a/infra/modules/providers/azure/service-bus/main.tf b/infra/modules/providers/azure/service-bus/main.tf index 353619d28474367e1c34e7ba0883ff0fd3f1adc1..282552da1865bd1967644bc3689bc1728cf3cd21 100644 --- a/infra/modules/providers/azure/service-bus/main.tf +++ b/infra/modules/providers/azure/service-bus/main.tf @@ -16,11 +16,15 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = "=3.90.0" + version = "<=3.116.0" } } } +provider "azurerm" { + features {} +} + locals { authorization_rules = [ for rule in var.authorization_rules : merge({ diff --git a/infra/modules/providers/azure/storage-account/main.tf b/infra/modules/providers/azure/storage-account/main.tf index 81583f4b51fa627f3325a7528d01df5502f3e694..6f65c8c7cf8145746c91bd6a8dbcbdf93ebdd23f 100644 --- a/infra/modules/providers/azure/storage-account/main.tf +++ b/infra/modules/providers/azure/storage-account/main.tf @@ -17,7 +17,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = "=3.90.0" + version = "<=3.116.0" } } } diff --git a/infra/modules/providers/azure/test-functions.sh b/infra/modules/providers/azure/test-functions.sh index 544592d7335a5fddbabbcad09c5d56b7932ce380..aaef55578be25cb6d40362a1d4024402e281bf3b 100644 --- a/infra/modules/providers/azure/test-functions.sh +++ b/infra/modules/providers/azure/test-functions.sh @@ -79,7 +79,7 @@ generate_unique_name() { unique=$(openssl rand -hex 4 | tr '[:upper:]' '[:lower:]') else # Fallback to built-in $RANDOM if openssl is not available - unique=$(printf "%08x" $((RANDOM + RANDOM + RANDOM + RANDOM))) + unique=$(printf "%08x" $((RANDOM + RANDOM + RANDOM + RANDOM)) | tr '[:upper:]' '[:lower:]') fi [[ -n "$prefix" ]] && echo "${prefix}-${unique}${suffix}" || echo "tftest${unique}${suffix}"