NashTech Insights

How to run the terratest on the already created resources.

Mohd Muzakkir Saifi
Mohd Muzakkir Saifi
Table of Contents
person using silver macbook pro

Introduction:-

Hello Learners, I am back with another blog. In today’s blog, we will learn about the terratest. In this blog, we will explore How we can run the test cases on the already created Azure resource If you like my blogs, you can read more blogs here.

Note:- I am working on the terratest blog series. So please follow my blog and learn about the terratest. You can check out this link for more blogs on the terratest.

Terratest:-

Most of the time, we have deployed our resources without Terraform, and suppose that now we need to test the Azure resource after deployment with the use of the Azure portal. In this case, We will run the test case on the resource.

First of all, you must have the Azure credential which has permission to access the resource [ Any resource which you want to access or run the terratest on that resource ].

Setting Up Your Test Project:-

Create a test folder and main_test.go file in that folder.

I am taking an example to test the Private ACR which is already created. Our test case will be to test the endpoint whether is private or public ACR. Now you can paste the below code in the main_test.go file.

main_test.go
package test

import (
	"testing"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os/exec"
	"os"
	"strings"
	"github.com/stretchr/testify/assert"
	"github.com/gruntwork-io/terratest/modules/terraform"
)


var (

	expectedPublicNetworkAccess = "Disabled"  

)

func TestTerraformOutputs(t *testing.T) {

	subscriptionID := os.Getenv("azure_subscription_id")
	acrName := ""
	resourceGroupName := ""



	accessToken, err := getAccessToken(subscriptionID)
	if err != nil {
		t.Errorf("Failed to get access token: %s", err.Error())
		return
	}

	acrDetails, err := getACRDetails(accessToken, subscriptionID, resourceGroupName, acrName)
	assert.NoError(t, err)

	actualPublicNetworkAccess:= isACRPrivate(acrDetails)
	
	t.Run(fmt.Sprintf("Checking the Access for this ACR: %s", acrName), func(t *testing.T) {
		assert.Equal(t, expectedPublicNetworkAccess, actualPublicNetworkAccess, "Test case has been failed for ACR - publicNetworkAccess")
	})



	}

func getAccessToken(subscriptionID string) (string, error) {
	// fmt.Println(subscriptionID)
	cmd := exec.Command("az", "account", "get-access-token", "--query", "accessToken", "--output", "tsv", "--subscription", subscriptionID)

	output, err := cmd.Output()
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(string(output)), nil
}




func getACRDetails(accessToken, subscriptionID, resourceGroupName, acrName string) (map[string]interface{}, error) {
	url := fmt.Sprintf("https://management.azure.com/subscriptions/%s/resourceGroups/%s/providers/Microsoft.ContainerRegistry/registries/%s?api-version=2023-06-01-preview", subscriptionID, resourceGroupName, acrName)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Authorization", "Bearer "+accessToken)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	var acrDetails map[string]interface{}
	err = json.Unmarshal(body, &acrDetails)
	if err != nil {
		return nil, err
	}

	return acrDetails, nil
}


func isACRPrivate(acrDetails map[string]interface{}) string {
	// Check if the "properties" field exists and its value is a map
	if properties, ok := acrDetails["properties"].(map[string]interface{}); ok {
		// Check if the "publicNetworkAccess" property exists and its value is a string
		if publicNetworkAccess, ok := properties["publicNetworkAccess"].(string); ok {
			return publicNetworkAccess
		} else {
			return "publicNetworkAccess not found or not a string"
		}
	} else {
		return "properties not found"
	}
}

Explanation:-

In this code, we are importing the required packages in the stating of the code and defining the global variable expectedPublicNetworkAccess which will be used in the test cases

After this, we have four functions in this terratest. This is the main test function where is the testing happening TestTerraformOutputs. We have 3 other functions as follows:-

Basically, when we will fetch the details of the private ACR that time we will need an access token for the REST API. So that function is used to get that token.

With the help of this function, we are fetching the private ACR details using REST API. Here we need the access token which comes from the first function.

This is the important part of this terratest. Basically, this function is checking whether the ACR is private or not. We are searching for a key in the JSON of the ACR. Where we will get that repo is private or not – publicNetworkAccess. If it is enabled that means the repo is public otherwise private.

Testing the Existing Resources:-

Now, we have the terratest code to test the private ACR. You can run the code with this command:

go mod init github.com/<>

go mod tidy

go test -v

Conclusion:-

In this blog, we have seen how to test the private ACR with the help of REST API and I have tried to explain the complete code in the part. If you like my blog then you can like this or want to read more blogs then follow this link. and also check out the terratest official doc.

Mohd Muzakkir Saifi

Mohd Muzakkir Saifi

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

%d bloggers like this: