From 0d0a04e67ffcff1b77ab07f4423a16b0dbf7e095 Mon Sep 17 00:00:00 2001 From: polatengin Date: Tue, 1 Sep 2020 16:14:35 +0000 Subject: [PATCH 1/7] adding Azure Container Instances module --- .../terraform-azure-aci-example/README.md | 78 +++++++++++++++++++ .../azure/terraform-azure-aci-example/main.tf | 55 +++++++++++++ .../terraform-azure-aci-example/output.tf | 11 +++ .../terraform-azure-aci-example/variables.tf | 31 ++++++++ modules/azure/aci.go | 46 +++++++++++ .../azure/terraform_azure_aci_example_test.go | 50 ++++++++++++ 6 files changed, 271 insertions(+) create mode 100644 examples/azure/terraform-azure-aci-example/README.md create mode 100644 examples/azure/terraform-azure-aci-example/main.tf create mode 100644 examples/azure/terraform-azure-aci-example/output.tf create mode 100644 examples/azure/terraform-azure-aci-example/variables.tf create mode 100644 modules/azure/aci.go create mode 100644 test/azure/terraform_azure_aci_example_test.go diff --git a/examples/azure/terraform-azure-aci-example/README.md b/examples/azure/terraform-azure-aci-example/README.md new file mode 100644 index 000000000..875d01cfd --- /dev/null +++ b/examples/azure/terraform-azure-aci-example/README.md @@ -0,0 +1,78 @@ +# Terraform Azure Example + +This folder contains a simple 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 an [Azure Container Instance](https://azure.microsoft.com/en-us/services/container-instances/). + +Check out [test/azure/terraform_azure_aci_example_test.go](/test/azure/terraform_azure_aci_example_test.go) to see how you can write +automated tests for this module. + +**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. 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. [Review environment variables](#review-environment-variables). +1. Install [Golang](https://golang.org/) and make sure this code is checked out into your `GOPATH`. +1. `cd test` +1. Make sure [the azure-sdk-for-go versions match](#check-go-dependencies) in [/test/go.mod](/test/go.mod) and in [test/azure/terraform_azure_aci_example_test.go](/test/azure/terraform_azure_aci_example_test.go). +1. `go build terraform_azure_aci_example_test.go` +1. `go test -v -run TestTerraformAzureACIExample` + +## Check Go Dependencies + +Check that the `github.com/Azure/azure-sdk-for-go` version in your generated `go.mod` for this test matches the version in the terratest [go.mod](https://github.com/gruntwork-io/terratest/blob/master/go.mod) file. + +> This was tested with **go1.14.1**. + +### Check Azure-sdk-for-go version + +Let's make sure [go.mod](https://github.com/gruntwork-io/terratest/blob/master/go.mod) includes the appropriate [azure-sdk-for-go version](https://github.com/Azure/azure-sdk-for-go/releases/tag/v38.1.0): + +```go +require ( + ... + github.com/Azure/azure-sdk-for-go v38.1.0+incompatible + ... +) +``` + +If we make changes to either the **go.mod** or the **go test file**, we should make sure that the go build command works still. + +```powershell +go build terraform_azure_aci_example_test.go +``` + +## Review Environment Variables + +As part of configuring terraform for Azure, we'll want to check that we have set the appropriate [credentials](https://docs.microsoft.com/en-us/azure/terraform/terraform-install-configure?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fterraform%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json#set-up-terraform-access-to-azure) and also that we set the [environment variables](https://docs.microsoft.com/en-us/azure/terraform/terraform-install-configure?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fterraform%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json#configure-terraform-environment-variables) on the testing host. + +```bash +export ARM_CLIENT_ID=your_app_id +export ARM_CLIENT_SECRET=your_password +export ARM_SUBSCRIPTION_ID=your_subscription_id +export ARM_TENANT_ID=your_tenant_id +``` + +Note, in a Windows environment, these should be set as **system environment variables**. We can use a PowerShell console with administrative rights to update these environment variables: + +```powershell +[System.Environment]::SetEnvironmentVariable("ARM_CLIENT_ID",$your_app_id,[System.EnvironmentVariableTarget]::Machine) +[System.Environment]::SetEnvironmentVariable("ARM_CLIENT_SECRET",$your_password,[System.EnvironmentVariableTarget]::Machine) +[System.Environment]::SetEnvironmentVariable("ARM_SUBSCRIPTION_ID",$your_subscription_id,[System.EnvironmentVariableTarget]::Machine) +[System.Environment]::SetEnvironmentVariable("ARM_TENANT_ID",$your_tenant_id,[System.EnvironmentVariableTarget]::Machine) +``` diff --git a/examples/azure/terraform-azure-aci-example/main.tf b/examples/azure/terraform-azure-aci-example/main.tf new file mode 100644 index 000000000..46b506559 --- /dev/null +++ b/examples/azure/terraform-azure-aci-example/main.tf @@ -0,0 +1,55 @@ +# --------------------------------------------------------------------------------------------------------------------- +# DEPLOY AN AZURE CONTAINER REGISTRY +# This is an example of how to deploy an Azure Container Registry +# --------------------------------------------------------------------------------------------------------------------- + +# ------------------------------------------------------------------------------ +# CONFIGURE OUR AZURE CONNECTION +# ------------------------------------------------------------------------------ + +provider "azurerm" { + version = "=2.22.0" + features {} +} + +# --------------------------------------------------------------------------------------------------------------------- +# DEPLOY A RESOURCE GROUP +# --------------------------------------------------------------------------------------------------------------------- + +resource "azurerm_resource_group" "rg" { + name = var.resource_group_name + location = var.location +} + +# --------------------------------------------------------------------------------------------------------------------- +# DEPLOY AN AZURE CONTAINER INSTANCE +# --------------------------------------------------------------------------------------------------------------------- + +data "azurerm_client_config" "current" { +} + +resource "azurerm_container_group" "aci" { + name = var.aci_name + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + ip_address_type = "public" + dns_name_label = var.aci_name + os_type = "Linux" + + container { + name = "hello-world" + image = "microsoft/aci-helloworld:latest" + cpu = "0.5" + memory = "1.5" + + ports { + port = 443 + protocol = "TCP" + } + } + + tags = { + Environment = "Development" + } +} diff --git a/examples/azure/terraform-azure-aci-example/output.tf b/examples/azure/terraform-azure-aci-example/output.tf new file mode 100644 index 000000000..962670bf9 --- /dev/null +++ b/examples/azure/terraform-azure-aci-example/output.tf @@ -0,0 +1,11 @@ +output "ip_address" { + value = azurerm_container_group.aci.ip_address +} + +output "fqdn" { + value = azurerm_container_group.aci.fqdn +} + +output "subscription_id" { + value = data.azurerm_client_config.current.subscription_id +} diff --git a/examples/azure/terraform-azure-aci-example/variables.tf b/examples/azure/terraform-azure-aci-example/variables.tf new file mode 100644 index 000000000..22370157d --- /dev/null +++ b/examples/azure/terraform-azure-aci-example/variables.tf @@ -0,0 +1,31 @@ +# --------------------------------------------------------------------------------------------------------------------- +# REQUIRED PARAMETERS +# You must provide a value for each of these parameters. +# --------------------------------------------------------------------------------------------------------------------- + +variable "client_id" { + description = "The Service Principal Client Id for AKS to modify Azure resources." +} +variable "client_secret" { + description = "The Service Principal Client Password for AKS to modify Azure resources." +} + +# --------------------------------------------------------------------------------------------------------------------- +# OPTIONAL PARAMETERS +# These parameters have reasonable defaults. +# --------------------------------------------------------------------------------------------------------------------- + +variable "aci_name" { + description = "The name to set for the ACI." + default = "acitest" +} + +variable "resource_group_name" { + description = "The name to set for the resource group." + default = "aci-rg" +} + +variable "location" { + description = "The location to set for the ACR." + default = "Central US" +} diff --git a/modules/azure/aci.go b/modules/azure/aci.go new file mode 100644 index 000000000..4a05f72fb --- /dev/null +++ b/modules/azure/aci.go @@ -0,0 +1,46 @@ +package azure + +import ( + "context" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" + + "github.com/stretchr/testify/require" +) + +// GetACIClient is a helper function that will setup an Azure Container Instances client on your behalf +// resourceName - required to find the Function App +// resGroupName - use an empty string if you have the AZURE_RES_GROUP_NAME environment variable set +// subscriptionId - use an empty string if you have the ARM_SUBSCRIPTION_ID environment variable set +func GetACIClient(t *testing.T, resourceName string, resGroupName string, subscriptionID string) *containerinstance.ContainerGroup { + resource, err := getACIClientE(resourceName, resGroupName, subscriptionID) + + require.NoError(t, err) + + return resource +} + +func getACIClientE(resourceName string, resGroupName string, subscriptionID string) (*containerinstance.ContainerGroup, error) { + // Validate Azure subscription ID + subscriptionID, err := getTargetAzureSubscription(subscriptionID) + if err != nil { + return nil, err + } + + managedServicesClient := containerinstance.NewContainerGroupsClient(subscriptionID) + authorizer, err := NewAuthorizer() + + if err != nil { + return nil, err + } + + managedServicesClient.Authorizer = *authorizer + + resource, err := managedServicesClient.Get(context.Background(), resGroupName, resourceName) + if err != nil { + return nil, err + } + + return &resource, nil +} diff --git a/test/azure/terraform_azure_aci_example_test.go b/test/azure/terraform_azure_aci_example_test.go new file mode 100644 index 000000000..d88933e09 --- /dev/null +++ b/test/azure/terraform_azure_aci_example_test.go @@ -0,0 +1,50 @@ +// +build azure + +// NOTE: We use build tags to differentiate azure testing because we currently do not have azure access setup for +// CircleCI. + +package test + +import ( + "fmt" + "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/stretchr/testify/assert" +) + +func TestTerraformAzureACIExample(t *testing.T) { + t.Parallel() + + _random := strings.ToLower(random.UniqueId()) + + expectedResourceName := fmt.Sprintf("tmpaci%s", _random) + expectedResourceGroupName := fmt.Sprintf("tmp-rg-%s", _random) + + terraformOptions := &terraform.Options{ + TerraformDir: "../../examples/terraform-azure-aci-example", + Vars: map[string]interface{}{ + "aci_name": expectedResourceName, + "resource_group_name": expectedResourceGroupName, + }, + } + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer terraform.Destroy(t, terraformOptions) + + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.InitAndApply(t, terraformOptions) + + client := azure.GetACIClient(t, expectedResourceName, expectedResourceGroupName, "") + + assert := assert.New(t) + + assert.NotEmpty(*client.Name) + + assert.NotEmpty(*client.IPAddress.Fqdn) + + assert.NotEmpty(*client.IPAddress.IP) +} From 0d8323dd9cc917956df982c107652ec31645ce7a Mon Sep 17 00:00:00 2001 From: Hadwa Abdelhalem Date: Thu, 5 Aug 2021 15:47:53 -0700 Subject: [PATCH 2/7] Update Azure ACI example --- .../azure/terraform-azure-aci-example/main.tf | 20 +++++------ .../terraform-azure-aci-example/output.tf | 8 +++-- .../terraform-azure-aci-example/variables.tf | 36 +++++++++---------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/examples/azure/terraform-azure-aci-example/main.tf b/examples/azure/terraform-azure-aci-example/main.tf index 46b506559..57f1791d2 100644 --- a/examples/azure/terraform-azure-aci-example/main.tf +++ b/examples/azure/terraform-azure-aci-example/main.tf @@ -1,6 +1,7 @@ # --------------------------------------------------------------------------------------------------------------------- -# DEPLOY AN AZURE CONTAINER REGISTRY -# This is an example of how to deploy an Azure Container Registry +# DEPLOY AN AZURE CONTAINER Instance +# This is an example of how to deploy an Azure Container Instance +# See test/terraform_azure_aci_example_test.go for how to write automated tests for this code. # --------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------ @@ -8,7 +9,7 @@ # ------------------------------------------------------------------------------ provider "azurerm" { - version = "=2.22.0" + version = "~>2.29.0" features {} } @@ -17,7 +18,7 @@ provider "azurerm" { # --------------------------------------------------------------------------------------------------------------------- resource "azurerm_resource_group" "rg" { - name = var.resource_group_name + name = "terratest-aci-rg-${var.postfix}" location = var.location } @@ -25,17 +26,14 @@ resource "azurerm_resource_group" "rg" { # DEPLOY AN AZURE CONTAINER INSTANCE # --------------------------------------------------------------------------------------------------------------------- -data "azurerm_client_config" "current" { -} - resource "azurerm_container_group" "aci" { - name = var.aci_name + name = "aci${var.postfix}" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name - ip_address_type = "public" - dns_name_label = var.aci_name - os_type = "Linux" + ip_address_type = "public" + dns_name_label = "aci${var.postfix}" + os_type = "Linux" container { name = "hello-world" diff --git a/examples/azure/terraform-azure-aci-example/output.tf b/examples/azure/terraform-azure-aci-example/output.tf index 962670bf9..5dc01af4d 100644 --- a/examples/azure/terraform-azure-aci-example/output.tf +++ b/examples/azure/terraform-azure-aci-example/output.tf @@ -1,3 +1,7 @@ +output "resource_group_name" { + value = azurerm_resource_group.rg.name +} + output "ip_address" { value = azurerm_container_group.aci.ip_address } @@ -6,6 +10,6 @@ output "fqdn" { value = azurerm_container_group.aci.fqdn } -output "subscription_id" { - value = data.azurerm_client_config.current.subscription_id +output "container_instance_name" { + value = azurerm_container_group.aci.name } diff --git a/examples/azure/terraform-azure-aci-example/variables.tf b/examples/azure/terraform-azure-aci-example/variables.tf index 22370157d..fba88385d 100644 --- a/examples/azure/terraform-azure-aci-example/variables.tf +++ b/examples/azure/terraform-azure-aci-example/variables.tf @@ -1,31 +1,31 @@ +# --------------------------------------------------------------------------------------------------------------------- +# 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. # --------------------------------------------------------------------------------------------------------------------- -variable "client_id" { - description = "The Service Principal Client Id for AKS to modify Azure resources." -} -variable "client_secret" { - description = "The Service Principal Client Password for AKS to modify Azure resources." -} - # --------------------------------------------------------------------------------------------------------------------- # OPTIONAL PARAMETERS # These parameters have reasonable defaults. # --------------------------------------------------------------------------------------------------------------------- -variable "aci_name" { - description = "The name to set for the ACI." - default = "acitest" -} - -variable "resource_group_name" { - description = "The name to set for the resource group." - default = "aci-rg" +variable "location" { + description = "The supported azure location where the resource exists" + type = string + default = "West US2" } -variable "location" { - description = "The location to set for the ACR." - default = "Central US" +variable "postfix" { + description = "A postfix string to centrally mitigate resource name collisions." + type = string + default = "1276" } From 4d4cad520dcbe01279fdd9b239b572d4e40ea1dc Mon Sep 17 00:00:00 2001 From: Hadwa Abdelhalem Date: Thu, 5 Aug 2021 15:48:19 -0700 Subject: [PATCH 3/7] Update ACI example readme --- .../terraform-azure-aci-example/README.md | 72 ++++--------------- 1 file changed, 14 insertions(+), 58 deletions(-) diff --git a/examples/azure/terraform-azure-aci-example/README.md b/examples/azure/terraform-azure-aci-example/README.md index 875d01cfd..f1bf7471a 100644 --- a/examples/azure/terraform-azure-aci-example/README.md +++ b/examples/azure/terraform-azure-aci-example/README.md @@ -1,6 +1,6 @@ # Terraform Azure Example -This folder contains a simple Terraform module that deploys resources in [Azure](https://azure.microsoft.com/) to demonstrate +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 an [Azure Container Instance](https://azure.microsoft.com/en-us/services/container-instances/). Check out [test/azure/terraform_azure_aci_example_test.go](/test/azure/terraform_azure_aci_example_test.go) to see how you can write @@ -12,67 +12,23 @@ 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. 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. Run `terraform init`. -1. Run `terraform apply`. -1. When you're done, run `terraform destroy`. + tools](https://docs.microsoft.com/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. 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. [Review environment variables](#review-environment-variables). -1. Install [Golang](https://golang.org/) and make sure this code is checked out into your `GOPATH`. -1. `cd test` -1. Make sure [the azure-sdk-for-go versions match](#check-go-dependencies) in [/test/go.mod](/test/go.mod) and in [test/azure/terraform_azure_aci_example_test.go](/test/azure/terraform_azure_aci_example_test.go). + 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_aci_example_test.go` -1. `go test -v -run TestTerraformAzureACIExample` +1. `go test -v -timeout 60m -tags azure -run TestTerraformAzureACIExample` -## Check Go Dependencies - -Check that the `github.com/Azure/azure-sdk-for-go` version in your generated `go.mod` for this test matches the version in the terratest [go.mod](https://github.com/gruntwork-io/terratest/blob/master/go.mod) file. - -> This was tested with **go1.14.1**. - -### Check Azure-sdk-for-go version - -Let's make sure [go.mod](https://github.com/gruntwork-io/terratest/blob/master/go.mod) includes the appropriate [azure-sdk-for-go version](https://github.com/Azure/azure-sdk-for-go/releases/tag/v38.1.0): - -```go -require ( - ... - github.com/Azure/azure-sdk-for-go v38.1.0+incompatible - ... -) -``` - -If we make changes to either the **go.mod** or the **go test file**, we should make sure that the go build command works still. - -```powershell -go build terraform_azure_aci_example_test.go -``` - -## Review Environment Variables - -As part of configuring terraform for Azure, we'll want to check that we have set the appropriate [credentials](https://docs.microsoft.com/en-us/azure/terraform/terraform-install-configure?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fterraform%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json#set-up-terraform-access-to-azure) and also that we set the [environment variables](https://docs.microsoft.com/en-us/azure/terraform/terraform-install-configure?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fterraform%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json#configure-terraform-environment-variables) on the testing host. - -```bash -export ARM_CLIENT_ID=your_app_id -export ARM_CLIENT_SECRET=your_password -export ARM_SUBSCRIPTION_ID=your_subscription_id -export ARM_TENANT_ID=your_tenant_id -``` - -Note, in a Windows environment, these should be set as **system environment variables**. We can use a PowerShell console with administrative rights to update these environment variables: - -```powershell -[System.Environment]::SetEnvironmentVariable("ARM_CLIENT_ID",$your_app_id,[System.EnvironmentVariableTarget]::Machine) -[System.Environment]::SetEnvironmentVariable("ARM_CLIENT_SECRET",$your_password,[System.EnvironmentVariableTarget]::Machine) -[System.Environment]::SetEnvironmentVariable("ARM_SUBSCRIPTION_ID",$your_subscription_id,[System.EnvironmentVariableTarget]::Machine) -[System.Environment]::SetEnvironmentVariable("ARM_TENANT_ID",$your_tenant_id,[System.EnvironmentVariableTarget]::Machine) -``` From ef35c523bffa105c55b8eea1d3048e26f5c6ea5a Mon Sep 17 00:00:00 2001 From: Hadwa Abdelhalem Date: Fri, 6 Aug 2021 10:37:08 -0700 Subject: [PATCH 4/7] Update Containers module to support ACI --- modules/azure/client_factory.go | 21 ++++++++++ modules/azure/containers.go | 74 ++++++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/modules/azure/client_factory.go b/modules/azure/client_factory.go index 778de44c8..10d9e1b5c 100644 --- a/modules/azure/client_factory.go +++ b/modules/azure/client_factory.go @@ -20,6 +20,7 @@ import ( "github.com/Azure/azure-sdk-for-go/profiles/preview/cosmos-db/mgmt/documentdb" "github.com/Azure/azure-sdk-for-go/profiles/preview/preview/monitor/mgmt/insights" "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" + "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2019-05-01/containerregistry" "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" @@ -686,6 +687,26 @@ func CreateContainerRegistryClientE(subscriptionID string) (*containerregistry.R return ®istryClient, nil } +// CreateContainerInstanceClientE returns an ACI client instance configured with the +// correct BaseURI depending on the Azure environment that is currently setup (or "Public", if none is setup). +func CreateContainerInstanceClientE(subscriptionID string) (*containerinstance.ContainerGroupsClient, error) { + // Validate Azure subscription ID + subscriptionID, err := getTargetAzureSubscription(subscriptionID) + if err != nil { + return nil, err + } + + // Lookup environment URI + baseURI, err := getEnvironmentEndpointE(ResourceManagerEndpointName) + if err != nil { + return nil, err + } + + // create client + instanceClient := containerinstance.NewContainerGroupsClientWithBaseURI(baseURI, subscriptionID) + return &instanceClient, nil +} + // GetKeyVaultURISuffixE returns the proper KeyVault URI suffix for the configured Azure environment. // This function would fail the test if there is an error. func GetKeyVaultURISuffixE() (string, error) { diff --git a/modules/azure/containers.go b/modules/azure/containers.go index 9773896ef..0232f7eef 100644 --- a/modules/azure/containers.go +++ b/modules/azure/containers.go @@ -4,7 +4,9 @@ import ( "context" "testing" + "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2019-05-01/containerregistry" + "github.com/stretchr/testify/require" ) @@ -61,7 +63,7 @@ func GetContainerRegistryE(registryName string, resGroupName string, subscriptio // GetContainerRegistryClientE is a helper function that will setup an Azure Container Registry client on your behalf func GetContainerRegistryClientE(subscriptionID string) (*containerregistry.RegistriesClient, error) { - // Create an Apps client + // Create an ACR client registryClient, err := CreateContainerRegistryClientE(subscriptionID) if err != nil { return nil, err @@ -77,3 +79,73 @@ func GetContainerRegistryClientE(subscriptionID string) (*containerregistry.Regi registryClient.Authorizer = *authorizer return registryClient, nil } + +// ContainerInstanceExists indicates whether the specified container instance exists. +// This function would fail the test if there is an error. +func ContainerInstanceExists(t *testing.T, instanceName string, resourceGroupName string, subscriptionID string) bool { + exists, err := ContainerInstanceExistsE(instanceName, resourceGroupName, subscriptionID) + require.NoError(t, err) + + return exists +} + +// ContainerInstanceExistsE indicates whether the specified container instance exists. +func ContainerInstanceExistsE(instanceName string, resourceGroupName string, subscriptionID string) (bool, error) { + _, err := GetContainerInstanceE(instanceName, resourceGroupName, subscriptionID) + if err != nil { + if ResourceNotFoundErrorExists(err) { + return false, nil + } + return false, err + } + return true, nil +} + +// GetContainerInstance gets the container instance object +// This function would fail the test if there is an error. +func GetContainerInstance(t *testing.T, instanceName string, resGroupName string, subscriptionID string) *containerinstance.ContainerGroup { + instance, err := GetContainerInstanceE(instanceName, resGroupName, subscriptionID) + + require.NoError(t, err) + + return instance +} + +// GetContainerInstanceE gets the container instance object +func GetContainerInstanceE(instanceName string, resGroupName string, subscriptionID string) (*containerinstance.ContainerGroup, error) { + rgName, err := getTargetAzureResourceGroupName(resGroupName) + if err != nil { + return nil, err + } + + client, err := GetContainerInstanceClientE(subscriptionID) + if err != nil { + return nil, err + } + + instance, err := client.Get(context.Background(), rgName, instanceName) + if err != nil { + return nil, err + } + + return &instance, nil +} + +// GetContainerInstanceClientE is a helper function that will setup an Azure Container Instance client on your behalf +func GetContainerInstanceClientE(subscriptionID string) (*containerinstance.ContainerGroupsClient, error) { + // Create an ACI client + instanceClient, err := CreateContainerInstanceClientE(subscriptionID) + if err != nil { + return nil, err + } + + // Create an authorizer + authorizer, err := NewAuthorizer() + if err != nil { + return nil, err + } + + // Attach authorizer to the client + instanceClient.Authorizer = *authorizer + return instanceClient, nil +} From 2dd4878e0c90255a36a2e48dc56d7e0f997c3965 Mon Sep 17 00:00:00 2001 From: Hadwa Abdelhalem Date: Fri, 6 Aug 2021 10:37:43 -0700 Subject: [PATCH 5/7] remove unused aci.go helpers --- modules/azure/aci.go | 46 -------------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 modules/azure/aci.go diff --git a/modules/azure/aci.go b/modules/azure/aci.go deleted file mode 100644 index 4a05f72fb..000000000 --- a/modules/azure/aci.go +++ /dev/null @@ -1,46 +0,0 @@ -package azure - -import ( - "context" - "testing" - - "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" - - "github.com/stretchr/testify/require" -) - -// GetACIClient is a helper function that will setup an Azure Container Instances client on your behalf -// resourceName - required to find the Function App -// resGroupName - use an empty string if you have the AZURE_RES_GROUP_NAME environment variable set -// subscriptionId - use an empty string if you have the ARM_SUBSCRIPTION_ID environment variable set -func GetACIClient(t *testing.T, resourceName string, resGroupName string, subscriptionID string) *containerinstance.ContainerGroup { - resource, err := getACIClientE(resourceName, resGroupName, subscriptionID) - - require.NoError(t, err) - - return resource -} - -func getACIClientE(resourceName string, resGroupName string, subscriptionID string) (*containerinstance.ContainerGroup, error) { - // Validate Azure subscription ID - subscriptionID, err := getTargetAzureSubscription(subscriptionID) - if err != nil { - return nil, err - } - - managedServicesClient := containerinstance.NewContainerGroupsClient(subscriptionID) - authorizer, err := NewAuthorizer() - - if err != nil { - return nil, err - } - - managedServicesClient.Authorizer = *authorizer - - resource, err := managedServicesClient.Get(context.Background(), resGroupName, resourceName) - if err != nil { - return nil, err - } - - return &resource, nil -} From 05a54cc93a5d4462c841551ec0897b22dae04f23 Mon Sep 17 00:00:00 2001 From: Hadwa Abdelhalem Date: Fri, 6 Aug 2021 10:38:18 -0700 Subject: [PATCH 6/7] Add ACI helpers unit tests --- modules/azure/containers_test.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/modules/azure/containers_test.go b/modules/azure/containers_test.go index 6a3a9695f..ff62f145c 100644 --- a/modules/azure/containers_test.go +++ b/modules/azure/containers_test.go @@ -46,3 +46,34 @@ func TestGetContainerRegistryClientE(t *testing.T) { _, err := GetContainerRegistryClientE(subscriptionID) require.NoError(t, err) } + +func TestContainerInstanceExistsE(t *testing.T) { + t.Parallel() + + resGroupName := "" + instanceName := "" + subscriptionID := "" + + _, err := ContainerInstanceExistsE(instanceName, resGroupName, subscriptionID) + require.Error(t, err) +} + +func TestGetContainerInstanceE(t *testing.T) { + t.Parallel() + + resGroupName := "" + instanceName := "" + subscriptionID := "" + + _, err := GetContainerInstanceE(instanceName, resGroupName, subscriptionID) + require.Error(t, err) +} + +func TestGetContainerInstanceClientE(t *testing.T) { + t.Parallel() + + subscriptionID := "" + + _, err := GetContainerInstanceClientE(subscriptionID) + require.NoError(t, err) +} From e11ee1e1c1d75206277b32411855861076c75b94 Mon Sep 17 00:00:00 2001 From: Hadwa Abdelhalem Date: Fri, 6 Aug 2021 10:38:42 -0700 Subject: [PATCH 7/7] Update ACI sample test --- .../azure/terraform_azure_aci_example_test.go | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/test/azure/terraform_azure_aci_example_test.go b/test/azure/terraform_azure_aci_example_test.go index d88933e09..e4921e003 100644 --- a/test/azure/terraform_azure_aci_example_test.go +++ b/test/azure/terraform_azure_aci_example_test.go @@ -6,7 +6,6 @@ package test import ( - "fmt" "strings" "testing" @@ -20,31 +19,33 @@ import ( func TestTerraformAzureACIExample(t *testing.T) { t.Parallel() - _random := strings.ToLower(random.UniqueId()) - - expectedResourceName := fmt.Sprintf("tmpaci%s", _random) - expectedResourceGroupName := fmt.Sprintf("tmp-rg-%s", _random) + uniquePostfix := strings.ToLower(random.UniqueId()) + // website::tag::1:: Configure Terraform setting up a path to Terraform code. terraformOptions := &terraform.Options{ - TerraformDir: "../../examples/terraform-azure-aci-example", + TerraformDir: "../../examples/azure/terraform-azure-aci-example", Vars: map[string]interface{}{ - "aci_name": expectedResourceName, - "resource_group_name": expectedResourceGroupName, + "postfix": uniquePostfix, }, } - // At the end of the test, run `terraform destroy` to clean up any resources that were created + + // website::tag::5:: At the end of the test, run `terraform destroy` to clean up any resources that were created defer terraform.Destroy(t, terraformOptions) - // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + // website::tag::2:: Run `terraform init` and `terraform apply`. Fail the test if there are any errors. terraform.InitAndApply(t, terraformOptions) - client := azure.GetACIClient(t, expectedResourceName, expectedResourceGroupName, "") - - assert := assert.New(t) + // website::tag::3:: Run `terraform output` to get the values of output variables + resourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") + aciName := terraform.Output(t, terraformOptions, "container_instance_name") + ipAddress := terraform.Output(t, terraformOptions, "ip_address") + fqdn := terraform.Output(t, terraformOptions, "fqdn") - assert.NotEmpty(*client.Name) + // website::tag::4:: Assert + assert.True(t, azure.ContainerInstanceExists(t, aciName, resourceGroupName, "")) - assert.NotEmpty(*client.IPAddress.Fqdn) + actualInstance := azure.GetContainerInstance(t, aciName, resourceGroupName, "") - assert.NotEmpty(*client.IPAddress.IP) + assert.Equal(t, ipAddress, *actualInstance.ContainerGroupProperties.IPAddress.IP) + assert.Equal(t, fqdn, *actualInstance.ContainerGroupProperties.IPAddress.Fqdn) }