Skip to content

Commit

Permalink
feat: ddosProtection (#197)
Browse files Browse the repository at this point in the history
* allow link to ddos protection plan

* added code to azapi update resource

* enable ddos protection plan

* add var to main module

* testing conditional

* testing conditional

* fix docs and fmt

* added new config to resource

* fix tags

* Update modules/virtualnetwork/variables.tf

Co-authored-by: Matt White <[email protected]>

* ci: rationalise housekeeping

* test: add ddosTest

* test: go get

---------

Co-authored-by: Pedro Parra Ortega <[email protected]>
Co-authored-by: Pedro Parra Ortega <[email protected]>
  • Loading branch information
3 people authored May 16, 2023
1 parent d02f03f commit 170e341
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 143 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/docs-fmt-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ jobs:
- name: Setup go
uses: actions/setup-go@v4
with:
go-version: '1.18.x'
go-version: '1.20.x'
cache-dependency-path: tests/go.sum

- name: Install tools
run: make tools
Expand Down
40 changes: 0 additions & 40 deletions .github/workflows/housekeep-cancelsubscriptions.yml

This file was deleted.

40 changes: 0 additions & 40 deletions .github/workflows/housekeep-deleteresourcegroups.yml

This file was deleted.

40 changes: 0 additions & 40 deletions .github/workflows/housekeep-deletesubscriptionaliases.yml

This file was deleted.

100 changes: 100 additions & 0 deletions .github/workflows/housekeep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
name: Housekeeping
on:
schedule:
- cron: "11 3 * * *" # daily at 3:11
workflow_dispatch:

permissions:
id-token: write

jobs:
cancelsubscriptions:
name: Cancel subscriptions
runs-on: ubuntu-latest
steps:
- name: Azure login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
allow-no-subscriptions: true

- name: Azure cancel subscriptions
uses: azure/CLI@v1
continue-on-error: true
with:
inlineScript: |
az config set extension.use_dynamic_install=yes_without_prompt
echo "==> Cancelling the following subscriptions:"
az account subscription list | jq -r '.[] | select(.state == "Enabled") | select(.displayName | test("^testdeploy.*")) | .subscriptionId'
az account subscription list | jq -r '.[] | select(.state == "Enabled") | select(.displayName | test("^testdeploy.*")) | .subscriptionId' | xargs -n1 -I% az account subscription cancel --yes --id %
echo "==> Done cancelling subscriptions"
- name: Azure logout
uses: azure/CLI@v1
if: always()
with:
inlineScript: |
az logout
az cache purge
az account clear
deletealiases:
name: Delete subscription aliases
runs-on: ubuntu-latest
steps:
- name: Azure login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
allow-no-subscriptions: true

- name: Azure delete subscription aliases
uses: azure/CLI@v1
continue-on-error: true
with:
inlineScript: |
az config set extension.use_dynamic_install=yes_without_prompt
echo "==> Deleting the following subscription aliases:"
az rest --method GET --uri '/providers/Microsoft.Subscription/aliases/?api-version=2021-10-01' | jq -r '.value[] | select(.name | test("^testdeploy")) | .name'
az rest --method GET --uri '/providers/Microsoft.Subscription/aliases/?api-version=2021-10-01' | jq -r '.value[] | select(.name | test("^testdeploy")) | .name' | xargs -n1 -I% az rest --method DELETE --uri '/providers/Microsoft.Subscription/aliases/%?api-version=2021-10-01'
echo "==> Done deleting subscription aliases"
- name: Azure logout
uses: azure/CLI@v1
if: always()
with:
inlineScript: |
az logout
az cache purge
az account clear
deleteresourcegroups:
name: Delete resource groups
runs-on: ubuntu-latest
steps:
- name: Azure login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
allow-no-subscriptions: true

- name: Azure delete resourcegroups
uses: azure/CLI@v1
continue-on-error: true
with:
inlineScript: |
echo "==> Deleting the following resource groups:"
az group list | jq -r '.[] | select(.name|test("testdeploy*")) | .name'
az group list | jq -r '.[] | select(.name|test("testdeploy*")) | .name' | xargs -n1 -I% az group delete --yes --name %
echo "==> Done deleting resource groups"
- name: Azure logout
uses: azure/CLI@v1
if: always()
with:
inlineScript: |
az logout
az cache purge
az account clear
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@ Description: A map of the virtual networks to create. The map key must be known

- `dns_servers`: A list of DNS servers to use for the virtual network, e.g. `["192.168.0.1", "10.0.0.1"]`. If empty will use the Azure default DNS. [optional - default empty list]

### DDOS protection plan

- `ddos_protection_enabled`: Whether to enable ddos protection. [optional]
- `ddos_protection_plan_id`: The resource ID of the protection plan to attach the vnet. [optional - but required if ddos\_protection\_enabled is `true`]

### Location

- `location`: The location of the virtual network (and resource group if creation is enabled). [optional, will use `var.location` if not specified or empty string]
Expand Down Expand Up @@ -466,6 +471,9 @@ map(object({
dns_servers = optional(list(string), [])
ddos_protection_enabled = optional(bool, false)
ddos_protection_plan_id = optional(string, "")
hub_network_resource_id = optional(string, "")
hub_peering_enabled = optional(bool, false)
hub_peering_name_tohub = optional(string, "")
Expand Down
11 changes: 10 additions & 1 deletion modules/virtualnetwork/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@ Description: A map of the virtual networks to create. The map key must be known

### DNS servers

- `dns_servers`: A list of DNS servers to use for the virtual network, e.g. `["192.168.0.1", "10.0.0.1]`. If empty will use the Azure default DNS. [optional - default empty list]
- `dns_servers`: A list of DNS servers to use for the virtual network, e.g. `["192.168.0.1", "10.0.0.1]`. If empty will use the Azure default DNS. [optional - default empty list]
DNS. [optional - default empty list]

### DDOS protection plan

- `ddos_protection_enabled`: Whether to enable ddos protection. [optional]
- `ddos_protection_plan_id`: The resource ID of the protection plan to attach the vnet. [optional - but required if ddos\_protection\_enabled is `true`]

### Location

Expand Down Expand Up @@ -143,6 +149,9 @@ map(object({
dns_servers = optional(list(string), [])
ddos_protection_enabled = optional(bool, false)
ddos_protection_plan_id = optional(string, "")
hub_network_resource_id = optional(string, "")
hub_peering_enabled = optional(bool, false)
hub_peering_name_tohub = optional(string, "")
Expand Down
48 changes: 32 additions & 16 deletions modules/virtualnetwork/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,22 @@ resource "azapi_resource" "vnet" {
name = each.value.name
location = coalesce(each.value.location, var.location)
body = jsonencode({
properties = {
addressSpace = {
addressPrefixes = each.value.address_space
}
dhcpOptions = {
dnsServers = each.value.dns_servers
}
}
properties = merge(
{
addressSpace = {
addressPrefixes = each.value.address_space
}
dhcpOptions = {
dnsServers = each.value.dns_servers
}
},
each.value.ddos_protection_enabled ? {
ddosProtectionPlan = {
id = each.value.ddos_protection_plan_id
}
enableDdosProtection = true
} : null
)
})
tags = each.value.tags
lifecycle {
Expand All @@ -67,14 +75,22 @@ resource "azapi_update_resource" "vnet" {
resource_id = azapi_resource.vnet[each.key].id
type = "Microsoft.Network/virtualNetworks@2021-08-01"
body = jsonencode({
properties = {
addressSpace = {
addressPrefixes = each.value.address_space
}
dhcpOptions = {
dnsServers = each.value.dns_servers
}
}
properties = merge(
{
addressSpace = {
addressPrefixes = each.value.address_space
}
dhcpOptions = {
dnsServers = each.value.dns_servers
}
},
each.value.ddos_protection_enabled ? {
ddosProtectionPlan = {
id = each.value.ddos_protection_plan_id
}
enableDdosProtection = true
} : null
)
tags = each.value.tags
})
}
Expand Down
18 changes: 18 additions & 0 deletions modules/virtualnetwork/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ variable "virtual_networks" {

dns_servers = optional(list(string), [])

ddos_protection_enabled = optional(bool, false)
ddos_protection_plan_id = optional(string, "")

hub_network_resource_id = optional(string, "")
hub_peering_enabled = optional(bool, false)
hub_peering_name_tohub = optional(string, "")
Expand Down Expand Up @@ -67,6 +70,12 @@ A map of the virtual networks to create. The map key must be known at the plan s
### DNS servers
- `dns_servers`: A list of DNS servers to use for the virtual network, e.g. `["192.168.0.1", "10.0.0.1]`. If empty will use the Azure default DNS. [optional - default empty list]
DNS. [optional - default empty list]
### DDOS protection plan
- `ddos_protection_enabled`: Whether to enable ddos protection. [optional]
- `ddos_protection_plan_id`: The resource ID of the protection plan to attach the vnet. [optional - but required if ddos_protection_enabled is `true`]
### Location
Expand Down Expand Up @@ -156,6 +165,15 @@ DESCRIPTION
error_message = "Address space entries must be specified in CIDR notation, e.g. 192.168.0.0/24."
}

# validate ddos protection plan resource id for networks with ddos protection enabled
validation {
condition = alltrue([
for k, v in var.virtual_networks :
can(regex("^/subscriptions/[a-f\\d]{4}(?:[a-f\\d]{4}-){4}[a-f\\d]{12}/resourceGroups/[\\w-._]{1,89}[^\\s.]/providers/Microsoft.Network/ddosProtectionPlans/[\\w-_.]{2,64}$", v.ddos_protection_plan_id)) if v.ddos_protection_enabled
])
error_message = "Hub network resource id must be an Azure ddos protection plan resource id, e.g. /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.Network/ddosProtectionPlans/my-protection-plan."
}

# validate hub network resource id for networks with hub peering enabled
validation {
condition = alltrue([
Expand Down
Loading

0 comments on commit 170e341

Please sign in to comment.