diff --git a/examples/azure-2-vms-loadbalancer-lbrules/README.md b/examples/azure-2-vms-loadbalancer-lbrules/README.md new file mode 100644 index 000000000..3d547056e --- /dev/null +++ b/examples/azure-2-vms-loadbalancer-lbrules/README.md @@ -0,0 +1,22 @@ +# Create 2 Virtual Machines under a Load balancer and configures Load Balancing rules for the VMs + +This Terraform template was based on [this](https://github.com/Azure/azure-quickstart-templates/tree/master/201-2-vms-loadbalancer-lbrules) Azure Quickstart Template. Changes to the ARM template may have occured since the creation of this example may not be reflected here. + +This template allows you to create 2 Virtual Machines under a Load balancer and configure a load balancing rule on Port 80. This template also deploys a Storage Account, Virtual Network, Public IP address, Availability Set, and Network Interfaces. + +## main.tf +The `main.tf` file contains the actual resources that will be deployed. It also contains the Azure Resource Group definition and any defined variables. + +## outputs.tf +This data is outputted when `terraform apply` is called, and can be queried using the `terraform output` command. + +## provider.tf +Azure requires that an application is added to Azure Active Directory to generate the `client_id`, `client_secret`, and `tenant_id` needed by Terraform (`subscription_id` can be recovered from your Azure account details). Please go [here](https://www.terraform.io/docs/providers/azurerm/) for full instructions on how to create this to populate your `provider.tf` file. + +## terraform.tfvars +If a `terraform.tfvars` file is present in the current directory, Terraform automatically loads it to populate variables. We don't recommend saving usernames and password to version control, but you can create a local secret variables file and use `-var-file` to load it. + +If you are committing this template to source control, please insure that you add this file to your .gitignore file. + +## variables.tf +The `variables.tf` file contains all of the input parameters that the user can specify when deploying this Terraform template. diff --git a/examples/azure-2-vms-loadbalancer-lbrules/deploy.ci.sh b/examples/azure-2-vms-loadbalancer-lbrules/deploy.ci.sh new file mode 100755 index 000000000..57e0dc9b1 --- /dev/null +++ b/examples/azure-2-vms-loadbalancer-lbrules/deploy.ci.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -o errexit -o nounset + +docker run --rm -it \ + -e ARM_CLIENT_ID \ + -e ARM_CLIENT_SECRET \ + -e ARM_SUBSCRIPTION_ID \ + -e ARM_TENANT_ID \ + -v $(pwd):/data \ + --entrypoint "/bin/sh" \ + hashicorp/terraform:light \ + -c "cd /data; \ + /bin/terraform get; \ + /bin/terraform validate; \ + /bin/terraform plan -out=out.tfplan -var dns_name=$KEY -var hostname=$KEY -var lb_ip_dns_name=$KEY -var resource_group=$KEY -var admin_password=$PASSWORD; \ + /bin/terraform apply out.tfplan" + +# cleanup deployed azure resources via azure-cli +docker run --rm -it \ + azuresdk/azure-cli-python \ + sh -c "az login --service-principal -u $ARM_CLIENT_ID -p $ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID > /dev/null; \ + az network lb show -g $KEY -n rglb; \ + az network lb rule list -g $KEY --lb-name rglb;" + +# cleanup deployed azure resources via terraform +docker run --rm -it \ + -e ARM_CLIENT_ID \ + -e ARM_CLIENT_SECRET \ + -e ARM_SUBSCRIPTION_ID \ + -e ARM_TENANT_ID \ + -v $(pwd):/data \ + --workdir=/data \ + --entrypoint "/bin/sh" \ + hashicorp/terraform:light \ + -c "/bin/terraform destroy -force -var dns_name=$KEY -var hostname=$KEY -var lb_ip_dns_name=$KEY -var resource_group=$KEY -var admin_password=$PASSWORD;" diff --git a/examples/azure-2-vms-loadbalancer-lbrules/deploy.mac.sh b/examples/azure-2-vms-loadbalancer-lbrules/deploy.mac.sh new file mode 100755 index 000000000..cf5cdc322 --- /dev/null +++ b/examples/azure-2-vms-loadbalancer-lbrules/deploy.mac.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -o errexit -o nounset + +if docker -v; then + + # generate a unique string for CI deployment + export KEY=$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-z' | head -c 12) + export PASSWORD=$KEY$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'A-Z' | head -c 2)$(cat /dev/urandom | env LC_CTYPE=C tr -cd '0-9' | head -c 2) + +/bin/sh ./deploy.ci.sh + +else + echo "Docker is used to run terraform commands, please install before run: https://docs.docker.com/docker-for-mac/install/" +fi \ No newline at end of file diff --git a/examples/azure-2-vms-loadbalancer-lbrules/main.tf b/examples/azure-2-vms-loadbalancer-lbrules/main.tf new file mode 100644 index 000000000..495a5565f --- /dev/null +++ b/examples/azure-2-vms-loadbalancer-lbrules/main.tf @@ -0,0 +1,145 @@ +# provider "azurerm" { +# subscription_id = "REPLACE-WITH-YOUR-SUBSCRIPTION-ID" +# client_id = "REPLACE-WITH-YOUR-CLIENT-ID" +# client_secret = "REPLACE-WITH-YOUR-CLIENT-SECRET" +# tenant_id = "REPLACE-WITH-YOUR-TENANT-ID" +# } + +resource "azurerm_resource_group" "rg" { + name = "${var.resource_group}" + location = "${var.location}" +} + +resource "azurerm_storage_account" "stor" { + name = "${var.dns_name}stor" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + account_type = "${var.storage_account_type}" +} + +resource "azurerm_availability_set" "avset" { + name = "${var.dns_name}avset" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + platform_fault_domain_count = 2 + platform_update_domain_count = 2 + managed = true +} + +resource "azurerm_public_ip" "lbpip" { + name = "${var.rg_prefix}-ip" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + public_ip_address_allocation = "dynamic" + domain_name_label = "${var.lb_ip_dns_name}" +} + +resource "azurerm_virtual_network" "vnet" { + name = "${var.virtual_network_name}" + location = "${var.location}" + address_space = ["${var.address_space}"] + resource_group_name = "${azurerm_resource_group.rg.name}" +} + +resource "azurerm_subnet" "subnet" { + name = "${var.rg_prefix}subnet" + virtual_network_name = "${azurerm_virtual_network.vnet.name}" + resource_group_name = "${azurerm_resource_group.rg.name}" + address_prefix = "${var.subnet_prefix}" +} + +resource "azurerm_lb" "lb" { + resource_group_name = "${azurerm_resource_group.rg.name}" + name = "${var.rg_prefix}lb" + location = "${var.location}" + + frontend_ip_configuration { + name = "LoadBalancerFrontEnd" + public_ip_address_id = "${azurerm_public_ip.lbpip.id}" + } +} + +resource "azurerm_lb_backend_address_pool" "backend_pool" { + resource_group_name = "${azurerm_resource_group.rg.name}" + loadbalancer_id = "${azurerm_lb.lb.id}" + name = "BackendPool1" +} + +resource "azurerm_lb_nat_rule" "tcp" { + resource_group_name = "${azurerm_resource_group.rg.name}" + loadbalancer_id = "${azurerm_lb.lb.id}" + name = "RDP-VM-${count.index}" + protocol = "tcp" + frontend_port = "5000${count.index + 1}" + backend_port = 3389 + frontend_ip_configuration_name = "LoadBalancerFrontEnd" + count = 2 +} + +resource "azurerm_lb_rule" "lb_rule" { + resource_group_name = "${azurerm_resource_group.rg.name}" + loadbalancer_id = "${azurerm_lb.lb.id}" + name = "LBRule" + protocol = "tcp" + frontend_port = 80 + backend_port = 80 + frontend_ip_configuration_name = "LoadBalancerFrontEnd" + enable_floating_ip = false + backend_address_pool_id = "${azurerm_lb_backend_address_pool.backend_pool.id}" + idle_timeout_in_minutes = 5 + probe_id = "${azurerm_lb_probe.lb_probe.id}" + depends_on = ["azurerm_lb_probe.lb_probe"] +} + +resource "azurerm_lb_probe" "lb_probe" { + resource_group_name = "${azurerm_resource_group.rg.name}" + loadbalancer_id = "${azurerm_lb.lb.id}" + name = "tcpProbe" + protocol = "tcp" + port = 80 + interval_in_seconds = 5 + number_of_probes = 2 +} + +resource "azurerm_network_interface" "nic" { + name = "nic${count.index}" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + count = 2 + + ip_configuration { + name = "ipconfig${count.index}" + subnet_id = "${azurerm_subnet.subnet.id}" + private_ip_address_allocation = "Dynamic" + load_balancer_backend_address_pools_ids = ["${azurerm_lb_backend_address_pool.backend_pool.id}"] + load_balancer_inbound_nat_rules_ids = ["${element(azurerm_lb_nat_rule.tcp.*.id, count.index)}"] + } +} + +resource "azurerm_virtual_machine" "vm" { + name = "vm${count.index}" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + availability_set_id = "${azurerm_availability_set.avset.id}" + vm_size = "${var.vm_size}" + network_interface_ids = ["${element(azurerm_network_interface.nic.*.id, count.index)}"] + count = 2 + + storage_image_reference { + publisher = "${var.image_publisher}" + offer = "${var.image_offer}" + sku = "${var.image_sku}" + version = "${var.image_version}" + } + + storage_os_disk { + name = "osdisk${count.index}" + create_option = "FromImage" + } + + os_profile { + computer_name = "${var.hostname}" + admin_username = "${var.admin_username}" + admin_password = "${var.admin_password}" + } +} diff --git a/examples/azure-2-vms-loadbalancer-lbrules/outputs.tf b/examples/azure-2-vms-loadbalancer-lbrules/outputs.tf new file mode 100644 index 000000000..19757fa52 --- /dev/null +++ b/examples/azure-2-vms-loadbalancer-lbrules/outputs.tf @@ -0,0 +1,11 @@ +output "hostname" { + value = "${var.hostname}" +} + +output "vm_fqdn" { + value = "${azurerm_public_ip.lbpip.fqdn}" +} + +output "ssh_command" { + value = "ssh ${var.admin_username}@${azurerm_public_ip.lbpip.fqdn}" +} diff --git a/examples/azure-2-vms-loadbalancer-lbrules/variables.tf b/examples/azure-2-vms-loadbalancer-lbrules/variables.tf new file mode 100644 index 000000000..0e652606a --- /dev/null +++ b/examples/azure-2-vms-loadbalancer-lbrules/variables.tf @@ -0,0 +1,79 @@ +variable "resource_group" { + description = "The name of the resource group in which to create the virtual network." +} + +variable "rg_prefix" { + description = "The shortened abbreviation to represent your resource group that will go on the front of some resources." + default = "rg" +} + +variable "hostname" { + description = "VM name referenced also in storage-related names." +} + +variable "dns_name" { + description = " Label for the Domain Name. Will be used to make up the FQDN. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system." +} + +variable "lb_ip_dns_name" { + description = "DNS for Load Balancer IP" +} + +variable "location" { + description = "The location/region where the virtual network is created. Changing this forces a new resource to be created." + default = "southcentralus" +} + +variable "virtual_network_name" { + description = "The name for the virtual network." + default = "vnet" +} + +variable "address_space" { + description = "The address space that is used by the virtual network. You can supply more than one address space. Changing this forces a new resource to be created." + default = "10.0.0.0/16" +} + +variable "subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.0.10.0/24" +} + +variable "storage_account_type" { + description = "Defines the type of storage account to be created. Valid options are Standard_LRS, Standard_ZRS, Standard_GRS, Standard_RAGRS, Premium_LRS. Changing this is sometimes valid - see the Azure documentation for more information on which types of accounts can be converted into other types." + default = "Standard_LRS" +} + +variable "vm_size" { + description = "Specifies the size of the virtual machine." + default = "Standard_D1" +} + +variable "image_publisher" { + description = "name of the publisher of the image (az vm image list)" + default = "MicrosoftWindowsServer" +} + +variable "image_offer" { + description = "the name of the offer (az vm image list)" + default = "WindowsServer" +} + +variable "image_sku" { + description = "image sku to apply (az vm image list)" + default = "2012-R2-Datacenter" +} + +variable "image_version" { + description = "version of the image to apply (az vm image list)" + default = "latest" +} + +variable "admin_username" { + description = "administrator user name" + default = "vmadmin" +} + +variable "admin_password" { + description = "administrator password (recommended to disable password auth)" +} diff --git a/examples/azure-cdn-with-storage-account/main.tf b/examples/azure-cdn-with-storage-account/main.tf index 2e7f56954..0f50bb5eb 100644 --- a/examples/azure-cdn-with-storage-account/main.tf +++ b/examples/azure-cdn-with-storage-account/main.tf @@ -36,4 +36,4 @@ resource "azurerm_cdn_endpoint" "cdnendpt" { http_port = 80 https_port = 443 } -} +} \ No newline at end of file