Skip to content

Commit

Permalink
Merge pull request #641 from rguthriemsft/pull-request-635
Browse files Browse the repository at this point in the history
feat: adding Virtual Machine module
  • Loading branch information
yorinasub17 authored Oct 22, 2020
2 parents d6f05fc + b388cb6 commit 5fa1994
Show file tree
Hide file tree
Showing 15 changed files with 1,113 additions and 91 deletions.
2 changes: 1 addition & 1 deletion examples/azure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ go build terraform_azure_*_test.go

## Review Environment Variables

As part of configuring terraform for Azure, we'll want to check that we have set the appropriate [credentials](https://docs.microsoft.com/en-us/azure/terraform/terraform-install-configure?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fterraform%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json#set-up-terraform-access-to-azure) and also that we set the [environment variables](https://docs.microsoft.com/en-us/azure/terraform/terraform-install-configure?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fterraform%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json#configure-terraform-environment-variables) on the testing host.
As part of configuring terraform for Azure, we'll want to check that we have set the appropriate [credentials](https://docs.microsoft.com/azure/terraform/terraform-install-configure?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fterraform%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json#set-up-terraform-access-to-azure) and also that we set the [environment variables](https://docs.microsoft.com/azure/terraform/terraform-install-configure?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fterraform%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json#configure-terraform-environment-variables) on the testing host.

