Appendix D: Ivanti Connect Secure Terraform Template

Terraform is an open source tool to easily define, preview, and deploy cloud infrastructure on Azure Cloud. Ivanti provides sample Terraform template files for 2 NICs and 3 NICs to deploy the Ivanti Connect Secure Virtual Appliance on Azure Cloud. Users can modify this to make it suitable for their need. Visit https://www.Ivantisecure.net and download the template file.

Base Setup

#Terraform version

terraform {

required_version = ">= v0.12.24"

}

#Provider version

provider "azurerm" {

version = ">= 2.0.0"

features {}

}

#Create a Resource Group for storing common infra resources:

# Virtual Network

# Subnet for Int, Ext and Mgmt Port of ICS

# Subnet for Backend Server resources

# Security Group for Int, Ext and Mgmt Port of ICS

#Security Group for Backend Server resources

resource "azurerm_resource_group" "rg_for_base_setup" {

name = var.resource_group

location = var.location

}

resource "azurerm_storage_account" "storage_account_for_base_setup" {

name = var.storage_account

resource_group_name = var.resource_group

location = azurerm_resource_group.rg_for_base_setup.location

account_tier = "Standard"

account_replication_type = "LRS"

}

resource "azurerm_storage_container" "container_terraform_state" {

name = "terraform-state"

storage_account_name = azurerm_storage_account.storage_account_for_base_setup.name

container_access_type = "private"

}

#Create a Virtual Network within the Resource Group

resource "azurerm_virtual_network" "vnet" {

name = "vnet1-westus2"

resource_group_name = var.resource_group

location = azurerm_resource_group.rg_for_base_setup.location

address_space = ["10.11.0.0/16"]

}

#Create Subnet

#Internal Port

resource "azurerm_subnet" "pcs_int_port_subnet" {

name = var.subnet_map["pcs_int_port"]["name"]

resource_group_name = azurerm_resource_group.rg_for_base_setup.name

virtual_network_name = azurerm_virtual_network.vnet.name

address_prefix = var.subnet_map["pcs_int_port"]["cidr"]

}

#External Port

resource "azurerm_subnet" "pcs_ext_port_subnet" {

name = var.subnet_map["pcs_ext_port"]["name"]

resource_group_name = azurerm_resource_group.rg_for_base_setup.name

virtual_network_name = azurerm_virtual_network.vnet.name

address_prefix = var.subnet_map["pcs_ext_port"]["cidr"]

}

#Management Port

resource "azurerm_subnet" "pcs_mgmt_port_subnet" {

name = var.subnet_map["pcs_mgmt_port"]["name"]

resource_group_name = azurerm_resource_group.rg_for_base_setup.name

virtual_network_name = azurerm_virtual_network.vnet.name

address_prefix = var.subnet_map["pcs_mgmt_port"]["cidr"]

}

#Tunnel Subnet

resource "azurerm_subnet" "pcs_tunnel_subnet" {

name = var.subnet_map["pcs_tunnel_subnet"]["name"]

resource_group_name = azurerm_resource_group.rg_for_base_setup.name

virtual_network_name = azurerm_virtual_network.vnet.name

address_prefix = var.subnet_map["pcs_tunnel_subnet"]["cidr"]

}

#Create Security Group Internal Port

