Skip to content

Commit

Permalink
Initial Release (#1)
Browse files Browse the repository at this point in the history
* full functionality w linux or windows
* managed disks
  • Loading branch information
dtzar authored Sep 2, 2017
1 parent 019a98d commit 0f231b5
Show file tree
Hide file tree
Showing 8 changed files with 467 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
# Variable files
terraform.tfvars

### https://raw.github.com/github/gitignore/abad92dac5a4306f72242dae3bca6e277bce3615/Terraform.gitignore

# Compiled files
*.tfstate
*.tfstate.backup

# Module directory
.terraform/


### https://raw.github.com/github/gitignore/abad92dac5a4306f72242dae3bca6e277bce3615/Global/Vim.gitignore

# swap
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
# session
Session.vim
# temporary
.netrwhist
*~
# auto-generated tag files
tags
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) Microsoft Corporation. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
120 changes: 120 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
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
- 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.

Module Input Variables
----------------------

- `resource_group_name` - The name of the resource group in which the resources will be created. - default `compute`
- `location` - The Azure location where the resources will be created.
- `vnet_subnet_id` - The subnet id of the virtual network where the virtual machines will reside.
- `public_ip_dns` - Optional globally unique per datacenter region domain name label to apply to the public ip address. e.g. thisvar.varlocation.cloudapp.azure.com
- `admin_password` - The password of the administrator account. The password must comply with the complexity requirements for Azure virtual machines.
- `ssh_key` - The path on the local machine of the ssh public key in the case of a Linux deployment. - default `~/.ssh/id_rsa.pub`
- `remote_port` - Tcp port number to enable remote access to the nics on the vms via a NSG rule. Set to blank to disable.
- `admin_username` - The name of the administrator to access the machines part of the virtual machine scale set. - default `azureuser`
- `storage_account_type` - Defines the type of storage account to be created. Valid options are Standard_LRS, Standard_ZRS, Standard_GRS, Standard_RAGRS, Premium_LRS. - default `Premium_LRS`
- `vm_size` - The initial size of the virtual machine that will be deployed. - default `Standard_DS1_V2`
- `nb_instances` - The number of instances that will be initially deployed in the virtual machine scale set. - default `1`
- `vm_hostname` - local name of the VM. - default `myvm`
- `vm_os_simple`- This variable allows to use a simple name to reference Linux or Windows operating systems. When used, you can ommit the `vm_os_publisher`, `vm_os_offer` and `vm_os_sku`. The supported values are: "UbuntuServer", "WindowsServer", "RHEL", "openSUSE-Leap", "CentOS", "Debian", "CoreOS" and "SLES".
- `vm_os_id` - The ID of the image that you want to deploy if you are using a custom image. When used, you can ommit the `vm_os_publisher`, `vm_os_offer` and `vm_os_sku`.
- `vm_os_publisher` - The name of the publisher of the image that you want to deploy, for example "Canonical" if you are not using the `vm_os_simple` or `vm_os_id` variables.
- `vm_os_offer` - The name of the offer of the image that you want to deploy, for example "UbuntuServer" if you are not using the `vm_os_simple` or `vm_os_id` variables.
- `vm_os_sku` - The sku of the image that you want to deploy, for example "14.04.2-LTS" if you are not using the `vm_os_simple` or `vm_os_id` variables.
- `vm_os_version` - The version of the image that you want to deploy. - default `latest`
- `public_ip_address_allocation` - Defines how an IP address is assigned. Options are Static or Dynamic. - default `static`
- `tags` - A map of the tags to use on the resources that are deployed with this module.

Usage
-----

Provisions 2 Windows 2016 Datacenter Server VMs using `vm_os_simple` to a new VNet and opens up port 3389 for RDP access:

```hcl
module "mycompute" {
source = "github.com/Azure/terraform-azurerm-compute"
resource_group_name = "mycompute"
location = "East US 2"
admin_password = ComplxP@ssw0rd!
vm_os_simple = "WindowsServer"
public_ip_dns = "mywindowsservers225"
remote_port = "3389"
nb_instances = 2
vnet_subnet_id = "${module.network.vnet_subnets[0]}"
}
module "network" {
source = "github.com/Azure/terraform-azurerm-network"
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}"
}
}
```
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 :

