diff --git a/terraform/azure/modules/add-routing-intent.py b/terraform/azure/modules/add-routing-intent.py new file mode 100755 index 00000000..a13eaa0d --- /dev/null +++ b/terraform/azure/modules/add-routing-intent.py @@ -0,0 +1,28 @@ +import json + +import requests +import sys + +def perform_put_request(url, data, headers=None): + """ + This function perform the PUT request to Azure in order to edit the vWAN Hub Routing-Intent + """ + result = {"status": "success", "message": ""} + try: + response = requests.put(url, json=data, headers=headers) + result["message"] = response.text + except Exception as e: + result["status"] = "error" + result["message"] = f"An error occurred: {str(e)}" + return result + +if __name__ == "__main__": + """ + This script receives url, body, and authorization token as arguments and set vWAN Hub Routing-Intent + """ + api_url = sys.argv[1] + api_data = eval(sys.argv[2]) + auth_token = sys.argv[3] + api_headers = {"Authorization": f'Bearer {auth_token}'} + result = perform_put_request(api_url, api_data, api_headers) + print(json.dumps(result)) diff --git a/terraform/azure/nva-into-existing-hub/README.md b/terraform/azure/nva-into-existing-hub/README.md index 13b467c1..e8c8ca55 100755 --- a/terraform/azure/nva-into-existing-hub/README.md +++ b/terraform/azure/nva-into-existing-hub/README.md @@ -11,6 +11,7 @@ As part of the deployment the following resources are created: ## Configurations - Install and configure Terraform to provision Azure resources: [Configure Terraform for Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/terraform-install-configure). +- In order to configure hub routing-intent policies it is **required** to have Python installed. ## Usage - Choose the preferred login method to Azure in order to deploy the solution: @@ -98,6 +99,10 @@ As part of the deployment the following resources are created: | **bgp-asn** | The BGP autonomous system number. | string | 64512 || | | | | | | | **custom-metrics** | Indicates whether CloudGuard Metrics will be use for gateway monitoring | string | yes;
no; | + | | | | | | + | **routing-intent-internet-traffic** | Set routing intent policy to allow internet traffic through the new nva | string | yes;
no; | + | | | | | | + | **routing-intent-private-traffic** | Set routing intent policy to allow private traffic through the new nva | string | yes;
no; | | | | | | | | **smart1-cloud-token-a** | Smart-1 Cloud token to connect automatically ***NVA instance a*** to Check Point's Security Management as a Service.

