Skip to content

Commit c16df5a

Browse files
authored
feat: Add network module (#401)
* Add network module * address code review comments * rename the tfvars file
1 parent 5a6debf commit c16df5a

File tree

13 files changed

+334
-0
lines changed

13 files changed

+334
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Network
2+
3+
This Terraform module template provide a vnet and subnet resources in Azure for the given resource group.
4+
5+
Information about Azure virtual network can be found [here](https://docs.microsoft.com/en-us/azure/virtual-network/) as well as for the subnet [here](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-manage-subnet#add-a-subnet)
6+
7+
## Current Features:
8+
9+
- Provisions a virtual network resource for a given resource group
10+
- Provisions a set of subnets for the created VNet
11+
12+
## Usage Example
13+
14+
Virtual network (vnet) usage example:
15+
16+
```hcl
17+
module "network" {
18+
source = "../../modules/providers/azure/network"
19+
vnet_name = var.vnet_name
20+
resource_group_name = data.azurerm_resource_group.vnet.name
21+
location = data.azurerm_resource_group.vnet.location
22+
address_space = azurerm_virtual_network.address_space
23+
subnet_names = ["subnet1", "subent2"]
24+
subnet_prefixes = ["10.0.1.0/24", "10.0.2.0/24"]
25+
}
26+
```
27+
28+
## Outputs
29+
30+
Once the deployments are completed successfully, the output for the current module will be available in [output.tf](./output.tf)
31+
32+
## Argument Reference
33+
34+
Supported arguments for this module are available in [variables.tf](./variables.tf).
35+
More resources on this module are provided [here](https://www.terraform.io/docs/providers/azurerm/r/virtual_network.html) and [here](https://www.terraform.io/docs/providers/azurerm/r/subnet.html)
36+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module "azure-provider" {
2+
source = "../provider"
3+
}
4+
5+
data "azurerm_resource_group" "vnet" {
6+
name = var.resource_group_name
7+
}
8+
9+
resource "azurerm_virtual_network" "vnet" {
10+
name = var.vnet_name
11+
location = data.azurerm_resource_group.vnet.location
12+
resource_group_name = data.azurerm_resource_group.vnet.name
13+
address_space = var.address_space
14+
}
15+
16+
17+
resource "azurerm_subnet" "subnet" {
18+
count = length(var.subnets)
19+
name = var.subnets[count.index].name
20+
resource_group_name = data.azurerm_resource_group.vnet.name
21+
address_prefix = var.subnets[count.index].address_prefix
22+
virtual_network_name = var.vnet_name
23+
service_endpoints = var.subnets[count.index].service_endpoints
24+
25+
delegation {
26+
name = var.subnets[count.index].delegation.name
27+
service_delegation {
28+
name = var.subnets[count.index].delegation.service_delegation.name
29+
actions = var.subnets[count.index].delegation.service_delegation.actions
30+
}
31+
}
32+
33+
depends_on = [azurerm_virtual_network.vnet]
34+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "virtual_network_id" {
2+
description = "The id of the newly created vnet"
3+
value = azurerm_virtual_network.vnet.id
4+
}
5+
6+
output "subnet_ids" {
7+
description = "If supplied this represents the subnet IDs that should be allowed to access this resource"
8+
value = azurerm_subnet.subnet[*].id
9+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
resource_group_name = ""
2+
vnet_name = ""
3+
subnets = []
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
RESOURCE_GROUP_NAME=""
2+
VNET_NAME=""
3+
SUBNET_NAME=""
4+
ADDRESS_SPACE="10.2.0.0/16"
5+
ADDRESS_PREFIX=""
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package integration
2+
3+
import (
4+
"testing"
5+
6+
"github.com/microsoft/cobalt/test-harness/terratest-extensions/modules/azure"
7+
"github.com/microsoft/terratest-abstraction/integration"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
// healthCheck - Asserts that the deployment was successful.
12+
func healthCheck(t *testing.T, provisionState *string) {
13+
require.Equal(t, "Succeeded", *provisionState, "The deployment hasn't succeeded.")
14+
}
15+
16+
// VerifyCreatedVnets - validate the created subnets
17+
func VerifyCreatedVnets(subscriptionID, resourceGroupName, vnetOutputName string, vnetID string) func(goTest *testing.T, output integration.TerraformOutput) {
18+
return func(goTest *testing.T, output integration.TerraformOutput) {
19+
20+
expectedVnetList := output[vnetID].(interface{})
21+
22+
actualVnetList := azure.VnetsList(goTest, subscriptionID, resourceGroupName)
23+
24+
require.Subset(goTest, *actualVnetList, expectedVnetList, "Vnet does not exist in the resource group")
25+
}
26+
}
27+
28+
// VerifyCreatedSubnets - validate the created subnets
29+
func VerifyCreatedSubnets(subscriptionID, resourceGroupName, subnetOutputName string, vnetName string, subnetID string) func(goTest *testing.T, output integration.TerraformOutput) {
30+
return func(goTest *testing.T, output integration.TerraformOutput) {
31+
32+
expectedSubnetList := output[subnetID].([]interface{})
33+
34+
actualSubnetList := azure.VnetSubnetsList(goTest, subscriptionID, resourceGroupName, vnetName)
35+
36+
require.Subset(goTest, actualSubnetList, expectedSubnetList, "subnet does not exist in the VNet")
37+
}
38+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package integration
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/microsoft/cobalt/infra/modules/providers/azure/network/tests"
8+
"github.com/microsoft/terratest-abstraction/integration"
9+
)
10+
11+
var subscriptionID = os.Getenv("ARM_SUBSCRIPTION_ID")
12+
13+
func TestNetwork(t *testing.T) {
14+
testFixture := integration.IntegrationTestFixture{
15+
GoTest: t,
16+
TfOptions: tests.NetworkTFOptions,
17+
ExpectedTfOutputCount: 2,
18+
TfOutputAssertions: []integration.TerraformOutputValidation{
19+
VerifyCreatedVnets(subscriptionID,
20+
tests.ResourceGroupName,
21+
tests.VnetName,
22+
"virtual_network_id",
23+
),
24+
VerifyCreatedSubnets(subscriptionID,
25+
tests.ResourceGroupName,
26+
tests.SubnetName,
27+
tests.VnetName,
28+
"subnet_ids",
29+
),
30+
},
31+
}
32+
integration.RunIntegrationTests(&testFixture)
33+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
resource_group_name = ""
2+
vnet_name = ""
3+
subnet_names = [""]
4+
subnet_prefixes = [""]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package tests
2+
3+
import (
4+
"os"
5+
6+
"github.com/gruntwork-io/terratest/modules/terraform"
7+
)
8+
9+
// ResourceGroupName - The Resource Group Name
10+
var ResourceGroupName = os.Getenv("RESOURCE_GROUP_NAME")
11+
12+
// VnetName - The name of vnet
13+
var VnetName = os.Getenv("VNET_NAME")
14+
15+
// SubnetName - The name of subnet
16+
var SubnetName = os.Getenv("SUBNET_NAME")
17+
18+
// AddressSpace -
19+
var AddressSpace = os.Getenv("ADDRESS_SPACE")
20+
21+
// AddressPrefix -
22+
var AddressPrefix = os.Getenv("ADDRESS_PREFIX")
23+
24+
// NetworkTFOptions common terraform options used for unit and integration testing
25+
var NetworkTFOptions = &terraform.Options{
26+
TerraformDir: "../../",
27+
VarFiles: []string{"./tests/test.tfvars"},
28+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package unit
2+
3+
import (
4+
"encoding/json"
5+
"strings"
6+
"testing"
7+
8+
"github.com/gruntwork-io/terratest/modules/random"
9+
tests "github.com/microsoft/cobalt/infra/modules/providers/azure/network/tests"
10+
"github.com/microsoft/terratest-abstraction/unit"
11+
)
12+
13+
var resourceCount = 3
14+
15+
// helper function to parse blocks of JSON into a generic Go map
16+
func asMap(t *testing.T, jsonString string) map[string]interface{} {
17+
var theMap map[string]interface{}
18+
if err := json.Unmarshal([]byte(jsonString), &theMap); err != nil {
19+
t.Fatal(err)
20+
}
21+
return theMap
22+
}
23+
24+
func TestNetworkDeployment_Unit(t *testing.T) {
25+
26+
expectedVnetResult := asMap(t, `{
27+
"name": "`+tests.VnetName+`",
28+
"resource_group_name": "`+tests.ResourceGroupName+`",
29+
"address_space": ["`+tests.AddressSpace+`"]
30+
}`)
31+
32+
expectedSubnetResult := asMap(t, `{
33+
"name": "`+tests.SubnetName+`",
34+
"resource_group_name": "`+tests.ResourceGroupName+`",
35+
"address_prefix": ["`+tests.AddressPrefix+`"],
36+
"virtual_network_name": "`+tests.VnetName+`"
37+
}`)
38+
39+
testFixture := unit.UnitTestFixture{
40+
GoTest: t,
41+
TfOptions: tests.NetworkTFOptions,
42+
PlanAssertions: nil,
43+
ExpectedResourceCount: resourceCount,
44+
ExpectedResourceAttributeValues: unit.ResourceDescription{
45+
"azurerm_virtual_network.vnet": expectedVnetResult,
46+
"azurerm_subnet.subnet[0]": expectedSubnetResult,
47+
},
48+
}
49+
50+
unit.RunUnitTests(&testFixture)
51+
}

0 commit comments

Comments
 (0)