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"
}