Skip to content

Commit 0f231b5

Browse files
authored
Initial Release (#1)
* full functionality w linux or windows * managed disks
1 parent 019a98d commit 0f231b5

File tree

8 files changed

+467
-0
lines changed

8 files changed

+467
-0
lines changed

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
1+
# Variable files
2+
terraform.tfvars
3+
4+
### https://raw.github.com/github/gitignore/abad92dac5a4306f72242dae3bca6e277bce3615/Terraform.gitignore
5+
16
# Compiled files
27
*.tfstate
38
*.tfstate.backup
49

510
# Module directory
611
.terraform/
12+
13+
14+
### https://raw.github.com/github/gitignore/abad92dac5a4306f72242dae3bca6e277bce3615/Global/Vim.gitignore
15+
16+
# swap
17+
[._]*.s[a-w][a-z]
18+
[._]s[a-w][a-z]
19+
# session
20+
Session.vim
21+
# temporary
22+
.netrwhist
23+
*~
24+
# auto-generated tag files
25+
tags

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) Microsoft Corporation. All rights reserved.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE

README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
Deploys 1+ Virtual Machines to your provided VNet
2+
=================================================
3+
4+
This Terraform module deploys Virtual Machines in Azure with the following characteristics:
5+
6+
- Ability to specify a simple string to get the latest marketplace image using `var.vm_os_simple`
7+
- All VMs use managed disks
8+
- Network Security Group (NSG) created and only if `var.remote_port` specified, then remote access rule created and opens this port to all nics
9+
- VM nics attached to a single virtual network subnet of your choice (new or existing) via `var.vnet_subnet_id`.
10+
- 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.
11+
12+
Module Input Variables
13+
----------------------
14+
15+
- `resource_group_name` - The name of the resource group in which the resources will be created. - default `compute`
16+
- `location` - The Azure location where the resources will be created.
17+
- `vnet_subnet_id` - The subnet id of the virtual network where the virtual machines will reside.
18+
- `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
19+
- `admin_password` - The password of the administrator account. The password must comply with the complexity requirements for Azure virtual machines.
20+
- `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`
21+
- `remote_port` - Tcp port number to enable remote access to the nics on the vms via a NSG rule. Set to blank to disable.
22+
- `admin_username` - The name of the administrator to access the machines part of the virtual machine scale set. - default `azureuser`
23+
- `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`
24+
- `vm_size` - The initial size of the virtual machine that will be deployed. - default `Standard_DS1_V2`
25+
- `nb_instances` - The number of instances that will be initially deployed in the virtual machine scale set. - default `1`
26+
- `vm_hostname` - local name of the VM. - default `myvm`
27+
- `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".
28+
- `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`.
29+
- `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.
30+
- `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.
31+
- `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.
32+
- `vm_os_version` - The version of the image that you want to deploy. - default `latest`
33+
- `public_ip_address_allocation` - Defines how an IP address is assigned. Options are Static or Dynamic. - default `static`
34+
- `tags` - A map of the tags to use on the resources that are deployed with this module.
35+
36+
Usage
37+
-----
38+
39+
Provisions 2 Windows 2016 Datacenter Server VMs using `vm_os_simple` to a new VNet and opens up port 3389 for RDP access:
40+
41+
```hcl
42+
module "mycompute" {
43+
source = "github.com/Azure/terraform-azurerm-compute"
44+
resource_group_name = "mycompute"
45+
location = "East US 2"
46+
admin_password = ComplxP@ssw0rd!
47+
vm_os_simple = "WindowsServer"
48+
public_ip_dns = "mywindowsservers225"
49+
remote_port = "3389"
50+
nb_instances = 2
51+
vnet_subnet_id = "${module.network.vnet_subnets[0]}"
52+
}
53+
54+
module "network" {
55+
source = "github.com/Azure/terraform-azurerm-network"
56+
location = "East US 2"
57+
resource_group_name = "mycompute"
58+
}
59+
60+
output "vm_public_name"{
61+
value = "${module.mycompute.public_ip_dns_name}"
62+
}
63+
64+
output "vm_public_ip" {
65+
value = "${module.mycompute.public_ip_address}"
66+
}
67+
68+
output "vm_private_ips" {
69+
value = "${module.mycompute.network_interface_private_ip}"
70+
}
71+
}
72+
73+
```
74+
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 :
75+
76+
```hcl
77+
module "mycompute2" {
78+
source = "github.com/Azure/terraform-azurerm-compute"
79+
resource_group_name = "mycompute2"
80+
location = "westus"
81+
public_ip_dns = "myubuntuservers225"
82+
remote_port = "22"
83+
nb_instances = 2
84+
vm_os_publisher = "Canonical"
85+
vm_os_offer = "UbuntuServer"
86+
vm_os_sku = "14.04.2-LTS"
87+
vnet_subnet_id = "${module.network.vnet_subnets[0]}"
88+
tags = {
89+
environment = "dev"
90+
costcenter = "it"
91+
}
92+
}
93+
module "network" {
94+
source = "github.com/Azure/terraform-azurerm-network"
95+
location = "westus"
96+
resource_group_name = "mycompute2"
97+
}
98+
99+
```
100+
101+
Outputs
102+
=======
103+
104+
- `vm_ids`- Virtual machine ids created
105+
- `network_security_group_id` - id of the security group provisioned
106+
- `network_interface_ids` - ids of the vm nics provisoned
107+
- `network_interface_private_ip` - private ip addresses of the vm nics
108+
- `public_ip_id` - id of the public ip address provisoned
109+
- `public_ip_address` - The actual ip address allocated for the resource.
110+
- `public_ip_dns_name` - fqdn to connect to the first vm provisioned.
111+
- `availability_set_id` - id of the availability set where the vms are provisioned.
112+
113+
Authors
114+
=======
115+
Originally created by [David Tesar](http://github.com/dtzar)
116+
117+
License
118+
=======
119+
120+
[MIT](LICENSE)

main.tf

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
provider "azurerm" {
2+
version = "~> 0.1"
3+
}
4+
5+
module "os" {
6+
source = "./os"
7+
vm_os_simple = "${var.vm_os_simple}"
8+
}
9+
10+
resource "azurerm_resource_group" "vm" {
11+
name = "${var.resource_group_name}"
12+
location = "${var.location}"
13+
tags = "${var.tags}"
14+
}
15+
16+
resource "azurerm_virtual_machine" "vm-linux" {
17+
count = "${contains(list("${var.vm_os_simple}","${var.vm_os_offer}"), "WindowsServer") ? 0 : var.nb_instances}"
18+
name = "${var.vm_hostname}${count.index}"
19+
location = "${var.location}"
20+
resource_group_name = "${azurerm_resource_group.vm.name}"
21+
availability_set_id = "${azurerm_availability_set.vm.id}"
22+
vm_size = "${var.vm_size}"
23+
network_interface_ids = ["${element(azurerm_network_interface.vm.*.id, count.index)}"]
24+
25+
storage_image_reference {
26+
id = "${var.vm_os_id}"
27+
publisher = "${coalesce(var.vm_os_publisher, module.os.calculated_value_os_publisher)}"
28+
offer = "${coalesce(var.vm_os_offer, module.os.calculated_value_os_offer)}"
29+
sku = "${coalesce(var.vm_os_sku, module.os.calculated_value_os_sku)}"
30+
version = "${var.vm_os_version}"
31+
}
32+
33+
storage_os_disk {
34+
name = "osdisk${count.index}"
35+
create_option = "FromImage"
36+
caching = "ReadWrite"
37+
managed_disk_type = "${var.storage_account_type}"
38+
}
39+
40+
os_profile {
41+
computer_name = "${var.vm_hostname}"
42+
admin_username = "${var.admin_username}"
43+
admin_password = "${var.admin_password}"
44+
}
45+
46+
os_profile_linux_config {
47+
48+
disable_password_authentication = true
49+
50+
ssh_keys {
51+
path = "/home/${var.admin_username}/.ssh/authorized_keys"
52+
key_data = "${file("${var.ssh_key}")}"
53+
}
54+
}
55+
}
56+
57+
resource "azurerm_virtual_machine" "vm-windows" {
58+
count = "${contains(list("${var.vm_os_simple}","${var.vm_os_offer}"), "WindowsServer") ? var.nb_instances : 0}"
59+
name = "${var.vm_hostname}${count.index}"
60+
location = "${var.location}"
61+
resource_group_name = "${azurerm_resource_group.vm.name}"
62+
availability_set_id = "${azurerm_availability_set.vm.id}"
63+
vm_size = "${var.vm_size}"
64+
network_interface_ids = ["${element(azurerm_network_interface.vm.*.id, count.index)}"]
65+
66+
storage_image_reference {
67+
id = "${var.vm_os_id}"
68+
publisher = "${coalesce(var.vm_os_publisher, module.os.calculated_value_os_publisher)}"
69+
offer = "${coalesce(var.vm_os_offer, module.os.calculated_value_os_offer)}"
70+
sku = "${coalesce(var.vm_os_sku, module.os.calculated_value_os_sku)}"
71+
version = "${var.vm_os_version}"
72+
}
73+
74+
storage_os_disk {
75+
name = "osdisk${count.index}"
76+
create_option = "FromImage"
77+
caching = "ReadWrite"
78+
managed_disk_type = "${var.storage_account_type}"
79+
}
80+
81+
os_profile {
82+
computer_name = "${var.vm_hostname}"
83+
admin_username = "${var.admin_username}"
84+
admin_password = "${var.admin_password}"
85+
}
86+
}
87+
88+
resource "azurerm_availability_set" "vm" {
89+
name = "${var.vm_hostname}avset"
90+
location = "${azurerm_resource_group.vm.location}"
91+
resource_group_name = "${azurerm_resource_group.vm.name}"
92+
platform_fault_domain_count = 2
93+
platform_update_domain_count = 2
94+
managed = true
95+
}
96+
97+
resource "azurerm_public_ip" "vm" {
98+
name = "${var.vm_hostname}-publicIP"
99+
location = "${var.location}"
100+
resource_group_name = "${azurerm_resource_group.vm.name}"
101+
public_ip_address_allocation = "${var.public_ip_address_allocation}"
102+
domain_name_label = "${var.public_ip_dns}"
103+
}
104+
105+
resource "azurerm_network_security_group" "vm" {
106+
name = "remote-access-nsg"
107+
location = "${azurerm_resource_group.vm.location}"
108+
resource_group_name = "${azurerm_resource_group.vm.name}"
109+
110+
security_rule {
111+
name = "allow_remote_in_all"
112+
description = "Allow remote protocol in from all locations"
113+
priority = 100
114+
direction = "Inbound"
115+
access = "Allow"
116+
protocol = "Tcp"
117+
source_port_range = "*"
118+
destination_port_range = "${var.remote_port}"
119+
source_address_prefix = "*"
120+
destination_address_prefix = "*"
121+
}
122+
}
123+
124+
resource "azurerm_network_interface" "vm" {
125+
count = "${var.nb_instances}"
126+
name = "nic${count.index}"
127+
location = "${azurerm_resource_group.vm.location}"
128+
resource_group_name = "${azurerm_resource_group.vm.name}"
129+
network_security_group_id = "${azurerm_network_security_group.vm.id}"
130+
131+
ip_configuration {
132+
name = "ipconfig${count.index}"
133+
subnet_id = "${var.vnet_subnet_id}"
134+
private_ip_address_allocation = "Dynamic"
135+
public_ip_address_id = "${count.index == 0 ? azurerm_public_ip.vm.id : ""}"
136+
}
137+
}

os/outputs.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
output "calculated_value_os_publisher" {
3+
value = "${element(split(",", lookup(var.standard_os, var.vm_os_simple, "")), 0)}"
4+
}
5+
6+
output "calculated_value_os_offer" {
7+
value = "${element(split(",", lookup(var.standard_os, var.vm_os_simple, "")), 1)}"
8+
}
9+
10+
output "calculated_value_os_sku" {
11+
value = "${element(split(",", lookup(var.standard_os, var.vm_os_simple, "")), 2)}"
12+
}
13+

os/variables.tf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
variable "vm_os_simple" {
3+
default = ""
4+
}
5+
6+
7+
# Definition of the standard OS with "SimpleName" = "publisher,offer,sku"
8+
variable "standard_os" {
9+
default = {
10+
"UbuntuServer" = "Canonical,UbuntuServer,16.04-LTS"
11+
"WindowsServer" = "MicrosoftWindowsServer,WindowsServer,2016-Datacenter"
12+
"RHEL" = "RedHat,RHEL,7.3"
13+
"openSUSE-Leap" = "SUSE,openSUSE-Leap,42.2"
14+
"CentOS" = "OpenLogic,CentOS,7.3"
15+
"Debian" = "credativ,Debian,8"
16+
"CoreOS" = "CoreOS,CoreOS,Stable"
17+
"SLES" = "SUSE,SLES,12-SP2"
18+
}
19+
}

outputs.tf

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
output "vm_ids" {
2+
description = "Virtual machine ids created."
3+
value = "${concat(azurerm_virtual_machine.vm-windows.*.id, azurerm_virtual_machine.vm-linux.*.id)}"
4+
}
5+
6+
output "network_security_group_id" {
7+
description = "id of the security group provisioned"
8+
value = "${azurerm_network_security_group.vm.id}"
9+
}
10+
11+
output "network_interface_ids" {
12+
description = "ids of the vm nics provisoned."
13+
value = "${azurerm_network_interface.vm.*.id}"
14+
}
15+
16+
output "network_interface_private_ip"{
17+
description = "private ip addresses of the vm nics"
18+
value = "${azurerm_network_interface.vm.*.private_ip_address}"
19+
}
20+
21+
output "public_ip_id" {
22+
description = "id of the public ip address provisoned."
23+
value = "${azurerm_public_ip.vm.id}"
24+
}
25+
26+
output "public_ip_address" {
27+
description = "The actual ip address allocated for the resource."
28+
value = "${azurerm_public_ip.vm.ip_address}"
29+
}
30+
31+
output "public_ip_dns_name" {
32+
description = "fqdn to connect to the first vm provisioned."
33+
value = "${azurerm_public_ip.vm.fqdn}"
34+
}
35+
36+
output "availability_set_id" {
37+
description = "id of the availability set where the vms are provisioned."
38+
value = "${azurerm_availability_set.vm.id}"
39+
}

0 commit comments

Comments
 (0)