Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ crash.*.log
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
#*.tfvars
#*.tfvars.json

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
Expand Down
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
# terraform-azurerm-secure-network
Deploys an Azure Vnet that is NIST and PBMM compliant.
## Description
This module creates a NIST SP 800-53 and Canada Federal PBMM compliant Azure virtual network, and optional custom subnets, in an existing resource group (BYORG) and location that you specify. It's highly adjustable and takes the same input variables as [`azurerm_virtual_network`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network.html) and [`azurerm_subnet`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) resource definitions have attributes. All attributes for the vnet and subnets are optional. The vnet output variables contain all the information for the vnet, subnets, and nsgs.

## Using the Module
See the `examples/` folders on how to use the module.

### Terraform Registry
```
module "network" {
source = "cloudelementsca/terraform-azurerm-secure-network"

resource_group_name = azurerm_resource_group.network_rg.name
location = azurerm_resource_group.network_rg.location
}
```

### GitHub
```
module "network" {
source = "github.com/cloudelementsca/terraform-azurerm-secure-network"

resource_group_name = azurerm_resource_group.network_rg.name
location = azurerm_resource_group.network_rg.location
}
```
70 changes: 70 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
## ---------------------------------------------------------------------------------------------------------------------
## ONE LINE SUMMARY DESCRIBING WHAT IS BEING MANAGED IN THIS SECTION IN ALL CAPS
## The rest of the comments should be in standard casing. This section should contain an overall description of the
## component that is being managed, and highlight any unconventional workarounds or configurations that are in place.
## ---------------------------------------------------------------------------------------------------------------------

## ---------------------------------------------------------------------------------------------------------------------
## ALL MODULE RESOURCES
## Define all module resources in this file.
## ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_virtual_network" "vnet" {
name = var.network.name != null ? var.network.name : "vnet-${random_string.random_string_vnet.result}"
location = var.location
resource_group_name = var.resource_group_name
address_space = var.network.address_space
dns_servers = var.network.dns_servers
bgp_community = var.network.bgp_community
edge_zone = var.network.edge_zone
flow_timeout_in_minutes = var.network.flow_timeout_in_minutes

dynamic "ddos_protection_plan" {
for_each = var.network.ddos_protection_plan != null ? var.network.ddos_protection_plan : {}

content {
id = ddos_protection_plan.value.id
enable = ddos_protection_plan.value.enable
}
}

tags = var.tags
}

resource "azurerm_subnet" "subnets" {
for_each = var.network.subnets

name = each.value.name != null ? each.value.name : "subnet-${random_string.random_string_subnets[each.key].result}"
resource_group_name = var.resource_group_name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = each.value.address_prefixes != null ? each.value.address_prefixes : azurerm_virtual_network.vnet.address_space
private_endpoint_network_policies_enabled = each.value.private_endpoint_network_policies_enabled
private_link_service_network_policies_enabled = each.value.private_link_service_network_policies_enabled
service_endpoints = each.value.service_endpoints
service_endpoint_policy_ids = each.value.service_endpoint_policy_ids

dynamic "delegation" {
for_each = each.value.service_delegations != null ? each.value.service_delegations : {}
content {
name = delegation.key
service_delegation {
name = delegation.value.name
actions = delegation.value.actions
}
}
}
}

resource "random_string" "random_string_vnet" {
length = 6
special = false
upper = false
}

resource "random_string" "random_string_subnets" {
for_each = var.network.subnets

length = 6
special = false
upper = false
}
16 changes: 16 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## ---------------------------------------------------------------------------------------------------------------------
## ONE LINE SUMMARY DESCRIBING WHAT IS BEING MANAGED IN THIS SECTION IN ALL CAPS
## The rest of the comments should be in standard casing. This section should contain an overall description of the
## component that is being managed, and highlight any unconventional workarounds or configurations that are in place.
## ---------------------------------------------------------------------------------------------------------------------


output "vnet" {
description = "All vnet info."
value = azurerm_virtual_network.vnet
}

output "subnets" {
description = "All subnets info."
value = azurerm_subnet.subnets
}
17 changes: 17 additions & 0 deletions providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## ---------------------------------------------------------------------------------------------------------------------
## PROVIDERS FILE
## Define all required providers below.
## ---------------------------------------------------------------------------------------------------------------------

terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.54.0"
}
random = {
source = "hashicorp/random"
version = "=3.5.1"
}
}
}
61 changes: 61 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## ---------------------------------------------------------------------------------------------------------------------
## ALL MODULE VARIABLES
## Define all module variables below.
## ---------------------------------------------------------------------------------------------------------------------

## ---------------------------------------------------------------------------------------------------------------------
## MODULE PARAMETERS
## These variables are expected to be passed in by the operator
## ---------------------------------------------------------------------------------------------------------------------

variable "resource_group_name" {
description = "Name of existing resource group that will contain the vnet."
type = string
}

variable "location" {
description = "Location for all resources."
type = string
}

## ---------------------------------------------------------------------------------------------------------------------
## OPTIONAL PARAMETERS
## These variables have defaults and may be overridden
## ---------------------------------------------------------------------------------------------------------------------

variable "network" {
description = "Vnet definition."
type = object({
address_space = list(string)
subnets = optional(map(object({
address_prefixes = optional(list(string))
name = optional(string)
service_delegations = optional(map(object({
name = string
actions = list(string)
})), {})
private_endpoint_network_policies_enabled = optional(bool)
private_link_service_network_policies_enabled = optional(bool)
service_endpoints = optional(list(string))
service_endpoint_policy_ids = optional(list(string))
})), { subnet1 = {} })
name = optional(string)
dns_servers = optional(list(string), [])
bgp_community = optional(string)
ddos_protection_plan = optional(object({
id = string
enable = bool
}))
edge_zone = optional(string)
flow_timeout_in_minutes = optional(number)
})
default = {
address_space = ["10.0.0.0/8"]
}
}

variable "tags" {
description = "Tags for all resources."
type = map(string)
default = { environment = "dev" }
}