Follow these instructions to quickly connect this member to Smart-1 Cloud - [SK180501](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk180501) | string | A valid token copied from the Connect Gateway screen in Smart-1 Cloud portal | | | | | | | | @@ -137,6 +142,8 @@ As part of the deployment the following resources are created: ssh-public-key = "ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxx imported-openssh-key" bgp-asn = "64512" custom-metrics = "yes" + routing-intent-internet-traffic = "yes" + routing-intent-private-traffic = "yes" smart1-cloud-token-a = "" smart1-cloud-token-b = "" smart1-cloud-token-c = "" diff --git a/terraform/azure/nva-into-existing-hub/main.tf b/terraform/azure/nva-into-existing-hub/main.tf index 0f3fbe13..7498c236 100755 --- a/terraform/azure/nva-into-existing-hub/main.tf +++ b/terraform/azure/nva-into-existing-hub/main.tf @@ -41,10 +41,59 @@ data "http" "image-versions" { locals { image_versions = tolist([for version in jsondecode(data.http.image-versions.response_body).properties.availableVersions : version if substr(version, 0, 4) == lower(substr(replace(var.cloudguard-version, ".", ""), 1, 4))]) + routing_intent-internet-policy = { + "name": "InternetTraffic", + "destinations": [ + "Internet" + ], + "nextHop": "/subscriptions/${var.subscription_id}/resourcegroups/${var.nva-rg-name}/providers/Microsoft.Network/networkVirtualAppliances/${var.nva-name}" + } + routing_intent-private-policy = { + "name": "PrivateTrafficPolicy", + "destinations": [ + "PrivateTraffic" + ], + "nextHop": "/subscriptions/${var.subscription_id}/resourcegroups/${var.nva-rg-name}/providers/Microsoft.Network/networkVirtualAppliances/${var.nva-name}" + } + routing-intent-policies = var.routing-intent-internet-traffic == "yes" ? (var.routing-intent-private-traffic == "yes" ? tolist([local.routing_intent-internet-policy, local.routing_intent-private-policy]) : tolist([local.routing_intent-internet-policy])) : (var.routing-intent-private-traffic == "yes" ? tolist([local.routing_intent-private-policy]) : []) + req_body = jsonencode({"properties": {"routingPolicies": local.routing-intent-policies}}) + req_url = "https://management.azure.com/subscriptions/${var.subscription_id}/resourceGroups/${var.vwan-hub-resource-group}/providers/Microsoft.Network/virtualHubs/${var.vwan-hub-name}/routingIntent/hubRoutingIntent?api-version=2022-01-01" +} + +//********************** Marketplace Terms & Solution Registration **************************// +data "http" "accept-marketplace-terms-existing-agreement" { + method = "GET" + url = "https://management.azure.com/subscriptions/${var.subscription_id}/providers/Microsoft.MarketplaceOrdering/agreements/checkpoint/offers/azure-vwan/plans/vwan-app?api-version=2021-01-01" + request_headers = { + Accept = "application/json" + "Authorization" = "Bearer ${local.access_token}" + } +} + +resource "azurerm_marketplace_agreement" "accept-marketplace-terms" { + count = can(jsondecode(data.http.accept-marketplace-terms-existing-agreement.response_body).properties.id) && jsondecode(data.http.accept-marketplace-terms-existing-agreement.response_body).properties.state == "Active" ? 0 : 1 + publisher = "checkpoint" + offer = "azure-vwan" + plan = "vwan-app" +} + +data "http" "azurerm_resource_provider_registration-exist" { + method = "GET" + url = "https://management.azure.com/subscriptions/${var.subscription_id}/providers/Microsoft.Solutions?api-version=2021-01-01" + request_headers = { + Accept = "application/json" + "Authorization" = "Bearer ${local.access_token}" + } +} + +resource "azurerm_resource_provider_registration" "solutions" { + count = jsondecode(data.http.azurerm_resource_provider_registration-exist.response_body).registrationState == "Registered" ? 0 : 1 + name = "Microsoft.Solutions" } //********************** Managed Application Configuration **************************// resource "azurerm_managed_application" "nva" { + depends_on = [azurerm_marketplace_agreement.accept-marketplace-terms, azurerm_resource_provider_registration.solutions] name = var.managed-app-name location = azurerm_resource_group.managed-app-rg.location resource_group_name = azurerm_resource_group.managed-app-rg.name @@ -116,4 +165,17 @@ resource "azurerm_managed_application" "nva" { value = var.smart1-cloud-token-e } }) -} \ No newline at end of file +} + +//********************** Routing Intent **************************// + +data "external" "update-routing-intent" { + count = length(local.routing-intent-policies) != 0 ? 1 : 0 + depends_on = [azurerm_managed_application.nva] + program = ["python", "../modules/add-routing-intent.py", "${local.req_url}", "${local.req_body}", "${local.access_token}"] +} + +output "api_request_result" { + value = length(local.routing-intent-policies) != 0 ? data.external.update-routing-intent[0].result : {routing-intent: "not changed"} +} + diff --git a/terraform/azure/nva-into-existing-hub/terraform.tfvars b/terraform/azure/nva-into-existing-hub/terraform.tfvars index a0d055e5..fe410e5e 100755 --- a/terraform/azure/nva-into-existing-hub/terraform.tfvars +++ b/terraform/azure/nva-into-existing-hub/terraform.tfvars @@ -18,7 +18,9 @@ admin-shell = "PLEASE ENTER ADMIN SHELL" sic-key = "PLEASE ENTER SIC KEY" # "xxxxxxxxxx" ssh-public-key = "PLEASE ENTER SSH PUBLIC KEY" # "ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxx imported-openssh-key" bgp-asn = "PLEASE ENTER BGP AUTONOMOUS SYSTEM NUMBER" # "64512" -custom-metrics = "PLEASE ENTER yes or no" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +custom-metrics = "PLEASE ENTER yes or no" # "yes" +routing-intent-internet-traffic = "PLEASE ENTER yes or no" # "yes" +routing-intent-private-traffic = "PLEASE ENTER yes or no" # "yes" smart1-cloud-token-a = "PASTE TOKEN FROM SMART-1 CLOUD PORTAL FOR INSTANCE A OR LEAVE EMPTY DOUBLE QUOTES" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" smart1-cloud-token-b = "PASTE TOKEN FROM SMART-1 CLOUD PORTAL FOR INSTANCE B OR LEAVE EMPTY DOUBLE QUOTES" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" smart1-cloud-token-c = "PASTE TOKEN FROM SMART-1 CLOUD PORTAL FOR INSTANCE C OR LEAVE EMPTY DOUBLE QUOTES" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/terraform/azure/nva-into-existing-hub/variables.tf b/terraform/azure/nva-into-existing-hub/variables.tf index cbe5bfde..0842b74e 100755 --- a/terraform/azure/nva-into-existing-hub/variables.tf +++ b/terraform/azure/nva-into-existing-hub/variables.tf @@ -113,6 +113,22 @@ variable "custom-metrics" { } } +variable "routing-intent-internet-traffic" { + default = "yes" + validation { + condition = contains(["yes", "no"], var.routing-intent-internet-traffic) + error_message = "Valid options are string('yes' or 'no')" + } +} + +variable "routing-intent-private-traffic" { + default = "yes" + validation { + condition = contains(["yes", "no"], var.routing-intent-private-traffic) + error_message = "Valid options are string('yes' or 'no')" + } +} + variable "smart1-cloud-token-a" { type = string default = "" diff --git a/terraform/azure/nva-into-new-vwan/README.md b/terraform/azure/nva-into-new-vwan/README.md index d8365bd3..b886b595 100755 --- a/terraform/azure/nva-into-new-vwan/README.md +++ b/terraform/azure/nva-into-new-vwan/README.md @@ -13,6 +13,7 @@ As part of the deployment the following resources are created: ## Configurations - Install and configure Terraform to provision Azure resources: [Configure Terraform for Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/terraform-install-configure). +- In order to configure hub routing-intent policies it is **required** to have Python installed. ## Usage - Choose the preferred login method to Azure in order to deploy the solution: @@ -102,7 +103,11 @@ As part of the deployment the following resources are created: | **bgp-asn** | The BGP autonomous system number. | string | 64512 || | | | | | | | **custom-metrics** | Indicates whether CloudGuard Metrics will be use for gateway monitoring | string | yes;
no; | - | | | | | | + | | | | | | + | **routing-intent-internet-traffic** | Set routing intent policy to allow internet traffic through the new nva | string | yes;
no; | + | | | | | | + | **routing-intent-private-traffic** | Set routing intent policy to allow private traffic through the new nva | string | yes;
no; | + | | | | | | | **smart1-cloud-token-a** | Smart-1 Cloud token to connect automatically ***NVA instance a*** to Check Point's Security Management as a Service.

Follow these instructions to quickly connect this member to Smart-1 Cloud - [SK180501](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk180501) | string | A valid token copied from the Connect Gateway screen in Smart-1 Cloud portal | | | | | | | | | **smart1-cloud-token-b** | Smart-1 Cloud token to connect automatically ***NVA instance b*** to Check Point's Security Management as a Service.

Follow these instructions to quickly connect this member to Smart-1 Cloud - [SK180501](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk180501) | string | A valid token copied from the Connect Gateway screen in Smart-1 Cloud portal | | @@ -142,6 +147,8 @@ As part of the deployment the following resources are created: ssh-public-key = "ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxx imported-openssh-key" bgp-asn = "64512" custom-metrics = "yes" + routing-intent-internet-traffic = "yes" + routing-intent-private-traffic = "yes" smart1-cloud-token-a = "" smart1-cloud-token-b = "" smart1-cloud-token-c = "" diff --git a/terraform/azure/nva-into-new-vwan/main.tf b/terraform/azure/nva-into-new-vwan/main.tf index 5a420e6b..143ddd5c 100755 --- a/terraform/azure/nva-into-new-vwan/main.tf +++ b/terraform/azure/nva-into-new-vwan/main.tf @@ -18,7 +18,6 @@ resource "azurerm_virtual_hub" "vwan-hub" { virtual_wan_id = azurerm_virtual_wan.vwan.id } - //********************** Image Version **************************// data "external" "az_access_token" { @@ -51,10 +50,61 @@ data "http" "image-versions" { locals { image_versions = tolist([for version in jsondecode(data.http.image-versions.response_body).properties.availableVersions : version if substr(version, 0, 4) == lower(substr(replace(var.cloudguard-version, ".", ""), 1, 4))]) + routing_intent-internet-policy = { + "name": "InternetTraffic", + "destinations": [ + "Internet" + ], + "nextHop": "/subscriptions/${var.subscription_id}/resourcegroups/${var.nva-rg-name}/providers/Microsoft.Network/networkVirtualAppliances/${var.nva-name}" + } + routing_intent-private-policy = { + "name": "PrivateTrafficPolicy", + "destinations": [ + "PrivateTraffic" + ], + "nextHop": "/subscriptions/${var.subscription_id}/resourcegroups/${var.nva-rg-name}/providers/Microsoft.Network/networkVirtualAppliances/${var.nva-name}" + } + routing-intent-policies = var.routing-intent-internet-traffic == "yes" ? (var.routing-intent-private-traffic == "yes" ? tolist([local.routing_intent-internet-policy, local.routing_intent-private-policy]) : tolist([local.routing_intent-internet-policy])) : (var.routing-intent-private-traffic == "yes" ? tolist([local.routing_intent-private-policy]) : []) + req_body = jsonencode({"properties": {"routingPolicies": local.routing-intent-policies}}) + req_url = "https://management.azure.com/subscriptions/${var.subscription_id}/resourceGroups/${azurerm_resource_group.managed-app-rg.name}/providers/Microsoft.Network/virtualHubs/${var.vwan-hub-name}/routingIntent/hubRoutingIntent?api-version=2022-01-01" + +} + +//********************** Marketplace Terms & Solution Registration **************************// +data "http" "accept-marketplace-terms-existing-agreement" { + method = "GET" + url = "https://management.azure.com/subscriptions/${var.subscription_id}/providers/Microsoft.MarketplaceOrdering/agreements/checkpoint/offers/azure-vwan/plans/vwan-app?api-version=2021-01-01" + request_headers = { + Accept = "application/json" + "Authorization" = "Bearer ${local.access_token}" + } +} + +resource "azurerm_marketplace_agreement" "accept-marketplace-terms" { + count = can(jsondecode(data.http.accept-marketplace-terms-existing-agreement.response_body).properties.id) && jsondecode(data.http.accept-marketplace-terms-existing-agreement.response_body).properties.state == "Active" ? 0 : 1 + publisher = "checkpoint" + offer = "azure-vwan" + plan = "vwan-app" +} + + +data "http" "azurerm_resource_provider_registration-exist" { + method = "GET" + url = "https://management.azure.com/subscriptions/${var.subscription_id}/providers/Microsoft.Solutions?api-version=2021-01-01" + request_headers = { + Accept = "application/json" + "Authorization" = "Bearer ${local.access_token}" + } +} + +resource "azurerm_resource_provider_registration" "solutions" { + count = jsondecode(data.http.azurerm_resource_provider_registration-exist.response_body).registrationState == "Registered" ? 0 : 1 + name = "Microsoft.Solutions" } //********************** Managed Application Configuration **************************// resource "azurerm_managed_application" "nva" { + depends_on = [azurerm_marketplace_agreement.accept-marketplace-terms, azurerm_resource_provider_registration.solutions] name = var.managed-app-name location = azurerm_resource_group.managed-app-rg.location resource_group_name = azurerm_resource_group.managed-app-rg.name @@ -126,4 +176,15 @@ resource "azurerm_managed_application" "nva" { value = var.smart1-cloud-token-e } }) -} \ No newline at end of file +} + +//********************** Routing Intent **************************// +data "external" "update-routing-intent" { + count = length(local.routing-intent-policies) != 0 ? 1 : 0 + depends_on = [azurerm_managed_application.nva] + program = ["python", "../modules/add-routing-intent.py", "${local.req_url}", "${local.req_body}", "${local.access_token}"] +} + +output "api_request_result" { + value = length(local.routing-intent-policies) != 0 ? data.external.update-routing-intent[0].result : {routing-intent: "not changed"} +} diff --git a/terraform/azure/nva-into-new-vwan/terraform.tfvars b/terraform/azure/nva-into-new-vwan/terraform.tfvars index 7a58991a..9b29241a 100755 --- a/terraform/azure/nva-into-new-vwan/terraform.tfvars +++ b/terraform/azure/nva-into-new-vwan/terraform.tfvars @@ -1,4 +1,4 @@ - #PLEASE refer to the README.md for accepted values for the variables below +#PLEASE refer to the README.md for accepted values for the variables below authentication_method = "PLEASE ENTER AUTHENTICATION METHOD" # "Service Principal" client_secret = "PLEASE ENTER CLIENT SECRET" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" client_id = "PLEASE ENTER CLIENT ID" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -6,8 +6,8 @@ tenant_id = "PLEASE ENTER TENANT ID" subscription_id = "PLEASE ENTER SUBSCRIPTION ID" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" resource-group-name = "PLEASE ENTER RESOURCE GROUP NAME" # "tf-managed-app-resource-group" location = "PLEASE ENTER LOCATION" # "westcentralus" -vwan-name = "PLEASE ENTER VIRTUAL WAN NAME" # "tf-vwan" -vwan-hub-name = "PLEASE ENTER VWAN HUB NAME" # "tf-vwan-hub" +vwan-name = "PLEASE ENTER VIRTUAL WAN NAME" # "tf-cp-vwan" +vwan-hub-name = "PLEASE ENTER VWAN HUB NAME" # "tf-cp-vwan-hub" vwan-hub-address-prefix = "PLEASE ENTER VWAN HUB ADDRESS PREFIX" # "10.0.0.0/16" managed-app-name = "PLEASE ENTER MANAGED APPLICATION NAME" # "tf-vwan-managed-app-nva" nva-rg-name = "PLEASE ENTER NVA RESOURCE GROUP NAME" # "tf-vwan-nva-rg" @@ -19,7 +19,9 @@ admin-shell = "PLEASE ENTER ADMIN SHELL" sic-key = "PLEASE ENTER SIC KEY" # "xxxxxxxxxx" ssh-public-key = "PLEASE ENTER SSH PUBLIC KEY" # "ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxx imported-openssh-key" bgp-asn = "PLEASE ENTER BGP AUTONOMOUS SYSTEM NUMBER" # "64512" -custom-metrics = "PLEASE ENTER yes or no" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +custom-metrics = "PLEASE ENTER yes or no" # "yes" +routing-intent-internet-traffic = "PLEASE ENTER yes or no" # "yes" +routing-intent-private-traffic = "PLEASE ENTER yes or no" # "yes" smart1-cloud-token-a = "PASTE TOKEN FROM SMART-1 CLOUD PORTAL FOR INSTANCE A OR LEAVE EMPTY DOUBLE QUOTES" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" smart1-cloud-token-b = "PASTE TOKEN FROM SMART-1 CLOUD PORTAL FOR INSTANCE B OR LEAVE EMPTY DOUBLE QUOTES" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" smart1-cloud-token-c = "PASTE TOKEN FROM SMART-1 CLOUD PORTAL FOR INSTANCE C OR LEAVE EMPTY DOUBLE QUOTES" # "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/terraform/azure/nva-into-new-vwan/variables.tf b/terraform/azure/nva-into-new-vwan/variables.tf index bfd866d8..033819bb 100755 --- a/terraform/azure/nva-into-new-vwan/variables.tf +++ b/terraform/azure/nva-into-new-vwan/variables.tf @@ -119,6 +119,22 @@ variable "custom-metrics" { } } +variable "routing-intent-internet-traffic" { + default = "yes" + validation { + condition = contains(["yes", "no"], var.routing-intent-internet-traffic) + error_message = "Valid options are string('yes' or 'no')" + } +} + +variable "routing-intent-private-traffic" { + default = "yes" + validation { + condition = contains(["yes", "no"], var.routing-intent-private-traffic) + error_message = "Valid options are string('yes' or 'no')" + } +} + variable "smart1-cloud-token-a" { type = string default = ""