resource "azurerm_network_security_group" "nsg_pcs_int_port" {

name = var.security_group_map["pcs_int_port"]

location = var.location

resource_group_name = azurerm_resource_group.rg_for_base_setup.name

#AllowCustomSSH for connecting to Azure

security_rule {

name = "AllowCustomSSH"

priority = 100

direction = "Inbound"

access = "Allow"

protocol = "*"

source_port_range = "*"

destination_port_range = "6667"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#HTTP

security_rule {

name = "HTTP"

priority = 200

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "80"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#HTTPS

security_rule {

name = "HTTPS"

priority = 300

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "443"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#DMI Netconf port

security_rule {

name = "DMINetconfPort"

priority = 400

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "830"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#Allow All ICMP

security_rule {

name = "AllowAllICMP"

priority = 500

direction = "Inbound"

access = "Allow"

protocol = "Icmp"

source_port_range = "*"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#TCP Ports for Cluster Communication

security_rule {

name = "TCPPortsForClusterCommunication"

priority = 600

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "11000-11099"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#TCP Ports 4808 and 4809 for Cluster Communication

security_rule {

name = "TCPPorts4808and4809ForClusterCommunication"

priority = 700

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "4808-4809"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#TCP Ports 4900 - 4910 for Cluster Key Exchange and State Sync

security_rule {

name = "TCPPorts4900-4910ForClusterKeyExchangeandStateSync"

priority = 800

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "4900-4910"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#UDP Ports for Cluster Communication

security_rule {

name = "UDPPortsForClusterCommunication"

priority = 900

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "4803"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#UDP Ports for Cluster HeartBeat

security_rule {

name = "UDPPortsForClusterHeartBeat"

priority = 1000

direction = "Inbound"

access = "Allow"

protocol = "Udp"

source_port_range = "4804"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#UDP Ports for Pulse L3 Connection

security_rule {

name = "UDPPortsforPulseL3Connection"

priority = 1100

direction = "Inbound"

access = "Allow"

protocol = "Udp"

source_port_range = "4500"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

}

#Create Security Group for External Port

resource "azurerm_network_security_group" "nsg_pcs_ext_port" {

name = var.security_group_map["pcs_ext_port"]

location = var.location

resource_group_name = azurerm_resource_group.rg_for_base_setup.name

#AllowCustomSSH for connecting to Azure

security_rule {

name = "AllowCustomSSH"

priority = 100

direction = "Inbound"

access = "Allow"

protocol = "*"

source_port_range = "*"

destination_port_range = "6667"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#HTTP

security_rule {

name = "HTTP"

priority = 200

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "80"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#HTTPS

security_rule {

name = "HTTPS"

priority = 300

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "443"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#Allow All ICMP

security_rule {

name = "AllowAllICMP"

priority = 400

direction = "Inbound"

access = "Allow"

protocol = "Icmp"

source_port_range = "*"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#UDP Ports for Pulse L3 Connection

security_rule {

name = "UDPPortsforPulseL3Connection"

priority = 500

direction = "Inbound"

access = "Allow"

protocol = "Udp"

source_port_range = "4500"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#IKEv2

security_rule {

name = "IKEv2"

priority = 600

direction = "Inbound"

access = "Allow"

protocol = "Udp"

source_port_range = "*"

destination_port_range = "500"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#PTP

security_rule {

name = "PTP"

priority = 700

direction = "Inbound"

access = "Allow"

protocol = "Udp"

source_port_range = "*"

destination_port_range = "11000-11099"

source_address_prefix = "*"

destination_address_prefix = "*"

}

}

#Create Security Group for Management Port

resource "azurerm_network_security_group" "nsg_pcs_mgmt_port" {

name = var.security_group_map["pcs_mgmt_port"]

location = var.location

resource_group_name = azurerm_resource_group.rg_for_base_setup.name

#AllowCustomSSH for connecting to Azure

security_rule {

name = "AllowCustomSSH"

priority = 100

direction = "Inbound"

access = "Allow"

protocol = "*"

source_port_range = "*"

destination_port_range = "6667"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#HTTP

security_rule {

name = "HTTP"

priority = 200

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "80"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#HTTPS

security_rule {

name = "HTTPS"

priority = 300

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "443"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#DMI Netconf port

security_rule {

name = "DMINetconfPort"

priority = 400

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "830"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#Allow All ICMP

security_rule {

name = "AllowAllICMP"

priority = 500

direction = "Inbound"

access = "Allow"

protocol = "Icmp"

source_port_range = "*"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

}

#Create Security Group for Backend Servers

resource "azurerm_network_security_group" "nsg_backend_svr" {

name = var.security_group_map["backend_svr"]

location = var.location

resource_group_name = azurerm_resource_group.rg_for_base_setup.name

#SSh

security_rule {

name = "SSh"

priority = 100

direction = "Inbound"

access = "Allow"

protocol = "*"

source_port_range = "*"

destination_port_range = "22"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#HTTP

security_rule {

name = "HTTP"

priority = 200

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "80"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#HTTPS

security_rule {

name = "HTTPS"

priority = 300

direction = "Inbound"

access = "Allow"

protocol = "Tcp"

source_port_range = "*"

destination_port_range = "443"

source_address_prefix = "*"

destination_address_prefix = "*"

}

#Allow All ICMP

security_rule {

name = "AllowAllICMP"

priority = 500

direction = "Inbound"

access = "Allow"

protocol = "Icmp"

source_port_range = "*"

destination_port_range = "*"

source_address_prefix = "*"

destination_address_prefix = "*"

}

}

ICS with 2 NICs

#Terraform version

terraform {

required_version = ">= v0.12.24"

}

#Provider version

provider "azurerm" {

version = ">= 2.0.0"

features {}

}

#Data sources

data "azurerm_storage_account" "storage_account" {

name = var.storage_account

resource_group_name = var.resource_group

}

#Internal Port Subnet

data "azurerm_subnet" "pcs_int_port_subnet" {

name = var.subnet_map["pcs_int_port"]["name"]

virtual_network_name = var.vnet

resource_group_name = var.resource_group

}

#External Port Subnet

data "azurerm_subnet" "pcs_ext_port_subnet" {

name = var.subnet_map["pcs_ext_port"]["name"]

virtual_network_name = var.vnet

resource_group_name = var.resource_group

}

#Mangement Port Subnet

data "azurerm_subnet" "pcs_mgmt_port_subnet" {

name = var.subnet_map["pcs_mgmt_port"]["name"]

virtual_network_name = var.vnet

resource_group_name = var.resource_group

}

#Data sources for Security Groups

data "azurerm_network_security_group" "nsg_pcs_int_port" {

name = var.security_group_map["pcs_int_port"]

resource_group_name = var.resource_group

}

data "azurerm_network_security_group" "nsg_pcs_ext_port" {

name = var.security_group_map["pcs_ext_port"]

resource_group_name = var.resource_group

}

data "azurerm_network_security_group" "nsg_pcs_mgmt_port" {

name = var.security_group_map["pcs_mgmt_port"]

resource_group_name = var.resource_group

}

data "azurerm_network_security_group" "nsg_backend_svr" {

name = var.security_group_map["backend_svr"]

resource_group_name = var.resource_group

}

#Local variables

locals {

security_group_id_map = {

"pcs_int_port" = data.azurerm_network_security_group.nsg_pcs_int_port.id,

"pcs_ext_port" = data.azurerm_network_security_group.nsg_pcs_ext_port.id,

"pcs_mgmt_port" = data.azurerm_network_security_group.nsg_pcs_mgmt_port.id,

"backend_svr" = data.azurerm_network_security_group.nsg_backend_svr.id,

}

subnet_id_map = {

"pcs_int_port" = data.azurerm_subnet.pcs_int_port_subnet.id

"pcs_ext_port" = data.azurerm_subnet.pcs_ext_port_subnet.id

"pcs_mgmt_port" = data.azurerm_subnet.pcs_mgmt_port_subnet.id

}

}

#Create a Resource Group

resource "azurerm_resource_group" "rg_for_pcs_instance" {

name = "rg-${var.instance_name}"

location = var.location

}

#Create Internal Port

resource "azurerm_network_interface" "pcs_int_port" {

name = "pcs-int-port"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

ip_configuration {

name = "pcs-int-port-ip"

#subnet_id = "${azurerm_subnet.intsubnet.id}"

subnet_id = local.subnet_id_map["pcs_int_port"]

private_ip_address_allocation = "Dynamic"

private_ip_address_version = "IPv4" #or IPv6. IPv6 is not supported on ICS on Azure yet

#assign public IP for the pcs_int_port

public_ip_address_id = azurerm_public_ip.int_port_public_ip.id

}

#when set to true, Azure allows this interface to send traffic with source IP other than its own IP

#this is needed for Pulse Client usecase

enable_ip_forwarding = "true" #default is false

#The (relative) DNS Name used for internal communications between Virtual Machines in the same Virtual Network

#internal_dns_name_label = "dns-name"

}

#associate security group to internal port

resource "azurerm_network_interface_security_group_association" "nsg_asso_pcs_int_port" {

network_interface_id = azurerm_network_interface.pcs_int_port.id

network_security_group_id = local.security_group_id_map["pcs_int_port"]

}

#Create External Port

resource "azurerm_network_interface" "pcs_ext_port" {

name = "pcs-ext-port"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

ip_configuration {

name = "pcs-ext-port-ip"

#subnet_id = "${azurerm_subnet.intsubnet.id}"

subnet_id = local.subnet_id_map["pcs_ext_port"]

private_ip_address_allocation = "Dynamic"

private_ip_address_version = "IPv4" #or IPv6. IPv6 is not supported on Azure yet

#assign public IP for the pcs_ext_port

public_ip_address_id = azurerm_public_ip.ext_port_public_ip.id

}

}

#Associate Security Group to External Port

resource "azurerm_network_interface_security_group_association" "nsg_asso_pcs_ext_port" {

network_interface_id = azurerm_network_interface.pcs_ext_port.id

network_security_group_id = local.security_group_id_map["pcs_ext_port"]

}

#Create a Public IP for Internal Port

resource "azurerm_public_ip" "int_port_public_ip" {

name = "pcs-int-port-public-ip"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

allocation_method = "Static"

#domain_name_label = var.pcs_int_port_hostname

}

#Create a Public IP for External Port

resource "azurerm_public_ip" "ext_port_public_ip" {

name = "pcs-ext-port-public-ip"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

allocation_method = "Static"

#domain_name_label = var.pcs_ext_port_hostname

}

#accept the terms using az vm image terms accept --urn pulse-secure:pulse-connect-secure-vm:pcs-byol:9.1.1505

#substitute 9.1.1505 with the version you are trying to installe

#this command has to be run only once for a version

#hence commenting the azurerm_marketplace_agreement block

#resource "azurerm_marketplace_agreement" "pcs_agreement" {

# publisher = var.image_publisher #pulse-secure

# offer = var.image_offer #pulse-connect-secure-vm

# plan = var.image_sku #pcs-byol

#}

#Create a instance on Azure

resource "azurerm_linux_virtual_machine" "pcs_instance" {

name = var.instance_name

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name #all resources belonging to this VM will be stored in this resource group

#vm_size = "Standard_B1s"

size = "Standard_DS2_v2"

#availability zone

#zone = "1" #create in availability zone 1 in westus2 region, this is for resiliency

network_interface_ids = [ azurerm_network_interface.pcs_int_port.id, azurerm_network_interface.pcs_ext_port.id ]

admin_username = "adminuser"

admin_ssh_key {

username = "adminuser"

public_key = var.os_profile_ssh_key_map["public_key"]

}

#custom-data - used for initial config

custom_data = base64encode("<pulse-config><primary-dns>8.8.8.8</primary-dns><secondary-dns>8.8.8.9</secondary-dns><wins-server>1.1.1.1</wins-server><dns-domain>pcsqa.psecure.net</dns-domain><admin-username>admindb</admin-username><admin-password>*******</admin-password><cert-common-name>azure-pcs.psecure.net</cert-common-name><cert-random-text>fdsfpisonvsfnms</cert-random-text><cert-organisation>Psecure Org</cert-organisation><config-download-url></config-download-url><config-data></config-data><auth-code-license></auth-code-license><enable-license-server>n</enable-license-server><accept-license-agreement>y</accept-license-agreement></pulse-config>")

os_disk {

caching = "ReadWrite"

storage_account_type = "Standard_LRS"

}

plan {

name = var.image_sku #pcs-byol

product = var.image_offer #pulse-connect-secure-vm

publisher = var.image_publisher #pulse-secure

}

source_image_reference {

publisher = var.image_publisher

offer = var.image_offer

sku = var.image_sku

version = var.image_version

}

boot_diagnostics {

storage_account_uri = data.azurerm_storage_account.storage_account.primary_blob_endpoint

}

}

ICS with 3 NICs

#Terraform version

terraform {

required_version = ">= v0.12.24"

}

#Provider version

provider "azurerm" {

version = ">= 2.0.0"

features {}

}

#Data sources

data "azurerm_storage_account" "storage_account" {

name = var.storage_account

resource_group_name = var.resource_group

}

#Internal Port Subnet

data "azurerm_subnet" "pcs_int_port_subnet" {

name = var.subnet_map["pcs_int_port"]["name"]

virtual_network_name = var.vnet

resource_group_name = var.resource_group

}

#External Port Subnet

data "azurerm_subnet" "pcs_ext_port_subnet" {

name = var.subnet_map["pcs_ext_port"]["name"]

virtual_network_name = var.vnet

resource_group_name = var.resource_group

}

#Mangement Port Subnet

data "azurerm_subnet" "pcs_mgmt_port_subnet" {

name = var.subnet_map["pcs_mgmt_port"]["name"]

virtual_network_name = var.vnet

resource_group_name = var.resource_group

}

#Data sources for Security Groups

data "azurerm_network_security_group" "nsg_pcs_int_port" {

name = var.security_group_map["pcs_int_port"]

resource_group_name = var.resource_group

}

data "azurerm_network_security_group" "nsg_pcs_ext_port" {

name = var.security_group_map["pcs_ext_port"]

resource_group_name = var.resource_group

}

data "azurerm_network_security_group" "nsg_pcs_mgmt_port" {

name = var.security_group_map["pcs_mgmt_port"]

resource_group_name = var.resource_group

}

data "azurerm_network_security_group" "nsg_backend_svr" {

name = var.security_group_map["backend_svr"]

resource_group_name = var.resource_group

}

#Local variables

locals {

security_group_id_map = {

"pcs_int_port" = data.azurerm_network_security_group.nsg_pcs_int_port.id,

"pcs_ext_port" = data.azurerm_network_security_group.nsg_pcs_ext_port.id,

"pcs_mgmt_port" = data.azurerm_network_security_group.nsg_pcs_mgmt_port.id,

"backend_svr" = data.azurerm_network_security_group.nsg_backend_svr.id,

}

subnet_id_map = {

"pcs_int_port" = data.azurerm_subnet.pcs_int_port_subnet.id

"pcs_ext_port" = data.azurerm_subnet.pcs_ext_port_subnet.id

"pcs_mgmt_port" = data.azurerm_subnet.pcs_mgmt_port_subnet.id

}

}

#Create a Resource Group

resource "azurerm_resource_group" "rg_for_pcs_instance" {

name = "rg-${var.instance_name}"

location = var.location

}

#Create Internal Port

resource "azurerm_network_interface" "pcs_int_port" {

name = "pcs-int-port"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

ip_configuration {

name = "pcs-int-port-ip"

#subnet_id = "${azurerm_subnet.intsubnet.id}"

subnet_id = local.subnet_id_map["pcs_int_port"]

private_ip_address_allocation = "Dynamic"

private_ip_address_version = "IPv4" #or IPv6. IPv6 is not supported on Azure yet

}

#when set to true, Azure allows this interface to send traffic with source IP other than its own IP

#this is needed for Pulse Client usecase

enable_ip_forwarding = "true" #default is false

#The (relative) DNS Name used for internal communications between Virtual Machines in the same Virtual Network

#internal_dns_name_label = "dns-name"

}

#Associate Security Group to Internal Port

resource "azurerm_network_interface_security_group_association" "nsg_asso_pcs_int_port" {

network_interface_id = azurerm_network_interface.pcs_int_port.id

network_security_group_id = local.security_group_id_map["pcs_int_port"]

}

#Create External Port

resource "azurerm_network_interface" "pcs_ext_port" {

name = "pcs-ext-port"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

ip_configuration {

name = "pcs-ext-port-ip"

#subnet_id = "${azurerm_subnet.intsubnet.id}"

subnet_id = local.subnet_id_map["pcs_ext_port"]

private_ip_address_allocation = "Dynamic"

private_ip_address_version = "IPv4" #or IPv6. IPv6 is not supported on Azure yet

#assign public IP for the pcs_ext_port

public_ip_address_id = azurerm_public_ip.ext_port_public_ip.id

}

}

#Associate Security Group to External Port

resource "azurerm_network_interface_security_group_association" "nsg_asso_pcs_ext_port" {

network_interface_id = azurerm_network_interface.pcs_ext_port.id

network_security_group_id = local.security_group_id_map["pcs_ext_port"]

}

#Create Management Port

resource "azurerm_network_interface" "pcs_mgmt_port" {

name = "pcs-mgmt-port"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

ip_configuration {

name = "pcs-mgmt-port-ip"

subnet_id = local.subnet_id_map["pcs_mgmt_port"]

private_ip_address_allocation = "Dynamic"

private_ip_address_version = "IPv4" #or IPv6. IPv6 is not supported on Azure yet

#assign public IP for the pcs_mgmt_port

public_ip_address_id = azurerm_public_ip.mgmt_port_public_ip.id

}

}

#Associate Security Group to External Port

resource "azurerm_network_interface_security_group_association" "nsg_asso_pcs_mgmt_port" {

network_interface_id = azurerm_network_interface.pcs_mgmt_port.id

network_security_group_id = local.security_group_id_map["pcs_mgmt_port"]

}

#Create a Public IP for External Port

resource "azurerm_public_ip" "ext_port_public_ip" {

name = "pcs-ext-port-public-ip"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

allocation_method = "Static"

#domain_name_label = var.pcs_ext_port_hostname

}

#Create a Public IP for Managment Port

resource "azurerm_public_ip" "mgmt_port_public_ip" {

name = "pcs-mgmt-port-public-ip"

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name

allocation_method = "Static"

#domain_name_label = var.pcs_mgmt_port_hostname

}

#accept the terms using az vm image terms accept --urn pulse-secure:pulse-connect-secure-vm:pcs-byol:9.1.1505

#substitute 9.1.1505 with the version you are trying to installe

#this command has to be run only once for a version

#hence commenting the azurerm_marketplace_agreement block

#resource "azurerm_marketplace_agreement" "pcs_agreement" {

# publisher = var.image_publisher #pulse-secure

# offer = var.image_offer #pulse-connect-secure-vm

# plan = var.image_sku #pcs-byol

#}

#Create an instance on Azure

resource "azurerm_linux_virtual_machine" "pcs_instance" {

name = var.instance_name

location = var.location

resource_group_name = azurerm_resource_group.rg_for_pcs_instance.name #all resources belonging to this VM will be stored in this resource group

#vm_size = "Standard_B1s"

size = "Standard_DS3_v2"

#availability zone

#zone = "1" #create in availability zone 1 in westus2 region, this is for resiliency

network_interface_ids = [ azurerm_network_interface.pcs_int_port.id, azurerm_network_interface.pcs_ext_port.id, azurerm_network_interface.pcs_mgmt_port.id]

admin_username = "adminuser"

admin_ssh_key {

username = "adminuser"

public_key = var.os_profile_ssh_key_map["public_key"]

}

#custom-data - used for initial config of ICS

custom_data = base64encode("<pulse-config><primary-dns>8.8.8.8</primary-dns><secondary-dns>8.8.8.9</secondary-dns><wins-server>1.1.1.1</wins-server><dns-domain>pcsqa.psecure.net</dns-domain><admin-username>admindb</admin-username><admin-password>*******</admin-password><cert-common-name>azure-pcs.psecure.net</cert-common-name><cert-random-text>fdsfpisonvsfnms</cert-random-text><cert-organisation>Psecure Org</cert-organisation><config-download-url></config-download-url><config-data></config-data><auth-code-license></auth-code-license><enable-license-server>n</enable-license-server><accept-license-agreement>y</accept-license-agreement></pulse-config>")

os_disk {

caching = "ReadWrite"

storage_account_type = "Standard_LRS"

}

plan {

name = var.image_sku #ics-byol

product = var.image_offer #ivanti-connect-secure-vm

publisher = var.image_publisher #ivanti

}

source_image_reference {

publisher = var.image_publisher

offer = var.image_offer

sku = var.image_sku

version = var.image_version

}

boot_diagnostics {

storage_account_uri = data.azurerm_storage_account.storage_account.primary_blob_endpoint

}

}

Variables

variable region {

description = "The region where the virtual network is created."

default = "westus2"

}

variable location {

description = "The region where the virtual network is created."

default = "westus2"

}

variable zone {

description = "availability zone where the PSA-V needs to be created"

default = "1"

}

#variable zone_1 {

# description = "availability zone-1 where the PSA-V needs to be created"

# default = ""

#}

#variable zone_2 {

# description = "availability zone-2 where the PSA-V needs to be created"

# default = ""

#}

variable resource_group {

description = "The name of your Azure Resource Group where the common resources such as vnet, subnets, security groups need to be created"

default = "rg-westus2-sulthan4"

}

variable storage_account {

description = "The name of your Azure Resource Group where the resources need to be created"

default = "storagewestus2sulthan4"

}

variable vnet {

description = "The name of your Azure Virtual Network under which subnets need to be created"

default = "vnet1-westus2"

}

variable subnet_map {

description = "customise the names of the subnet for Internal, External and Management Ports for zones(zone-1 and zone-2)"

type = map

default = {

"pcs_int_port" = {

"name" = "subnet-pcs-int-port"

"cidr" = "10.11.1.0/24"

}

"pcs_ext_port" = {

"name" = "subnet-pcs-ext-port"

"cidr" = "10.11.2.0/24"

}

"pcs_mgmt_port" = {

"name" = "subnet-pcs-mgmt-port"

"cidr" = "10.11.3.0/24"

}

"pcs_tunnel_subnet" = {

"name" = "subnet-pcs-tunnel-subnet"

"cidr" = "10.11.4.0/24"

}

}

}

variable security_group_map {

description = "customise the names of the network security group for Internal, External and Management Ports"

type = map

default = {

"pcs_int_port" = "sg-pcs-int-port",

"pcs_ext_port" = "sg-pcs-ext-port",

"pcs_mgmt_port" = "sg-pcs-mgmt-port",

"backend_svr" = "sg-backend-svr",

}

}

variable image_name {

description = "name of the Azure image in storage blob to be used for creating a new instance"

#default = "9.1R1_RC_Prod"

default = "Pulse Connect Secure -BYOL 2 NIC"

#default = "Pulse Connect Secure - BYOL 3 NIC"

}

variable os_profile_ssh_key_map {

type = map

default = {

#"path" = "/home/sulthan3/.ssh/authorized_keys",

"public_key" = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0MoRMdku5GQAKkOmfRzey5MNY9AsDHUXAtfIVvsShNxWXv4t43XjeOT6XhutzU2isYuhFteoA43nSnQ/kYJumO0TRi+cYQdz/KZohhlNcZqQMnlGaQF/ksjjWBSdulcSIRUv1rnEWaygU6VP3KXMAhrPR7710ReSdpth3HYJHROtFT8wFOaZUTwpi7Kjqc3h1q/IjNfe0rdSpyLdaK4XsOEYzRbk7mxddH/VHf+WNTvH2tgtkdMf+cQIMVj40W0aFbZp9bXZY3g2sotIZPViBzyMPaPkCcBm07ZiFFCjx7qUzqLk+IOrOTQNaTbsb3TFsKzKpiYXODRtOoGVXwjtD [email protected]"

}

}

variable "pcs_vm_size" {

# Recommended Sizes

# * Standard_F4s - PSA5K

# * Standard_F8s - PSA7K

description = "Specifies the size of the virtual machine."

default = "Standard_F4s"

}

variable "server_vm_size" {

description = "Specifies the size of the virtual machine."

default = "Standard_F4s"

}

variable "image_publisher" {

description = "Name of the publisher of the image (az vm image list)"

default = "pulse-secure"

}

variable "image_offer" {

description = "Name of the offer (az vm image list)"

default = "pulse-connect-secure-vm"

}

variable "image_sku" {

description = "Image SKU to apply (az vm image list)"

default = "pcs-byol"

}

variable "image_version" {

description = "Version of the image to apply (az vm image list)"

default = "9.13.3535"

}

variable instance_type {

default = "Standard_DS2_v2"

}

variable instance_name {

default = "az3nic1"

}

variable instance_name_1 {

default = "pcsaznod1"

}

variable instance_name_2 {

default = "pcsaznod2"

}

variable cpu_core_count {

default = "4"

}

variable memory_size {

default = "8"

}

variable eni_amount {

default = "2"

}

variable oss_bucket {

default = ""

}

variable instance_charge_type {

default = "PostPaid"

}