```bash
export ARM_CLIENT_ID=your_app_id
Expand Down
44 changes: 22 additions & 22 deletions examples/azure/terraform-azure-example/main.tf
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AN AZURE VIRTUAL MACHINE
# This is a basic example of how to deploy an Azure Virtual Machine with the minimum network resources.
# This is an example of how to deploy an Azure Virtual Machine with the minimum network resources.
# ---------------------------------------------------------------------------------------------------------------------
# See test/azure/terraform_azure_example_test.go for how to write automated tests for this code.
# ---------------------------------------------------------------------------------------------------------------------

provider "azurerm" {
version = "~> 2.29"
features {}
}


# ---------------------------------------------------------------------------------------------------------------------
# PIN TERRAFORM VERSION TO >= 0.12
# The examples have been upgraded to 0.12 syntax
Expand All @@ -21,26 +23,12 @@ terraform {
required_version = ">= 0.12.26"
}

# ---------------------------------------------------------------------------------------------------------------------
# GENERATE RANDOMIZATION STRING
# This random password is used to improve test security
# ---------------------------------------------------------------------------------------------------------------------

resource "random_password" "main" {
length = 16
override_special = "-_%@"
min_upper = "1"
min_lower = "1"
min_numeric = "1"
min_special = "1"
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY A RESOURCE GROUP
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_resource_group" "main" {
name = "${var.prefix}-resources"
name = "terratest-rg-${var.postfix}"
location = "East US"
}

Expand All @@ -49,21 +37,21 @@ resource "azurerm_resource_group" "main" {
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_virtual_network" "main" {
name = "${var.prefix}-network"
name = "vnet-${var.postfix}"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
}

resource "azurerm_subnet" "internal" {
name = "internal"
name = "subnet-${var.postfix}"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefix = "10.0.17.0/24"
address_prefixes = ["10.0.17.0/24"]
}

resource "azurerm_network_interface" "main" {
name = "${var.prefix}-nic"
name = "nic-${var.postfix}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name

Expand All @@ -79,7 +67,7 @@ resource "azurerm_network_interface" "main" {
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_virtual_machine" "main" {
name = "${var.prefix}-vm"
name = "vm-${var.postfix}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
network_interface_ids = [azurerm_network_interface.main.id]
Expand All @@ -102,13 +90,25 @@ resource "azurerm_virtual_machine" "main" {
}

os_profile {
computer_name = var.hostname
computer_name = "vm-${var.postfix}"
admin_username = var.username
admin_password = random_password.main.result
}

os_profile_linux_config {
disable_password_authentication = false
}

depends_on = [random_password.main]
}

# Random password is used as an example to simplify the deployment and improve the security of the remote VM.
# This is not as a production recommendation as the password is stored in the Terraform state file.
resource "random_password" "main" {
length = 16
override_special = "-_%@"
min_upper = "1"
min_lower = "1"
min_numeric = "1"
min_special = "1"
}
7 changes: 3 additions & 4 deletions examples/azure/terraform-azure-example/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
output "vm_name" {
value = azurerm_virtual_machine.main.name
}

output "resource_group_name" {
value = azurerm_resource_group.main.name
}

output "vm_name" {
value = azurerm_virtual_machine.main.name
}
18 changes: 6 additions & 12 deletions examples/azure/terraform-azure-example/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,16 @@
# These parameters have reasonable defaults.
# ---------------------------------------------------------------------------------------------------------------------

variable "hostname" {
description = "The hostname of the new VM to be configured"
variable "location" {
description = "The Azure location where to deploy your resources too"
type = string
default = "terratest-vm"
default = "East US"
}

variable "password" {
description = "The password to configure for SSH access"
variable "postfix" {
description = "A postfix string to centrally mitigate resource name collisions"
type = string
default = "HorriblePassword1234!"
}

variable "prefix" {
description = "The prefix that will be attached to all resources deployed"
type = string
default = "terratest-example"
default = "resource"
}

variable "username" {
Expand Down
45 changes: 45 additions & 0 deletions examples/azure/terraform-azure-vm-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Terraform Azure Virtual Machine Example

This folder contains a complete Terraform VM module that deploys resources in [Azure](https://azure.microsoft.com/) to demonstrate
how you can use Terratest to write automated tests for your Azure Virtual Machine Terraform code. This module deploys these resources:

- A [Virtual Machine](https://azure.microsoft.com/services/virtual-machines/) and gives that VM the following resources:
- [Virtual Machine](https://docs.microsoft.com/azure/virtual-machines/) with the name specified in the `vm_name` variable.
- [Managed Disk](https://docs.microsoft.com/azure/virtual-machines/managed-disks-overview) with the name specified in the `managed_disk_name` variable.
- [Availability Set](https://docs.microsoft.com/azure/virtual-machines/availability) with the name specified in the `availability_set_name` variable.
- A [Virtual Network](https://azure.microsoft.com/services/virtual-network/) module that contains the following resources:
- [Virtual Network](https://docs.microsoft.com/azure/virtual-network/) with the name specified in the `virtual_network_name` variable.
- [Subnet](https://docs.microsoft.com/rest/api/virtualnetwork/subnets) with the name specified in the `subnet_name` variable.
- [Public Address](https://docs.microsoft.com/azure/virtual-network/public-ip-addresses) with the name specified in the `public_ip_name` variable.
- [Network Interface](https://docs.microsoft.com/azure/virtual-network/virtual-network-network-interface) with the name specified in the `network_interface_name` variable.

Check out [test/azure/terraform_azure_vm_test.go](/test/azure/terraform_azure_vm_test.go) to see how you can write
automated tests for this module.

Note that the Virtual Machine module creates a Microsoft Windows Server Image with a managed disk, availability set and network configuration for demonstration purposes.

**WARNING**: This module and the automated tests for it deploy real resources into your Azure account which can cost you
money. The resources are all part of the [Azure Free Account](https://azure.microsoft.com/free/), so if you haven't used that up,
it should be free, but you are completely responsible for all Azure charges.

## Running this module manually

1. Sign up for [Azure](https://azure.microsoft.com/)
1. Configure your Azure credentials using one of the [supported methods for Azure CL
tools](https://docs.microsoft.com/cli/azure/azure-cli-configuration?view=azure-cli-latest)
1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH`
1. Ensure [environment variables](../README.md#review-environment-variables) are available
1. Run `terraform init`
1. Run `terraform apply`
1. When you're done, run `terraform destroy`

## Running automated tests against this module

1. Sign up for [Azure](https://azure.microsoft.com/)
1. Configure your Azure credentials using one of the [supported methods for Azure CLI
tools](https://docs.microsoft.com/cli/azure/azure-cli-configuration?view=azure-cli-latest)
1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH`
1. Configure your Terratest [Go test environment](../README.md)
1. `cd test/azure`
1. `go build terraform_azure_vm_test.go`
1. `go test -run -v -timeout 20m TestTerraformAzureVmExample`
162 changes: 162 additions & 0 deletions examples/azure/terraform-azure-vm-example/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AN ADVANCED AZURE VIRTUAL MACHINE
# This is an advanced example of how to deploy an Azure Virtual Machine in an availability set, managed disk
# and networking with a public IP.
# ---------------------------------------------------------------------------------------------------------------------
# See test/azure/terraform_azure_vm_example_test.go for how to write automated tests for this code.
# ---------------------------------------------------------------------------------------------------------------------

provider "azurerm" {
version = "~> 2.29"
features {}
}

# ---------------------------------------------------------------------------------------------------------------------
# PIN TERRAFORM VERSION
# ---------------------------------------------------------------------------------------------------------------------

terraform {
# This module is now only being tested with Terraform 0.13.x. However, to make upgrading easier, we are setting
# 0.12.26 as the minimum version, as that version added support for required_providers with source URLs, making it
# forwards compatible with 0.13.x code.
required_version = ">= 0.12.26"
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY A RESOURCE GROUP
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_resource_group" "vm_rg" {
name = "terratest-vm-rg-${var.postfix}"
location = var.location
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY NETWORK RESOURCES
# This network includes a public address for integration test demonstration purposes
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_virtual_network" "vnet" {
name = "vnet-${var.postfix}"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.vm_rg.location
resource_group_name = azurerm_resource_group.vm_rg.name
}

resource "azurerm_subnet" "subnet" {
name = "subnet-${var.postfix}"
resource_group_name = azurerm_resource_group.vm_rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = [var.subnet_prefix]
}

resource "azurerm_public_ip" "pip" {
name = "pip-${var.postfix}"
resource_group_name = azurerm_resource_group.vm_rg.name
location = azurerm_resource_group.vm_rg.location
allocation_method = "Static"
ip_version = "IPv4"
sku = "Standard"
idle_timeout_in_minutes = "4"
}

# Public and Private IPs assigned to one NIC for test demonstration purposes
resource "azurerm_network_interface" "nic" {
name = "nic-${var.postfix}"
location = azurerm_resource_group.vm_rg.location
resource_group_name = azurerm_resource_group.vm_rg.name

ip_configuration {
name = "terratestconfiguration1"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "Static"
private_ip_address = var.private_ip
public_ip_address_id = azurerm_public_ip.pip.id
}
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AN AVAILABILITY SET
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_availability_set" "avs" {
name = "avs-${var.postfix}"
location = azurerm_resource_group.vm_rg.location
resource_group_name = azurerm_resource_group.vm_rg.name
platform_fault_domain_count = 2
managed = true
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY VIRTUAL MACHINE
# This VM does not actually do anything and is the smallest size VM available with a Windows image
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_virtual_machine" "vm_example" {
name = "vm-${var.postfix}"
location = azurerm_resource_group.vm_rg.location
resource_group_name = azurerm_resource_group.vm_rg.name
network_interface_ids = [azurerm_network_interface.nic.id]
availability_set_id = azurerm_availability_set.avs.id
vm_size = var.vm_size
license_type = var.vm_license_type
delete_os_disk_on_termination = true
delete_data_disks_on_termination = true

storage_image_reference {
publisher = var.vm_image_publisher
offer = var.vm_image_offer
sku = var.vm_image_sku
version = var.vm_image_version
}

storage_os_disk {
name = "osdisk-${var.postfix}"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = var.disk_type
}

os_profile {
computer_name = "vm-${var.postfix}"
admin_username = var.user_name
admin_password = random_password.rand.result
}

os_profile_windows_config {
provision_vm_agent = true
}

depends_on = [random_password.rand]
}

# Random password is used as an example to simplify the deployment and improve the security of the remote VM.
# This is not as a production recommendation as the password is stored in the Terraform state file.
resource "random_password" "rand" {
length = 16
override_special = "-_%@"
min_upper = "1"
min_lower = "1"
min_numeric = "1"
min_special = "1"
}

# ---------------------------------------------------------------------------------------------------------------------
# ATTACH A MANAGED DISK TO THE VIRTUAL MACHINE
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_managed_disk" "disk" {
name = "disk-${var.postfix}"
location = azurerm_resource_group.vm_rg.location
resource_group_name = azurerm_resource_group.vm_rg.name
storage_account_type = var.disk_type
create_option = "Empty"
disk_size_gb = 10
}

resource "azurerm_virtual_machine_data_disk_attachment" "vm_disk" {
managed_disk_id = azurerm_managed_disk.disk.id
virtual_machine_id = azurerm_virtual_machine.vm_example.id
caching = "ReadWrite"
lun = 10
}
Loading

0 comments on commit 5fa1994

Please sign in to comment.