```hcl
module "mycompute2" {
source = "github.com/Azure/terraform-azurerm-compute"
resource_group_name = "mycompute2"
location = "westus"
public_ip_dns = "myubuntuservers225"
remote_port = "22"
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]}"
tags = {
environment = "dev"
costcenter = "it"
}
}
module "network" {
source = "github.com/Azure/terraform-azurerm-network"
location = "westus"
resource_group_name = "mycompute2"
}
```

Outputs
=======

- `vm_ids`- Virtual machine ids created
- `network_security_group_id` - id of the security group provisioned
- `network_interface_ids` - ids of the vm nics provisoned
- `network_interface_private_ip` - private ip addresses of the vm nics
- `public_ip_id` - id of the public ip address provisoned
- `public_ip_address` - The actual ip address allocated for the resource.
- `public_ip_dns_name` - fqdn to connect to the first vm provisioned.
- `availability_set_id` - id of the availability set where the vms are provisioned.

Authors
=======
Originally created by [David Tesar](http://github.com/dtzar)

License
=======

[MIT](LICENSE)
137 changes: 137 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
provider "azurerm" {
version = "~> 0.1"
}

module "os" {
source = "./os"
vm_os_simple = "${var.vm_os_simple}"
}

resource "azurerm_resource_group" "vm" {
name = "${var.resource_group_name}"
location = "${var.location}"
tags = "${var.tags}"
}

resource "azurerm_virtual_machine" "vm-linux" {
count = "${contains(list("${var.vm_os_simple}","${var.vm_os_offer}"), "WindowsServer") ? 0 : var.nb_instances}"
name = "${var.vm_hostname}${count.index}"
location = "${var.location}"
resource_group_name = "${azurerm_resource_group.vm.name}"
availability_set_id = "${azurerm_availability_set.vm.id}"
vm_size = "${var.vm_size}"
network_interface_ids = ["${element(azurerm_network_interface.vm.*.id, count.index)}"]

storage_image_reference {
id = "${var.vm_os_id}"
publisher = "${coalesce(var.vm_os_publisher, module.os.calculated_value_os_publisher)}"
offer = "${coalesce(var.vm_os_offer, module.os.calculated_value_os_offer)}"
sku = "${coalesce(var.vm_os_sku, module.os.calculated_value_os_sku)}"
version = "${var.vm_os_version}"
}

storage_os_disk {
name = "osdisk${count.index}"
create_option = "FromImage"
caching = "ReadWrite"
managed_disk_type = "${var.storage_account_type}"
}

os_profile {
computer_name = "${var.vm_hostname}"
admin_username = "${var.admin_username}"
admin_password = "${var.admin_password}"
}

os_profile_linux_config {

disable_password_authentication = true

ssh_keys {
path = "/home/${var.admin_username}/.ssh/authorized_keys"
key_data = "${file("${var.ssh_key}")}"
}
}
}

resource "azurerm_virtual_machine" "vm-windows" {
count = "${contains(list("${var.vm_os_simple}","${var.vm_os_offer}"), "WindowsServer") ? var.nb_instances : 0}"
name = "${var.vm_hostname}${count.index}"
location = "${var.location}"
resource_group_name = "${azurerm_resource_group.vm.name}"
availability_set_id = "${azurerm_availability_set.vm.id}"
vm_size = "${var.vm_size}"
network_interface_ids = ["${element(azurerm_network_interface.vm.*.id, count.index)}"]

storage_image_reference {
id = "${var.vm_os_id}"
publisher = "${coalesce(var.vm_os_publisher, module.os.calculated_value_os_publisher)}"
offer = "${coalesce(var.vm_os_offer, module.os.calculated_value_os_offer)}"
sku = "${coalesce(var.vm_os_sku, module.os.calculated_value_os_sku)}"
version = "${var.vm_os_version}"
}

storage_os_disk {
name = "osdisk${count.index}"
create_option = "FromImage"
caching = "ReadWrite"
managed_disk_type = "${var.storage_account_type}"
}

os_profile {
computer_name = "${var.vm_hostname}"
admin_username = "${var.admin_username}"
admin_password = "${var.admin_password}"
}
}

resource "azurerm_availability_set" "vm" {
name = "${var.vm_hostname}avset"
location = "${azurerm_resource_group.vm.location}"
resource_group_name = "${azurerm_resource_group.vm.name}"
platform_fault_domain_count = 2
platform_update_domain_count = 2
managed = true
}

resource "azurerm_public_ip" "vm" {
name = "${var.vm_hostname}-publicIP"
location = "${var.location}"
resource_group_name = "${azurerm_resource_group.vm.name}"
public_ip_address_allocation = "${var.public_ip_address_allocation}"
domain_name_label = "${var.public_ip_dns}"
}

resource "azurerm_network_security_group" "vm" {
name = "remote-access-nsg"
location = "${azurerm_resource_group.vm.location}"
resource_group_name = "${azurerm_resource_group.vm.name}"

security_rule {
name = "allow_remote_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}"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}

resource "azurerm_network_interface" "vm" {
count = "${var.nb_instances}"
name = "nic${count.index}"
location = "${azurerm_resource_group.vm.location}"
resource_group_name = "${azurerm_resource_group.vm.name}"
network_security_group_id = "${azurerm_network_security_group.vm.id}"

ip_configuration {
name = "ipconfig${count.index}"
subnet_id = "${var.vnet_subnet_id}"
private_ip_address_allocation = "Dynamic"
public_ip_address_id = "${count.index == 0 ? azurerm_public_ip.vm.id : ""}"
}
}
13 changes: 13 additions & 0 deletions os/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

output "calculated_value_os_publisher" {
value = "${element(split(",", lookup(var.standard_os, var.vm_os_simple, "")), 0)}"
}

output "calculated_value_os_offer" {
value = "${element(split(",", lookup(var.standard_os, var.vm_os_simple, "")), 1)}"
}

output "calculated_value_os_sku" {
value = "${element(split(",", lookup(var.standard_os, var.vm_os_simple, "")), 2)}"
}

19 changes: 19 additions & 0 deletions os/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

variable "vm_os_simple" {
default = ""
}


# Definition of the standard OS with "SimpleName" = "publisher,offer,sku"
variable "standard_os" {
default = {
"UbuntuServer" = "Canonical,UbuntuServer,16.04-LTS"
"WindowsServer" = "MicrosoftWindowsServer,WindowsServer,2016-Datacenter"
"RHEL" = "RedHat,RHEL,7.3"
"openSUSE-Leap" = "SUSE,openSUSE-Leap,42.2"
"CentOS" = "OpenLogic,CentOS,7.3"
"Debian" = "credativ,Debian,8"
"CoreOS" = "CoreOS,CoreOS,Stable"
"SLES" = "SUSE,SLES,12-SP2"
}
}
39 changes: 39 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
output "vm_ids" {
description = "Virtual machine ids created."
value = "${concat(azurerm_virtual_machine.vm-windows.*.id, azurerm_virtual_machine.vm-linux.*.id)}"
}

output "network_security_group_id" {
description = "id of the security group provisioned"
value = "${azurerm_network_security_group.vm.id}"
}

output "network_interface_ids" {
description = "ids of the vm nics provisoned."
value = "${azurerm_network_interface.vm.*.id}"
}

output "network_interface_private_ip"{
description = "private ip addresses of the vm nics"
value = "${azurerm_network_interface.vm.*.private_ip_address}"
}

output "public_ip_id" {
description = "id of the public ip address provisoned."
value = "${azurerm_public_ip.vm.id}"
}

output "public_ip_address" {
description = "The actual ip address allocated for the resource."
value = "${azurerm_public_ip.vm.ip_address}"
}

output "public_ip_dns_name" {
description = "fqdn to connect to the first vm provisioned."
value = "${azurerm_public_ip.vm.fqdn}"
}

output "availability_set_id" {
description = "id of the availability set where the vms are provisioned."
value = "${azurerm_availability_set.vm.id}"
}
Loading

0 comments on commit 0f231b5

Please sign in to comment.