From 9dd670db699edcba0d4930b957ed8a45905692f2 Mon Sep 17 00:00:00 2001 From: sweanan Date: Tue, 13 Jun 2023 14:35:20 -0500 Subject: [PATCH 01/16] initial draft --- .../README.md | 0 .../main.tf | 108 ++++++++++++++++++ .../outputs.tf | 19 +++ .../variables.tf | 61 ++++++++++ modules/azure/client_factory.go | 30 +++++ modules/azure/sql_managedinstance.go | 36 ++++++ modules/azure/sql_managedinstance_test.go | 28 +++++ ...m_azure_sqlmanagedinstance_example_test.go | 61 ++++++++++ 8 files changed, 343 insertions(+) create mode 100644 examples/azure/terraform-azure-sqlmanagedinstance-example/README.md create mode 100644 examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf create mode 100644 examples/azure/terraform-azure-sqlmanagedinstance-example/outputs.tf create mode 100644 examples/azure/terraform-azure-sqlmanagedinstance-example/variables.tf create mode 100644 modules/azure/sql_managedinstance.go create mode 100644 modules/azure/sql_managedinstance_test.go create mode 100644 test/azure/terraform_azure_sqlmanagedinstance_example_test.go diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf b/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf new file mode 100644 index 000000000..0ea0fc56e --- /dev/null +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf @@ -0,0 +1,108 @@ +# --------------------------------------------------------------------------------------------------------------------- +# DEPLOY AN AZURE SQL Managed Instance +# This is an example of how to deploy an AZURE SQL Managed Instance +# See test/terraform_azure_example_test.go for how to write automated tests for this code. +# --------------------------------------------------------------------------------------------------------------------- + + +# --------------------------------------------------------------------------------------------------------------------- +# CONFIGURE OUR AZURE CONNECTION +# --------------------------------------------------------------------------------------------------------------------- + +provider "azurerm" { + version = "~>2.93.0" + features {} +} + +# --------------------------------------------------------------------------------------------------------------------- +# CREATE RANDOM PASSWORD +# --------------------------------------------------------------------------------------------------------------------- + +# Random password is used as an example to simplify the deployment and improve the security of the database. +# This is not as a production recommendation as the password is stored in the Terraform state file. +resource "random_password" "password" { + length = 16 + override_special = "-_%@" + min_upper = "1" + min_lower = "1" + min_numeric = "1" + min_special = "1" +} + +# --------------------------------------------------------------------------------------------------------------------- +# DEPLOY A RESOURCE GROUP +# --------------------------------------------------------------------------------------------------------------------- + +resource "azurerm_resource_group" "sqlmi_rg" { + name = "terratest-sqlmi-${var.postfix}" + location = var.location +} + +# --------------------------------------------------------------------------------------------------------------------- +# DEPLOY NETWORK RESOURCES +# This network includes a public address for integration test demonstration purposes +# --------------------------------------------------------------------------------------------------------------------- + +resource "azurerm_network_security_group" "sqlmi_nt_sec_grp" { + name = "securitygroup-${var.postfix}" + location = azurerm_resource_group.sqlmi_rg.location + resource_group_name = azurerm_resource_group.sqlmi_rg.name +} + +resource "azurerm_network_security_rule" "allow_misubnet_inbound" { + name = "allow_subnet_${var.postfix}" + priority = 200 + direction = "Inbound" + access = "Allow" + protocol = "*" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "10.0.0.0/24" + destination_address_prefix = "*" + resource_group_name = azurerm_resource_group.sqlmi_rg.name + network_security_group_name = azurerm_network_security_group.sqlmi_nt_sec_grp.name +} + +resource "azurerm_virtual_network" "sqlmi_vm" { + name = "vnet-${var.postfix}" + resource_group_name = azurerm_resource_group.sqlmi_rg.name + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.sqlmi_rg.location +} + +resource "azurerm_subnet" "sqlmi_sub" { + name = "subnet-${var.postfix}" + resource_group_name = azurerm_resource_group.sqlmi_rg.name + virtual_network_name = azurerm_virtual_network.sqlmi_vm.name + address_prefixes = ["10.0.0.0/24"] + + delegation { + name = "managedinstancedelegation" + + service_delegation { + name = "Microsoft.Sql/managedInstances" + actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action", "Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action"] + } + } +} + +resource "azurerm_subnet_network_security_group_association" "sqlmi_sb_assoc" { + subnet_id = azurerm_subnet.sqlmi_sub.id + network_security_group_id = azurerm_network_security_group.sqlmi_nt_sec_grp.id +} + +## DEPLOY managed sql instance ## This depends on vnet ## +# resource "azurerm_mssql_managed_instance" "sqlmi_mi" { +# name = "sqlmi${var.postfix}" +# resource_group_name = azurerm_resource_group.sqlmi_rg.name +# location = azurerm_resource_group.sqlmi_rg.location +# +# license_type = var.sqlmi_license_type +# sku_name = var.sku_name +# storage_size_in_gb = var.storage_size +# subnet_id = azurerm_subnet.sqlmi_sub.id +# vcores = var.cores +# +# administrator_login = var.admin_login +# administrator_login_password = var.admin_login_password +#} \ No newline at end of file diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/outputs.tf b/examples/azure/terraform-azure-sqlmanagedinstance-example/outputs.tf new file mode 100644 index 000000000..9410173dd --- /dev/null +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/outputs.tf @@ -0,0 +1,19 @@ +output "resource_group_name" { + value = azurerm_resource_group.sqlmi_rg.name +} + +output "network_security_group_name" { + value = azurerm_network_security_group.sqlmi_nt_sec_grp.name +} + +output "virtual_network_name" { + value = azurerm_virtual_network.sqlmi_vm.name +} + +output "subnet_name" { + value = azurerm_subnet.sqlmi_sub.name +} + +#output "managed_instance_name" { +# value = azurerm_mssql_managed_instance.sqlmi_mi.name +#} diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/variables.tf b/examples/azure/terraform-azure-sqlmanagedinstance-example/variables.tf new file mode 100644 index 000000000..1ce3173b1 --- /dev/null +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/variables.tf @@ -0,0 +1,61 @@ +# --------------------------------------------------------------------------------------------------------------------- +# ENVIRONMENT VARIABLES +# Define these secrets as environment variables +# --------------------------------------------------------------------------------------------------------------------- + +# ARM_CLIENT_ID +# ARM_CLIENT_SECRET +# ARM_SUBSCRIPTION_ID +# ARM_TENANT_ID + +# --------------------------------------------------------------------------------------------------------------------- +# REQUIRED PARAMETERS +# You must provide a value for each of these parameters. +# --------------------------------------------------------------------------------------------------------------------- + +# --------------------------------------------------------------------------------------------------------------------- +# OPTIONAL PARAMETERS +# These parameters have reasonable defaults. +# --------------------------------------------------------------------------------------------------------------------- + +variable "location" { + description = "The supported azure location where the resource exists" + type = string + default = "usgovvirginia" +} + +#variable "sqlmi_license_type" { + # description = "The license type for the sql managed instance" +# type = string + # default = "BasePrice" +#} + +#variable "sku_name" { + # description = "The sku name for the sql managed instance" + # type = string + # default = "GP_Gen5" +#} + +#variable "storage_size" { + # description = "The storage for the sql managed instance" + # type = string + # default = 32 +#} + +#variable "cores" { +# description = "The vcores for the sql managed instance" + # type = string +# default = 4 +#} + +#variable "admin_login" { +# description = "The login for the sql managed instance" +# type = string +# default = "sqlmiadmin" +#} + +variable "postfix" { + description = "A postfix string to centrally mitigate resource name collisions." + type = string + default = "resource" +} \ No newline at end of file diff --git a/modules/azure/client_factory.go b/modules/azure/client_factory.go index 383ff8980..41af7b7e1 100644 --- a/modules/azure/client_factory.go +++ b/modules/azure/client_factory.go @@ -26,6 +26,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2019-11-01/containerservice" kvmng "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2016-10-01/keyvault" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-09-01/network" + sqlmi "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/v3.0/sql" "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-06-01/subscriptions" "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-06-01/storage" "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2019-08-01/web" @@ -319,6 +320,35 @@ func CreateSQLServerClient(subscriptionID string) (*sql.ServersClient, error) { return &sqlClient, nil } +// // CreateSQLServerClient is a helper function that will create and setup a sql server client +func CreateSQLMangedInstanceClient(subscriptionID string) (*sqlmi.ManagedInstancesClient, error) { + // Validate Azure subscription ID + subscriptionID, err := getTargetAzureSubscription(subscriptionID) + if err != nil { + return nil, err + } + + // Lookup environment URI + baseURI, err := getBaseURI() + if err != nil { + return nil, err + } + + // Create a sql server client + sqlmiClient := sqlmi.NewManagedInstancesClientWithBaseURI(baseURI, subscriptionID) + + // Create an authorizer + authorizer, err := NewAuthorizer() + if err != nil { + return nil, err + } + + // Attach authorizer to the client + sqlmiClient.Authorizer = *authorizer + + return &sqlmiClient, nil +} + // CreateDatabaseClient is a helper function that will create and setup a SQL DB client func CreateDatabaseClient(subscriptionID string) (*sql.DatabasesClient, error) { // Validate Azure subscription ID diff --git a/modules/azure/sql_managedinstance.go b/modules/azure/sql_managedinstance.go new file mode 100644 index 000000000..abc9044a1 --- /dev/null +++ b/modules/azure/sql_managedinstance.go @@ -0,0 +1,36 @@ +package azure + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/v3.0/sql" + "github.com/gruntwork-io/terratest/modules/testing" + "github.com/stretchr/testify/require" +) + +// GetSQLServer is a helper function that gets the sql server object. +// This function would fail the test if there is an error. +func GetManagedInstance(t testing.TestingT, resGroupName string, managedInstanceName string, subscriptionID string) *sql.ManagedInstance { + managedInstance, err := GetManagedInstanceE(t, subscriptionID, resGroupName, managedInstanceName) + require.NoError(t, err) + + return managedInstance +} + +// GetSQLServerE is a helper function that gets the sql server object. +func GetManagedInstanceE(t testing.TestingT, subscriptionID string, resGroupName string, managedInstanceName string) (*sql.ManagedInstance, error) { + // Create a SQl Server client + sqlmiClient, err := CreateSQLMangedInstanceClient(subscriptionID) + if err != nil { + return nil, err + } + + //Get the corresponding server client + sqlmiClient, err := sqlmiClient.Get(context.Background(), resGroupName, managedInstanceName) + if err != nil { + return nil, err + } + + //Return sql mi + return &sqlmiClient, nil +} diff --git a/modules/azure/sql_managedinstance_test.go b/modules/azure/sql_managedinstance_test.go new file mode 100644 index 000000000..1a86f7609 --- /dev/null +++ b/modules/azure/sql_managedinstance_test.go @@ -0,0 +1,28 @@ +//go:build azure +// +build azure + +// NOTE: We use build tags to differentiate azure testing because we currently do not have azure access setup for +// CircleCI. +package azure + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +/* +The below tests are currently stubbed out, with the expectation that they will throw errors. +If/when CRUD methods are introduced for Azure SQL DB, these tests can be extended +*/ + +func TestGetManagedInstanceE(t *testing.T) { + t.Parallel() + + resGroupName := "" + managedInstanceName := "" + subscriptionID := "" + + _, err := GetManagedInstanceE(t, resGroupName, managedInstanceName, subscriptionID) + require.Error(t, err) +} diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go new file mode 100644 index 000000000..78f820d38 --- /dev/null +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -0,0 +1,61 @@ +package test + +import ( + "strings" + "testing" + + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/terraform" + // "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/v3.0/sql" + // "github.com/gruntwork-io/terratest/modules/azure" + // "github.com/gruntwork-io/terratest/modules/random" + // "github.com/gruntwork-io/terratest/modules/terraform" + // "github.com/stretchr/testify/assert" +) + +func TestTerraformAzureSQLManagedInstanceExample(t *testing.T) { + t.Parallel() + + uniquePostfix := strings.ToLower(random.UniqueId()) + expectedLocation := "usgovvirginia" + + // website::tag::1:: Configure Terraform setting up a path to Terraform code. + terraformOptions := &terraform.Options{ + // The path to where our Terraform code is located + TerraformDir: "../../examples/azure/terraform-azure-sqlmanagedinstance-example", + Vars: map[string]interface{}{ + "postfix": uniquePostfix, + "location": expectedLocation, + }, + } + + // website::tag::4:: At the end of the test, run `terraform destroy` to clean up any resources that were created + // defer terraform.Destroy(t, terraformOptions) + + // website::tag::2:: Run `terraform init` and `terraform apply`. Fail the test if there are any errors. + terraform.InitAndApply(t, terraformOptions) + + // website::tag::3:: Run `terraform output` to get the values of output variables + // expectedSQLServerID := terraform.Output(t, terraformOptions, "sql_server_id") + // expectedSQLServerName := terraform.Output(t, terraformOptions, "sql_server_name") + + // expectedSQLServerFullDomainName := terraform.Output(t, terraformOptions, "sql_server_full_domain_name") + // expectedSQLDBName := terraform.Output(t, terraformOptions, "sql_database_name") + + // expectedSQLDBID := terraform.Output(t, terraformOptions, "sql_database_id") + // expectedResourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") + // expectedSQLDBStatus := "Online" + + // // website::tag::4:: Get the SQL server details and assert them against the terraform output + // actualSQLServer := azure.GetSQLServer(t, expectedResourceGroupName, expectedSQLServerName, "") + + // assert.Equal(t, expectedSQLServerID, *actualSQLServer.ID) + // assert.Equal(t, expectedSQLServerFullDomainName, *actualSQLServer.FullyQualifiedDomainName) + // assert.Equal(t, sql.ServerStateReady, actualSQLServer.State) + + // // website::tag::5:: Get the SQL server DB details and assert them against the terraform output + // actualSQLDatabase := azure.GetSQLDatabase(t, expectedResourceGroupName, expectedSQLServerName, expectedSQLDBName, "") + + // assert.Equal(t, expectedSQLDBID, *actualSQLDatabase.ID) + // assert.Equal(t, expectedSQLDBStatus, *actualSQLDatabase.Status) +} From c251303d2e9a5e9422351ff1c25c8b3508f652cf Mon Sep 17 00:00:00 2001 From: sweanan Date: Wed, 14 Jun 2023 09:02:02 -0500 Subject: [PATCH 02/16] update sqlmi code after complete testing --- .../README.md | 32 +++++++++ .../main.tf | 52 +++++++++----- .../outputs.tf | 10 ++- .../variables.tf | 67 ++++++++++--------- modules/azure/client_factory.go | 31 ++++++++- modules/azure/sql_managedinstance.go | 35 ++++++++-- modules/azure/sql_managedinstance_test.go | 14 +++- ...m_azure_sqlmanagedinstance_example_test.go | 62 ++++++++--------- 8 files changed, 217 insertions(+), 86 deletions(-) diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md index e69de29bb..679d5bbb6 100644 --- a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md @@ -0,0 +1,32 @@ +# Terraform Azure SQL DB Example + +This folder contains a Terraform module that deploys resources in [Azure](https://azure.microsoft.com/) to demonstrate how you can use Terratest to write automated tests for your Azure Terraform code. This module deploys a SQL Managed Instance, and a SQL Managed Instance database. + +- A [SQL Managed Instance](https://azure.microsoft.com/en-us/products/azure-sql/managed-instance/). +- A SQL Managed Database. + +Check out [test/azure/terraform_azure_sqlmanagedinstance_example_test.go](./../../../test/azure/terraform_azure_sqlmanagedinstance_example_test.go) to see how you can write automated tests for this module and validate the configuration of the parameters and options. + +**WARNING**: This module and the automated tests for it deploy real resources into your Azure account which can cost you money. The resources are all part of the [Azure Free Account](https://azure.microsoft.com/en-us/free/), so if you haven't used that up, +it should be free, but you are completely responsible for all Azure charges. + +## Running this module manually +1. Sign up for [Azure](https://azure.microsoft.com/). +1. Configure your Azure credentials using one of the [supported methods for Azure CLI + tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest) +1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH`. +1. Ensure [environment variables](../README.md#review-environment-variables) are available +1. Run `terraform init` +1. Run `terraform apply` +1. When you're done, run `terraform destroy`. + + +## Running automated tests against this module +1. Sign up for [Azure](https://azure.microsoft.com/) +1. Configure your Azure credentials using one of the [supported methods for Azure CLI + tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest) +1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH` +1. Configure your Terratest [Go test environment](../README.md) +1. `cd test/azure` +1. `go build terraform_azure_sqlmanagedinstance_example_test.go` +1. `go test -v -run TestTerraformAzureSQLManagedInstanceExample` diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf b/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf index 0ea0fc56e..ed1ba5cb5 100644 --- a/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf @@ -10,7 +10,7 @@ # --------------------------------------------------------------------------------------------------------------------- provider "azurerm" { - version = "~>2.93.0" + version = "~>3.13.0" features {} } @@ -91,18 +91,38 @@ resource "azurerm_subnet_network_security_group_association" "sqlmi_sb_assoc" { network_security_group_id = azurerm_network_security_group.sqlmi_nt_sec_grp.id } -## DEPLOY managed sql instance ## This depends on vnet ## -# resource "azurerm_mssql_managed_instance" "sqlmi_mi" { -# name = "sqlmi${var.postfix}" -# resource_group_name = azurerm_resource_group.sqlmi_rg.name -# location = azurerm_resource_group.sqlmi_rg.location -# -# license_type = var.sqlmi_license_type -# sku_name = var.sku_name -# storage_size_in_gb = var.storage_size -# subnet_id = azurerm_subnet.sqlmi_sub.id -# vcores = var.cores -# -# administrator_login = var.admin_login -# administrator_login_password = var.admin_login_password -#} \ No newline at end of file +resource "azurerm_route_table" "sqlmi_rt" { + name = "routetable-${var.postfix}" + location = azurerm_resource_group.sqlmi_rg.location + resource_group_name = azurerm_resource_group.sqlmi_rg.name + disable_bgp_route_propagation = false + depends_on = [ + azurerm_subnet.sqlmi_sub, + ] +} + +resource "azurerm_subnet_route_table_association" "sqlmi_sb_rt_assoc" { + subnet_id = azurerm_subnet.sqlmi_sub.id + route_table_id = azurerm_route_table.sqlmi_rt.id +} + +# DEPLOY managed sql instance ## This depends on vnet ## + resource "azurerm_mssql_managed_instance" "sqlmi_mi" { + name = "sqlmi${var.postfix}" + resource_group_name = azurerm_resource_group.sqlmi_rg.name + location = azurerm_resource_group.sqlmi_rg.location + + license_type = var.sqlmi_license_type + sku_name = var.sku_name + storage_size_in_gb = var.storage_size + subnet_id = azurerm_subnet.sqlmi_sub.id + vcores = var.cores + + administrator_login = var.admin_login + administrator_login_password = "thisIsDog11" +} + +resource "azurerm_mssql_managed_database" "sqlmi_db" { + name = var.sqlmi_db_name + managed_instance_id = azurerm_mssql_managed_instance.sqlmi_mi.id +} \ No newline at end of file diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/outputs.tf b/examples/azure/terraform-azure-sqlmanagedinstance-example/outputs.tf index 9410173dd..5cade5cd7 100644 --- a/examples/azure/terraform-azure-sqlmanagedinstance-example/outputs.tf +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/outputs.tf @@ -14,6 +14,10 @@ output "subnet_name" { value = azurerm_subnet.sqlmi_sub.name } -#output "managed_instance_name" { -# value = azurerm_mssql_managed_instance.sqlmi_mi.name -#} +output "managed_instance_name" { + value = azurerm_mssql_managed_instance.sqlmi_mi.name +} + +output "managed_instance_db_name" { + value = azurerm_mssql_managed_database.sqlmi_db.name +} \ No newline at end of file diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/variables.tf b/examples/azure/terraform-azure-sqlmanagedinstance-example/variables.tf index 1ce3173b1..41411dd3b 100644 --- a/examples/azure/terraform-azure-sqlmanagedinstance-example/variables.tf +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/variables.tf @@ -21,38 +21,45 @@ variable "location" { description = "The supported azure location where the resource exists" type = string - default = "usgovvirginia" + default = "West US2" } -#variable "sqlmi_license_type" { - # description = "The license type for the sql managed instance" -# type = string - # default = "BasePrice" -#} - -#variable "sku_name" { - # description = "The sku name for the sql managed instance" - # type = string - # default = "GP_Gen5" -#} - -#variable "storage_size" { - # description = "The storage for the sql managed instance" - # type = string - # default = 32 -#} - -#variable "cores" { -# description = "The vcores for the sql managed instance" - # type = string -# default = 4 -#} - -#variable "admin_login" { -# description = "The login for the sql managed instance" -# type = string -# default = "sqlmiadmin" -#} +variable "sqlmi_license_type" { + description = "The license type for the sql managed instance" + type = string + default = "BasePrice" +} + +variable "sku_name" { + description = "The sku name for the sql managed instance" + type = string + default = "GP_Gen5" +} + +variable "storage_size" { + description = "The storage for the sql managed instance" + type = string + default = 32 +} + +variable "cores" { + description = "The vcores for the sql managed instance" + type = string + default = 4 +} + +variable "admin_login" { + description = "The login for the sql managed instance" + type = string + default = "sqlmiadmin" +} + + +variable "sqlmi_db_name" { + description = "The Database for the sql managed instance" + type = string + default = "testdb" +} variable "postfix" { description = "A postfix string to centrally mitigate resource name collisions." diff --git a/modules/azure/client_factory.go b/modules/azure/client_factory.go index 41af7b7e1..6d662c4ce 100644 --- a/modules/azure/client_factory.go +++ b/modules/azure/client_factory.go @@ -320,7 +320,7 @@ func CreateSQLServerClient(subscriptionID string) (*sql.ServersClient, error) { return &sqlClient, nil } -// // CreateSQLServerClient is a helper function that will create and setup a sql server client +// CreateSQLMangedInstanceClient is a helper function that will create and setup a sql server client func CreateSQLMangedInstanceClient(subscriptionID string) (*sqlmi.ManagedInstancesClient, error) { // Validate Azure subscription ID subscriptionID, err := getTargetAzureSubscription(subscriptionID) @@ -349,6 +349,35 @@ func CreateSQLMangedInstanceClient(subscriptionID string) (*sqlmi.ManagedInstanc return &sqlmiClient, nil } +// CreateSQLMangedDatabasesClient is a helper function that will create and setup a sql server client +func CreateSQLMangedDatabasesClient(subscriptionID string) (*sqlmi.ManagedDatabasesClient, error) { + // Validate Azure subscription ID + subscriptionID, err := getTargetAzureSubscription(subscriptionID) + if err != nil { + return nil, err + } + + // Lookup environment URI + baseURI, err := getBaseURI() + if err != nil { + return nil, err + } + + // Create a sql server client + sqlmidbClient := sqlmi.NewManagedDatabasesClientWithBaseURI(baseURI, subscriptionID) + + // Create an authorizer + authorizer, err := NewAuthorizer() + if err != nil { + return nil, err + } + + // Attach authorizer to the client + sqlmidbClient.Authorizer = *authorizer + + return &sqlmidbClient, nil +} + // CreateDatabaseClient is a helper function that will create and setup a SQL DB client func CreateDatabaseClient(subscriptionID string) (*sql.DatabasesClient, error) { // Validate Azure subscription ID diff --git a/modules/azure/sql_managedinstance.go b/modules/azure/sql_managedinstance.go index abc9044a1..1804eca9a 100644 --- a/modules/azure/sql_managedinstance.go +++ b/modules/azure/sql_managedinstance.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -// GetSQLServer is a helper function that gets the sql server object. +// GetManagedInstance is a helper function that gets the sql server object. // This function would fail the test if there is an error. func GetManagedInstance(t testing.TestingT, resGroupName string, managedInstanceName string, subscriptionID string) *sql.ManagedInstance { managedInstance, err := GetManagedInstanceE(t, subscriptionID, resGroupName, managedInstanceName) @@ -17,7 +17,16 @@ func GetManagedInstance(t testing.TestingT, resGroupName string, managedInstance return managedInstance } -// GetSQLServerE is a helper function that gets the sql server object. +// GetSQLServer is a helper function that gets the sql server object. +// This function would fail the test if there is an error. +func GetManagedInstanceDatabase(t testing.TestingT, resGroupName string, managedInstanceName string, databaseName string, subscriptionID string) *sql.ManagedDatabase { + managedDatabase, err := GetManagedInstanceDatabaseE(t, subscriptionID, resGroupName, managedInstanceName, databaseName) + require.NoError(t, err) + + return managedDatabase +} + +// GetManagedInstanceE is a helper function that gets the sql server object. func GetManagedInstanceE(t testing.TestingT, subscriptionID string, resGroupName string, managedInstanceName string) (*sql.ManagedInstance, error) { // Create a SQl Server client sqlmiClient, err := CreateSQLMangedInstanceClient(subscriptionID) @@ -26,11 +35,29 @@ func GetManagedInstanceE(t testing.TestingT, subscriptionID string, resGroupName } //Get the corresponding server client - sqlmiClient, err := sqlmiClient.Get(context.Background(), resGroupName, managedInstanceName) + sqlmi, err := sqlmiClient.Get(context.Background(), resGroupName, managedInstanceName) if err != nil { return nil, err } //Return sql mi - return &sqlmiClient, nil + return &sqlmi, nil +} + +// GetManagedInstanceDatabaseE is a helper function that gets the sql server object. +func GetManagedInstanceDatabaseE(t testing.TestingT, subscriptionID string, resGroupName string, managedInstanceName string, databaseName string) (*sql.ManagedDatabase, error) { + // Create a SQlMI db client + sqlmiDbClient, err := CreateSQLMangedDatabasesClient(subscriptionID) + if err != nil { + return nil, err + } + + //Get the corresponding client + sqlmidb, err := sqlmiDbClient.Get(context.Background(), resGroupName, managedInstanceName, databaseName) + if err != nil { + return nil, err + } + + //Return sql mi db + return &sqlmidb, nil } diff --git a/modules/azure/sql_managedinstance_test.go b/modules/azure/sql_managedinstance_test.go index 1a86f7609..178afe0fc 100644 --- a/modules/azure/sql_managedinstance_test.go +++ b/modules/azure/sql_managedinstance_test.go @@ -23,6 +23,18 @@ func TestGetManagedInstanceE(t *testing.T) { managedInstanceName := "" subscriptionID := "" - _, err := GetManagedInstanceE(t, resGroupName, managedInstanceName, subscriptionID) + _, err := GetManagedInstanceE(t, subscriptionID, resGroupName, managedInstanceName) + require.Error(t, err) +} + +func TestGetManagedInstanceDatabasesE(t *testing.T) { + t.Parallel() + + resGroupName := "" + managedInstanceName := "" + databaseName := "" + subscriptionID := "" + + _, err := GetManagedInstanceDatabaseE(t, subscriptionID, resGroupName, managedInstanceName, databaseName) require.Error(t, err) } diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go index 78f820d38..b37c13612 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -1,61 +1,61 @@ +// Build tags are not added as SQL Managed Instance takes 6-8 hours for deploytment + package test import ( "strings" "testing" + "github.com/gruntwork-io/terratest/modules/azure" "github.com/gruntwork-io/terratest/modules/random" "github.com/gruntwork-io/terratest/modules/terraform" - // "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/v3.0/sql" - // "github.com/gruntwork-io/terratest/modules/azure" - // "github.com/gruntwork-io/terratest/modules/random" - // "github.com/gruntwork-io/terratest/modules/terraform" - // "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/assert" ) func TestTerraformAzureSQLManagedInstanceExample(t *testing.T) { t.Parallel() uniquePostfix := strings.ToLower(random.UniqueId()) - expectedLocation := "usgovvirginia" + expectedLocation := "West US2" + expectedAdminLogin := "sqlmiadmin" + expectedSQLMIState := "Ready" + expectedSKUName := "GP_Gen5" + expectedDatabaseName := "testdb" - // website::tag::1:: Configure Terraform setting up a path to Terraform code. + // Configure Terraform setting up a path to Terraform code. terraformOptions := &terraform.Options{ // The path to where our Terraform code is located TerraformDir: "../../examples/azure/terraform-azure-sqlmanagedinstance-example", Vars: map[string]interface{}{ - "postfix": uniquePostfix, - "location": expectedLocation, + "postfix": uniquePostfix, + "location": expectedLocation, + "admin_login": expectedAdminLogin, + "sku_name": expectedSKUName, + "sqlmi_db_name": expectedDatabaseName, }, } - // website::tag::4:: At the end of the test, run `terraform destroy` to clean up any resources that were created - // defer terraform.Destroy(t, terraformOptions) + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer terraform.Destroy(t, terraformOptions) - // website::tag::2:: Run `terraform init` and `terraform apply`. Fail the test if there are any errors. + // Run `terraform init` and `terraform apply`. Fail the test if there are any errors. terraform.InitAndApply(t, terraformOptions) - // website::tag::3:: Run `terraform output` to get the values of output variables - // expectedSQLServerID := terraform.Output(t, terraformOptions, "sql_server_id") - // expectedSQLServerName := terraform.Output(t, terraformOptions, "sql_server_name") - - // expectedSQLServerFullDomainName := terraform.Output(t, terraformOptions, "sql_server_full_domain_name") - // expectedSQLDBName := terraform.Output(t, terraformOptions, "sql_database_name") - - // expectedSQLDBID := terraform.Output(t, terraformOptions, "sql_database_id") - // expectedResourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") - // expectedSQLDBStatus := "Online" + // Run `terraform output` to get the values of output variables + expectedResourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") + expectedManagedInstanceName := terraform.Output(t, terraformOptions, "managed_instance_name") - // // website::tag::4:: Get the SQL server details and assert them against the terraform output - // actualSQLServer := azure.GetSQLServer(t, expectedResourceGroupName, expectedSQLServerName, "") + // Get the SQL Managed Instance details and assert them against the terraform output + actualSQLManagedInstance := azure.GetManagedInstance(t, expectedResourceGroupName, expectedManagedInstanceName, "") + actualSQLManagedInstanceDatabase := azure.GetManagedInstanceDatabase(t, expectedResourceGroupName, expectedManagedInstanceName, expectedDatabaseName, "") + expectedDatabaseStatus := "Online" - // assert.Equal(t, expectedSQLServerID, *actualSQLServer.ID) - // assert.Equal(t, expectedSQLServerFullDomainName, *actualSQLServer.FullyQualifiedDomainName) - // assert.Equal(t, sql.ServerStateReady, actualSQLServer.State) + assert.Equal(t, expectedManagedInstanceName, *actualSQLManagedInstance.Name) + assert.Equal(t, expectedLocation, *actualSQLManagedInstance.Location) + assert.Equal(t, expectedSKUName, *actualSQLManagedInstance.Sku.Name) + assert.Equal(t, expectedSQLMIState, *actualSQLManagedInstance.ManagedInstanceProperties.State) - // // website::tag::5:: Get the SQL server DB details and assert them against the terraform output - // actualSQLDatabase := azure.GetSQLDatabase(t, expectedResourceGroupName, expectedSQLServerName, expectedSQLDBName, "") + assert.Equal(t, expectedDatabaseName, *actualSQLManagedInstanceDatabase.Name) + assert.Equal(t, expectedDatabaseStatus, actualSQLManagedInstanceDatabase.ManagedDatabaseProperties.Status) - // assert.Equal(t, expectedSQLDBID, *actualSQLDatabase.ID) - // assert.Equal(t, expectedSQLDBStatus, *actualSQLDatabase.Status) } From 5896a68f28535e31f2b6cd777a920868e5c68654 Mon Sep 17 00:00:00 2001 From: sweanan Date: Wed, 14 Jun 2023 12:40:55 -0500 Subject: [PATCH 03/16] added a note for duration --- .../terraform-azure-sqlmanagedinstance-example/README.md | 5 ++++- .../azure/terraform_azure_sqlmanagedinstance_example_test.go | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md index 679d5bbb6..7a4b4d569 100644 --- a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md @@ -22,6 +22,9 @@ it should be free, but you are completely responsible for all Azure charges. ## Running automated tests against this module + +**WARNING**: The deploymnet for this module usually takes more than 4-6 hours as stated in the [microsoft docs](https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/management-operations-overview?view=azuresql#duration), so please make sure to set the timeout accordingly in the below go test command. + 1. Sign up for [Azure](https://azure.microsoft.com/) 1. Configure your Azure credentials using one of the [supported methods for Azure CLI tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest) @@ -29,4 +32,4 @@ it should be free, but you are completely responsible for all Azure charges. 1. Configure your Terratest [Go test environment](../README.md) 1. `cd test/azure` 1. `go build terraform_azure_sqlmanagedinstance_example_test.go` -1. `go test -v -run TestTerraformAzureSQLManagedInstanceExample` +1. `go test -v -run TestTerraformAzureSQLManagedInstanceExample -timeout ` diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go index b37c13612..eea082422 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -1,4 +1,5 @@ -// Build tags are not added as SQL Managed Instance takes 6-8 hours for deploytment +// Build tags are not added as SQL Managed Instance takes 6-8 hours for deployment, Exclude this from the worflow +// Please refer to examples/azure/terraform-azure-sqlmanagedinstance-example/README.md for more details package test From 3aee5cccac4d903a7f42ffd9c81d641828ba6763 Mon Sep 17 00:00:00 2001 From: sweanan Date: Thu, 15 Jun 2023 13:29:21 -0500 Subject: [PATCH 04/16] update for fmt --- .../azure/terraform-azure-sqlmanagedinstance-example/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf b/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf index ed1ba5cb5..9e1b386b8 100644 --- a/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/main.tf @@ -107,7 +107,7 @@ resource "azurerm_subnet_route_table_association" "sqlmi_sb_rt_assoc" { } # DEPLOY managed sql instance ## This depends on vnet ## - resource "azurerm_mssql_managed_instance" "sqlmi_mi" { +resource "azurerm_mssql_managed_instance" "sqlmi_mi" { name = "sqlmi${var.postfix}" resource_group_name = azurerm_resource_group.sqlmi_rg.name location = azurerm_resource_group.sqlmi_rg.location From 6516905673ef52d5142ce2ab7adcffd8d3a81888 Mon Sep 17 00:00:00 2001 From: sweanan Date: Mon, 19 Jun 2023 17:21:02 -0500 Subject: [PATCH 05/16] update location as well as lint issue for ci --- .github/workflows/ci.yml | 2 +- test/azure/terraform_azure_sqlmanagedinstance_example_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 670798899..03813b91b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: ref: ${{ github.event.inputs.branch }} - name: install golangci-lint binary run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./bin v1.31.0 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./bin v1.53.2 - name: lint modules/azure folder id: azure_module_lint run: | diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go index eea082422..d516a71be 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -17,7 +17,7 @@ func TestTerraformAzureSQLManagedInstanceExample(t *testing.T) { t.Parallel() uniquePostfix := strings.ToLower(random.UniqueId()) - expectedLocation := "West US2" + expectedLocation := "westus" expectedAdminLogin := "sqlmiadmin" expectedSQLMIState := "Ready" expectedSKUName := "GP_Gen5" From 84219bd832e092b74dc0b0b5ba7629e6f9211ccd Mon Sep 17 00:00:00 2001 From: sweanan Date: Mon, 19 Jun 2023 17:28:48 -0500 Subject: [PATCH 06/16] update lint error --- modules/azure/region.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/azure/region.go b/modules/azure/region.go index e36733531..c478beeb2 100644 --- a/modules/azure/region.go +++ b/modules/azure/region.go @@ -4,7 +4,6 @@ import ( "context" "github.com/gruntwork-io/terratest/modules/collections" - "github.com/gruntwork-io/terratest/modules/logger" "github.com/gruntwork-io/terratest/modules/random" "github.com/gruntwork-io/terratest/modules/testing" ) @@ -115,7 +114,6 @@ func GetRandomRegionE(t testing.TestingT, approvedRegions []string, forbiddenReg regionsToPickFrom = collections.ListSubtract(regionsToPickFrom, forbiddenRegions) region := random.RandomString(regionsToPickFrom) - logger.Logf(t, "Using region %s", region) return region, nil } @@ -138,7 +136,6 @@ func GetAllAzureRegions(t testing.TestingT, subscriptionID string) []string { // GetAllAzureRegionsE gets the list of Azure regions available in this subscription func GetAllAzureRegionsE(t testing.TestingT, subscriptionID string) ([]string, error) { - logger.Log(t, "Looking up all Azure regions available in this account") // Validate Azure subscription ID subscriptionID, err := getTargetAzureSubscription(subscriptionID) From 283194c9479891aab5c6f911c552720ade54fba7 Mon Sep 17 00:00:00 2001 From: sweanan Date: Tue, 20 Jun 2023 09:42:11 -0500 Subject: [PATCH 07/16] renamed file to exclude from workflow --- ...o => terraform_azure_sqlmanagedinstance_example_testlong.go} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename test/azure/{terraform_azure_sqlmanagedinstance_example_test.go => terraform_azure_sqlmanagedinstance_example_testlong.go} (95%) diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go similarity index 95% rename from test/azure/terraform_azure_sqlmanagedinstance_example_test.go rename to test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go index d516a71be..ef9fe005a 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go @@ -1,4 +1,4 @@ -// Build tags are not added as SQL Managed Instance takes 6-8 hours for deployment, Exclude this from the worflow +// SQL Managed Instance takes 6-8 hours for deployment, Exclude this from the worflow by naming it as _testlong.go // Please refer to examples/azure/terraform-azure-sqlmanagedinstance-example/README.md for more details package test From b75dcd69585dbf48b7be545067a3e10eba9a5ad4 Mon Sep 17 00:00:00 2001 From: sweanan Date: Tue, 20 Jun 2023 11:23:32 -0500 Subject: [PATCH 08/16] revert back the ci changes --- .github/workflows/ci.yml | 2 +- modules/azure/region.go | 3 +++ .../terraform_azure_sqlmanagedinstance_example_testlong.go | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03813b91b..670798899 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: ref: ${{ github.event.inputs.branch }} - name: install golangci-lint binary run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./bin v1.53.2 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./bin v1.31.0 - name: lint modules/azure folder id: azure_module_lint run: | diff --git a/modules/azure/region.go b/modules/azure/region.go index c478beeb2..e36733531 100644 --- a/modules/azure/region.go +++ b/modules/azure/region.go @@ -4,6 +4,7 @@ import ( "context" "github.com/gruntwork-io/terratest/modules/collections" + "github.com/gruntwork-io/terratest/modules/logger" "github.com/gruntwork-io/terratest/modules/random" "github.com/gruntwork-io/terratest/modules/testing" ) @@ -114,6 +115,7 @@ func GetRandomRegionE(t testing.TestingT, approvedRegions []string, forbiddenReg regionsToPickFrom = collections.ListSubtract(regionsToPickFrom, forbiddenRegions) region := random.RandomString(regionsToPickFrom) + logger.Logf(t, "Using region %s", region) return region, nil } @@ -136,6 +138,7 @@ func GetAllAzureRegions(t testing.TestingT, subscriptionID string) []string { // GetAllAzureRegionsE gets the list of Azure regions available in this subscription func GetAllAzureRegionsE(t testing.TestingT, subscriptionID string) ([]string, error) { + logger.Log(t, "Looking up all Azure regions available in this account") // Validate Azure subscription ID subscriptionID, err := getTargetAzureSubscription(subscriptionID) diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go b/test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go index ef9fe005a..df1e1d501 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go @@ -1,4 +1,5 @@ -// SQL Managed Instance takes 6-8 hours for deployment, Exclude this from the worflow by naming it as _testlong.go +// SQL Managed Instance takes 6-8 hours for deployment, Exclude this from the worflow by naming it as *_testlong.go +// To include this as part of testing, rename the file to *_test.go // Please refer to examples/azure/terraform-azure-sqlmanagedinstance-example/README.md for more details package test From 02698fef8976d4244b872cca16b68712a53e1548 Mon Sep 17 00:00:00 2001 From: sweanan Date: Tue, 20 Jun 2023 11:30:30 -0500 Subject: [PATCH 09/16] update readme --- .../azure/terraform-azure-sqlmanagedinstance-example/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md index 7a4b4d569..3f79dd6c7 100644 --- a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md @@ -25,6 +25,8 @@ it should be free, but you are completely responsible for all Azure charges. **WARNING**: The deploymnet for this module usually takes more than 4-6 hours as stated in the [microsoft docs](https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/management-operations-overview?view=azuresql#duration), so please make sure to set the timeout accordingly in the below go test command. +**WARNING**: To exclude this long running test from the ci workflow, the test file is created as `terraform_azure_sqlmanagedinstance_example_testlong.go`. Rename it to `terraform_azure_sqlmanagedinstance_example_test.go` in order to run the test manually. + 1. Sign up for [Azure](https://azure.microsoft.com/) 1. Configure your Azure credentials using one of the [supported methods for Azure CLI tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest) From 5b658cad025758dac7d34de7ecb269738bb5b5a5 Mon Sep 17 00:00:00 2001 From: sweanan Date: Thu, 22 Jun 2023 06:44:38 -0500 Subject: [PATCH 10/16] rename the test file --- .github/workflows/ci.yml | 2 +- .../README.md | 14 ++++++-------- modules/azure/sql_managedinstance.go | 2 +- ...aform_azure_sqlmanagedinstance_example_test.go} | 3 +-- 4 files changed, 9 insertions(+), 12 deletions(-) rename test/azure/{terraform_azure_sqlmanagedinstance_example_testlong.go => terraform_azure_sqlmanagedinstance_example_test.go} (93%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03813b91b..d1bc732dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -131,7 +131,7 @@ jobs: export TF_VAR_client_secret="$APP_PASSWORD" # run the actual tests under the `azure` subfolder - go test ./azure/* -v -timeout 90m + go test ./azure/* --tags=azure -v -timeout 90m - name: report back the result if: always() env: diff --git a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md index 3f79dd6c7..b4f7fcedb 100644 --- a/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md +++ b/examples/azure/terraform-azure-sqlmanagedinstance-example/README.md @@ -25,13 +25,11 @@ it should be free, but you are completely responsible for all Azure charges. **WARNING**: The deploymnet for this module usually takes more than 4-6 hours as stated in the [microsoft docs](https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/management-operations-overview?view=azuresql#duration), so please make sure to set the timeout accordingly in the below go test command. -**WARNING**: To exclude this long running test from the ci workflow, the test file is created as `terraform_azure_sqlmanagedinstance_example_testlong.go`. Rename it to `terraform_azure_sqlmanagedinstance_example_test.go` in order to run the test manually. - 1. Sign up for [Azure](https://azure.microsoft.com/) -1. Configure your Azure credentials using one of the [supported methods for Azure CLI +2. Configure your Azure credentials using one of the [supported methods for Azure CLI tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest) -1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH` -1. Configure your Terratest [Go test environment](../README.md) -1. `cd test/azure` -1. `go build terraform_azure_sqlmanagedinstance_example_test.go` -1. `go test -v -run TestTerraformAzureSQLManagedInstanceExample -timeout ` +3. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH` +4. Configure your Terratest [Go test environment](../README.md) +5. `cd test/azure` +6. `go build terraform_azure_sqlmanagedinstance_example_test.go` +7. `go test -v -run TestTerraformAzureSQLManagedInstanceExample -timeout ` diff --git a/modules/azure/sql_managedinstance.go b/modules/azure/sql_managedinstance.go index 1804eca9a..303392449 100644 --- a/modules/azure/sql_managedinstance.go +++ b/modules/azure/sql_managedinstance.go @@ -17,7 +17,7 @@ func GetManagedInstance(t testing.TestingT, resGroupName string, managedInstance return managedInstance } -// GetSQLServer is a helper function that gets the sql server object. +// GetManagedInstanceDatabase is a helper function that gets the sql server object. // This function would fail the test if there is an error. func GetManagedInstanceDatabase(t testing.TestingT, resGroupName string, managedInstanceName string, databaseName string, subscriptionID string) *sql.ManagedDatabase { managedDatabase, err := GetManagedInstanceDatabaseE(t, subscriptionID, resGroupName, managedInstanceName, databaseName) diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go similarity index 93% rename from test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go rename to test/azure/terraform_azure_sqlmanagedinstance_example_test.go index df1e1d501..3559410d0 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_testlong.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -1,5 +1,4 @@ -// SQL Managed Instance takes 6-8 hours for deployment, Exclude this from the worflow by naming it as *_testlong.go -// To include this as part of testing, rename the file to *_test.go +// SQL Managed Instance takes 6-8 hours for deployment, Build tags are not added to exclude this file from CI workflow // Please refer to examples/azure/terraform-azure-sqlmanagedinstance-example/README.md for more details package test From 02987218f9a4415e04398468b1e0160e1d9736aa Mon Sep 17 00:00:00 2001 From: sweanan Date: Thu, 22 Jun 2023 16:07:15 -0500 Subject: [PATCH 11/16] update ci.yml --- .github/workflows/ci.yml | 4 ++-- .../azure/terraform_azure_sqlmanagedinstance_example_test.go | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1bc732dd..3733b6ad0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,7 +107,7 @@ jobs: env: AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} run: | - cd test + cd test/azure APP_ID=`echo $AZURE_CREDENTIALS | jq -r -c ".clientId"` APP_PASSWORD=`echo $AZURE_CREDENTIALS | jq -r -c ".clientSecret"` @@ -131,7 +131,7 @@ jobs: export TF_VAR_client_secret="$APP_PASSWORD" # run the actual tests under the `azure` subfolder - go test ./azure/* --tags=azure -v -timeout 90m + go test --tags=azure -v -timeout 90m - name: report back the result if: always() env: diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go index 3559410d0..063aac0a7 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -1,4 +1,7 @@ -// SQL Managed Instance takes 6-8 hours for deployment, Build tags are not added to exclude this file from CI workflow +//go:build !azure +// +build !azure + +// This test is tagged as !azure to prevent it from being executed from CI workflow, as SQL Managed Instance takes 6-8 hours for deployment // Please refer to examples/azure/terraform-azure-sqlmanagedinstance-example/README.md for more details package test From e158951e31a72ab0a29efee78fdaf560af7c3687 Mon Sep 17 00:00:00 2001 From: sweanan Date: Fri, 23 Jun 2023 07:41:38 -0500 Subject: [PATCH 12/16] added the exists helper function --- modules/azure/sql_managedinstance.go | 24 +++++++++++++++++-- modules/azure/sql_managedinstance_test.go | 13 ++++++++++ ...m_azure_sqlmanagedinstance_example_test.go | 6 +++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/modules/azure/sql_managedinstance.go b/modules/azure/sql_managedinstance.go index 303392449..43ea0f9fe 100644 --- a/modules/azure/sql_managedinstance.go +++ b/modules/azure/sql_managedinstance.go @@ -8,10 +8,30 @@ import ( "github.com/stretchr/testify/require" ) +// SQLManagedInstanceExists indicates whether the SQL Managed Instance exists for the subscription. +// This function would fail the test if there is an error. +func SQLManagedInstanceExists(t testing.TestingT, managedInstanceName string, resourceGroupName string, subscriptionID string) bool { + exists, err := SQLManagedInstanceExistsE(managedInstanceName, resourceGroupName, subscriptionID) + require.NoError(t, err) + return exists +} + +// SQLManagedInstanceExistsE indicates whether the specified SQL Managed Instance exists and may return an error. +func SQLManagedInstanceExistsE(managedInstanceName string, resourceGroupName string, subscriptionID string) (bool, error) { + _, err := GetManagedInstanceE(subscriptionID, resourceGroupName, managedInstanceName) + if err != nil { + if ResourceNotFoundErrorExists(err) { + return false, nil + } + return false, err + } + return true, nil +} + // GetManagedInstance is a helper function that gets the sql server object. // This function would fail the test if there is an error. func GetManagedInstance(t testing.TestingT, resGroupName string, managedInstanceName string, subscriptionID string) *sql.ManagedInstance { - managedInstance, err := GetManagedInstanceE(t, subscriptionID, resGroupName, managedInstanceName) + managedInstance, err := GetManagedInstanceE(subscriptionID, resGroupName, managedInstanceName) require.NoError(t, err) return managedInstance @@ -27,7 +47,7 @@ func GetManagedInstanceDatabase(t testing.TestingT, resGroupName string, managed } // GetManagedInstanceE is a helper function that gets the sql server object. -func GetManagedInstanceE(t testing.TestingT, subscriptionID string, resGroupName string, managedInstanceName string) (*sql.ManagedInstance, error) { +func GetManagedInstanceE(subscriptionID string, resGroupName string, managedInstanceName string) (*sql.ManagedInstance, error) { // Create a SQl Server client sqlmiClient, err := CreateSQLMangedInstanceClient(subscriptionID) if err != nil { diff --git a/modules/azure/sql_managedinstance_test.go b/modules/azure/sql_managedinstance_test.go index 178afe0fc..368f12069 100644 --- a/modules/azure/sql_managedinstance_test.go +++ b/modules/azure/sql_managedinstance_test.go @@ -16,6 +16,19 @@ The below tests are currently stubbed out, with the expectation that they will t If/when CRUD methods are introduced for Azure SQL DB, these tests can be extended */ +func TestSQLManagedInstanceExists(t *testing.T) { + t.Parallel() + + managedInstanceName := "" + resourceGroupName := "" + subscriptionID := "" + + exists, err := SQLManagedInstanceExistsE(managedInstanceName, resourceGroupName, subscriptionID) + + require.False(t, exists) + require.Error(t, err) +} + func TestGetManagedInstanceE(t *testing.T) { t.Parallel() diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go index 063aac0a7..13c0ecdf7 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -49,10 +49,13 @@ func TestTerraformAzureSQLManagedInstanceExample(t *testing.T) { expectedResourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") expectedManagedInstanceName := terraform.Output(t, terraformOptions, "managed_instance_name") + // check for if data factory exists + actualManagedInstanceExits := azure.SQLManagedInstanceExists(t, expectedManagedInstanceName, expectedResourceGroupName, "") + assert.True(t, actualManagedInstanceExits) + // Get the SQL Managed Instance details and assert them against the terraform output actualSQLManagedInstance := azure.GetManagedInstance(t, expectedResourceGroupName, expectedManagedInstanceName, "") actualSQLManagedInstanceDatabase := azure.GetManagedInstanceDatabase(t, expectedResourceGroupName, expectedManagedInstanceName, expectedDatabaseName, "") - expectedDatabaseStatus := "Online" assert.Equal(t, expectedManagedInstanceName, *actualSQLManagedInstance.Name) assert.Equal(t, expectedLocation, *actualSQLManagedInstance.Location) @@ -60,6 +63,5 @@ func TestTerraformAzureSQLManagedInstanceExample(t *testing.T) { assert.Equal(t, expectedSQLMIState, *actualSQLManagedInstance.ManagedInstanceProperties.State) assert.Equal(t, expectedDatabaseName, *actualSQLManagedInstanceDatabase.Name) - assert.Equal(t, expectedDatabaseStatus, actualSQLManagedInstanceDatabase.ManagedDatabaseProperties.Status) } From c4be13cf6572f286525a6716a5e3361d38df6269 Mon Sep 17 00:00:00 2001 From: sweanan Date: Fri, 23 Jun 2023 16:37:21 -0500 Subject: [PATCH 13/16] changed the api signature --- modules/azure/sql_managedinstance_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/azure/sql_managedinstance_test.go b/modules/azure/sql_managedinstance_test.go index 368f12069..f8a0f1cb8 100644 --- a/modules/azure/sql_managedinstance_test.go +++ b/modules/azure/sql_managedinstance_test.go @@ -36,7 +36,7 @@ func TestGetManagedInstanceE(t *testing.T) { managedInstanceName := "" subscriptionID := "" - _, err := GetManagedInstanceE(t, subscriptionID, resGroupName, managedInstanceName) + _, err := GetManagedInstanceE(subscriptionID, resGroupName, managedInstanceName) require.Error(t, err) } From 91c117a7efa2badfd0c10700bc363613c0274854 Mon Sep 17 00:00:00 2001 From: Hadwa Gaber Date: Wed, 5 Jul 2023 14:18:35 -0700 Subject: [PATCH 14/16] mark the test as long running test --- test/azure/terraform_azure_sqlmanagedinstance_example_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go index 13c0ecdf7..d2191991d 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -17,6 +17,9 @@ import ( ) func TestTerraformAzureSQLManagedInstanceExample(t *testing.T) { + if testing.Short(){ + t.Skip("Skipping long-running test") + } t.Parallel() uniquePostfix := strings.ToLower(random.UniqueId()) From 7d9d89d096dd0d7411a73643d85428b8f86fd8bf Mon Sep 17 00:00:00 2001 From: Hadwa Gaber Date: Wed, 5 Jul 2023 14:23:05 -0700 Subject: [PATCH 15/16] update the test tag --- test/azure/terraform_azure_sqlmanagedinstance_example_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go index d2191991d..d0ff1f4df 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -1,5 +1,5 @@ -//go:build !azure -// +build !azure +//go:build azure_ci_excluded +// +build azure_ci_excluded // This test is tagged as !azure to prevent it from being executed from CI workflow, as SQL Managed Instance takes 6-8 hours for deployment // Please refer to examples/azure/terraform-azure-sqlmanagedinstance-example/README.md for more details From 0fd2dfd27cf38ef2e1b04998b0ebf716710d8719 Mon Sep 17 00:00:00 2001 From: sweanan Date: Thu, 6 Jul 2023 15:24:41 -0500 Subject: [PATCH 16/16] fixed the imports --- test/azure/terraform_azure_sqlmanagedinstance_example_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go index d0ff1f4df..fb9146ad3 100644 --- a/test/azure/terraform_azure_sqlmanagedinstance_example_test.go +++ b/test/azure/terraform_azure_sqlmanagedinstance_example_test.go @@ -17,7 +17,7 @@ import ( ) func TestTerraformAzureSQLManagedInstanceExample(t *testing.T) { - if testing.Short(){ + if testing.Short() { t.Skip("Skipping long-running test") } t.Parallel()