Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NSG Update #17

Merged
merged 12 commits into from
Oct 20, 2017
161 changes: 115 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,75 +3,144 @@ Deploys 1+ Virtual Machines to your provided VNet

This Terraform module deploys Virtual Machines in Azure with the following characteristics:

- Ability to specify a simple string to get the latest marketplace image using `var.vm_os_simple`
- All VMs use managed disks
- Network Security Group (NSG) created and only if `var.remote_port` specified, then remote access rule created and opens this port to all nics
- Ability to specify a simple string to get the [latest marketplace image](https://docs.microsoft.com/cli/azure/vm/image?view=azure-cli-latest) using `var.vm_os_simple`
- All VMs use [managed disks](https://azure.microsoft.com/services/managed-disks/)
- Network Security Group (NSG) created with a single remote access rule which opens `var.remote_port` port or auto calculated port number if using `var.vm_os_simple` to all nics
- VM nics attached to a single virtual network subnet of your choice (new or existing) via `var.vnet_subnet_id`.
- Public IP is created and attached only to the first VM's nic. Once into this VM, connection can be make to the other vms using the private ip on the VNet.
- Control the number of Public IP addresses assigned to VMs via `var.nb_public_ip`. Create and attach one Public IP per VM up to the number of VMs or create NO public IPs via setting `var.nb_public_ip` to `0`.

> Note: Terraform module registry is incorrect in the number of required parameters since it only deems required based on variables with non-existent values. The actual minimum required variables depends on the configuration and is specified below in the usage.

Usage
Simple Usage
-----

Provisions 2 Windows 2016 Datacenter Server VMs using `vm_os_simple` to a new VNet and opens up port 3389 for RDP access:
This contains the bare minimum options to be configured for the VM to be provisioned. The entire code block provisions a Windows and a Linux VM, but feel free to delete one or the other and corresponding outputs. The outputs are also not necessary to provision, but included to make it convenient to know the address to connect to the VMs after provisioning completes.

Provisions an Ubuntu Server 16.04-LTS VM and a Windows 2016 Datacenter Server VM using `vm_os_simple` to a new VNet and opens up ports 22 for SSH and 3389 for RDP access via the attached public IP to each VM. All resources are provisioned into the default resource group called `terraform-compute`. The Ubuntu Server will use the ssh key found in the default location `~/.ssh/id_rsa.pub`.

```hcl
module "mycompute" {
source = "Azure/compute/azurerm"
resource_group_name = "mycompute"
location = "East US 2"
admin_password = "ComplxP@ssw0rd!"
vm_os_simple = "WindowsServer"
public_ip_dns = "mywinsrv252"
remote_port = "3389"
nb_instances = 2
vnet_subnet_id = "${module.network.vnet_subnets[0]}"
}

module "network" {
source = "Azure/network/azurerm"
location = "East US 2"
resource_group_name = "mycompute"
}

output "vm_public_name"{
value = "${module.mycompute.public_ip_dns_name}"
}

output "vm_public_ip" {
value = "${module.mycompute.public_ip_address}"
}

output "vm_private_ips" {
value = "${module.mycompute.network_interface_private_ip}"
}
module "linuxservers" {
source = "Azure/compute/azurerm"
location = "West US 2"
vm_os_simple = "UbuntuServer"
public_ip_dns = ["linsimplevmips"] // change to a unique name per datacenter region
vnet_subnet_id = "${module.network.vnet_subnets[0]}"
}

module "windowsservers" {
source = "Azure/compute/azurerm"
location = "West US 2"
vm_hostname = "mywinvm" // line can be removed if only one VM module per resource group
admin_password = "ComplxP@ssw0rd!"
vm_os_simple = "WindowsServer"
public_ip_dns = ["winsimplevmips"] // change to a unique name per datacenter region
vnet_subnet_id = "${module.network.vnet_subnets[0]}"
}

module "network" {
source = "Azure/network/azurerm"
location = "West US 2"
resource_group_name = "terraform-compute"
}

output "linux_vm_public_name"{
value = "${module.linuxservers.public_ip_dns_name}"
}

output "windows_vm_public_name"{
value = "${module.windowsservers.public_ip_dns_name}"
}
```
Provisions 2 Ubuntu 14.04 Server VMs using `vm_os_publisher`, `vm_os_offer` and `vm_os_sku` to a new VNet and opens up port 22 for SSH access with ~/.ssh/id_rsa.pub :

Advanced Usage
-----

The following example illustrates some of the configuration options available to deploy a virtual machine. Feel free to remove the Linux or Windows modules and corresponding outputs.

More specifically this provisions:

1 - New vnet for all vms

2 - Ubuntu 14.04 Server VMs using `vm_os_publisher`, `vm_os_offer` and `vm_os_sku` which is configured with:

- No public IP assigned, so access can only happen through another machine on the vnet.
- Opens up port 22 for SSH access with the default ~/.ssh/id_rsa.pub key
- Boot diagnostics is enabled.
- Additional tags are added to the resource group.
- OS disk is deleted upon deletion of the VM
- Add one 64GB premium managed data disk

2 - Windows Server 2012 R2 VMs using `vm_os_publisher`, `vm_os_offer` and `vm_os_sku` which is configured with:

- Two Public IP addresses (one for each VM)
- Opens up port 3389 for RDP access using the password as shown

```hcl
module "mycompute2" {
module "linuxservers" {
source = "Azure/compute/azurerm"
resource_group_name = "mycompute2"
location = "westus"
public_ip_dns = "myubuntuservers225"
resource_group_name = "terraform-advancedvms"
location = "westus2"
vm_hostname = "mylinuxvm"
nb_public_ip = "0"
remote_port = "22"
nb_instances = 2
nb_instances = "2"
vm_os_publisher = "Canonical"
vm_os_offer = "UbuntuServer"
vm_os_sku = "14.04.2-LTS"
vnet_subnet_id = "${module.network.vnet_subnets[0]}"
boot_diagnostics = "true"
delete_os_disk_on_termination = "true"
data_disk = "true"
data_disk_size_gb = "64"
data_sa_type = "Premium_LRS"

tags = {
environment = "dev"
costcenter = "it"
}
}
}

module "windowsservers" {
source = "Azure/compute/azurerm"
resource_group_name = "terraform-advancedvms"
location = "westus2"
vm_hostname = "mywinvm"
admin_password = "ComplxP@ssw0rd!"
public_ip_dns = ["winterravmip","winterravmip1"]
nb_public_ip = "2"
remote_port = "3389"
nb_instances = "2"
vm_os_publisher = "MicrosoftWindowsServer"
vm_os_offer = "WindowsServer"
vm_os_sku = "2012-R2-Datacenter"
vm_size = "Standard_DS2_V2"
vnet_subnet_id = "${module.network.vnet_subnets[0]}"
}

module "network" {
source = "Azure/network/azurerm"
location = "westus"
resource_group_name = "mycompute2"
}
source = "Azure/network/azurerm"
location = "westus2"
resource_group_name = "terraform-advancedvms"
}

output "linux_vm_private_ips" {
value = "${module.linuxservers.network_interface_private_ip}"
}

output "windows_vm_public_name"{
value = "${module.windowsservers.public_ip_dns_name}"
}

output "windows_vm_public_ip" {
value = "${module.windowsservers.public_ip_address}"
}

output "windows_vm_private_ips" {
value = "${module.windowsservers.network_interface_private_ip}"
}

```

Authors
=======
Originally created by [David Tesar](http://github.com/dtzar)
Expand Down
12 changes: 8 additions & 4 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ provider "azurerm" {
version = "~> 0.2.2"
}

provider "random" {
version = "~> 1.0"
}

module "os" {
source = "os"
vm_os_simple = "${var.vm_os_simple}"
Expand Down Expand Up @@ -206,7 +210,7 @@ resource "azurerm_virtual_machine" "vm-windows-with-datadisk" {
}

resource "azurerm_availability_set" "vm" {
name = "${var.vm_hostname}avset"
name = "${var.vm_hostname}-avset"
location = "${azurerm_resource_group.vm.location}"
resource_group_name = "${azurerm_resource_group.vm.name}"
platform_fault_domain_count = 2
Expand All @@ -224,19 +228,19 @@ resource "azurerm_public_ip" "vm" {
}

resource "azurerm_network_security_group" "vm" {
name = "${var.vm_hostname}-nsg"
name = "${var.vm_hostname}-${coalesce(var.remote_port,module.os.calculated_remote_port)}-nsg"
location = "${azurerm_resource_group.vm.location}"
resource_group_name = "${azurerm_resource_group.vm.name}"

security_rule {
name = "allow_remote_in_all"
name = "allow_remote_${coalesce(var.remote_port,module.os.calculated_remote_port)}_in_all"
description = "Allow remote protocol in from all locations"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "${var.remote_port}"
destination_port_range = "${coalesce(var.remote_port,module.os.calculated_remote_port)}"
source_address_prefix = "*"
destination_address_prefix = "*"
}
Expand Down
3 changes: 3 additions & 0 deletions os/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ output "calculated_value_os_sku" {
value = "${element(split(",", lookup(var.standard_os, var.vm_os_simple, "")), 2)}"
}

output "calculated_remote_port" {
value = "${element(split(",", lookup(var.standard_os, var.vm_os_simple, "")), 0) == "MicrosoftWindowsServer" ? 3389 : 22}"
}
2 changes: 0 additions & 2 deletions os/variables.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@

variable "vm_os_simple" {
default = ""
}


# Definition of the standard OS with "SimpleName" = "publisher,offer,sku"
variable "standard_os" {
default = {
Expand Down
4 changes: 2 additions & 2 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
variable "resource_group_name" {
description = "The name of the resource group in which the resources will be created"
default = "compute"
default = "terraform-compute"
}

variable "location" {
Expand Down Expand Up @@ -95,7 +95,7 @@ variable "tags" {
}
variable "public_ip_address_allocation" {
description = "Defines how an IP address is assigned. Options are Static or Dynamic."
default = "static"
default = "dynamic"
}

variable "nb_public_ip" {
Expand Down