diff --git a/examples/azure-vm-from-user-image/README.md b/examples/azure-vm-from-user-image/README.md new file mode 100644 index 000000000..c3ed92de1 --- /dev/null +++ b/examples/azure-vm-from-user-image/README.md @@ -0,0 +1,26 @@ +# [Create a Virtual Machine from a User Image](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/cli-deploy-templates#create-a-custom-vm-image) + +This Terraform template was based on [this](https://github.com/Azure/azure-quickstart-templates/tree/master/101-vm-from-user-image) Azure Quickstart Template. Changes to the ARM template that may have occurred since the creation of this example may not be reflected here. + +> Prerequisite - The generalized image VHD should exist, as well as a Storage Account for boot diagnostics + +This template allows you to create a Virtual Machine from an unmanaged User image vhd. This template also deploys a Virtual Network, Public IP addresses and a Network Interface. + +## 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. + +![graph](/examples/azure-vm-from-user-image/graph.png) \ No newline at end of file diff --git a/examples/azure-vm-from-user-image/deploy.ci.sh b/examples/azure-vm-from-user-image/deploy.ci.sh new file mode 100755 index 000000000..37578ed7d --- /dev/null +++ b/examples/azure-vm-from-user-image/deploy.ci.sh @@ -0,0 +1,45 @@ +#!/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 \ + --workdir=/data \ + --entrypoint "/bin/sh" \ + hashicorp/terraform:light \ + -c "/bin/terraform get; \ + /bin/terraform validate; \ + /bin/terraform plan -out=out.tfplan -var hostname=$KEY -var resource_group=$EXISTING_RESOURCE_GROUP -var admin_username=$KEY -var admin_password=$PASSWORD -var image_uri=$EXISTING_IMAGE_URI -var storage_account_name=$EXISTING_STORAGE_ACCOUNT_NAME; \ + /bin/terraform apply out.tfplan; \ + /bin/terraform show;" + +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 vm show --name $KEY --resource-group permanent" + +# 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 hostname=$KEY \ + -var resource_group=$EXISTING_RESOURCE_GROUP \ + -var admin_username=$KEY \ + -var admin_password=$PASSWORD \ + -var image_uri=$EXISTING_IMAGE_URI \ + -var storage_account_name=$EXISTING_STORAGE_ACCOUNT_NAME \ + -target=azurerm_virtual_machine.vm \ + -target=azurerm_network_interface.nic \ + -target=azurerm_virtual_network.vnet \ + -target=azurerm_public_ip.pip;" diff --git a/examples/azure-vm-from-user-image/deploy.mac.sh b/examples/azure-vm-from-user-image/deploy.mac.sh new file mode 100755 index 000000000..5073b4035 --- /dev/null +++ b/examples/azure-vm-from-user-image/deploy.mac.sh @@ -0,0 +1,18 @@ +#!/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) + export EXISTING_IMAGE_URI=https://permanentstor.blob.core.windows.net/permanent-vhds/permanent-osdisk1.vhd + export EXISTING_STORAGE_ACCOUNT_NAME=permanentstor + export EXISTING_RESOURCE_GROUP=permanent + + /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-vm-from-user-image/graph.png b/examples/azure-vm-from-user-image/graph.png new file mode 100644 index 000000000..2384ff0ce Binary files /dev/null and b/examples/azure-vm-from-user-image/graph.png differ diff --git a/examples/azure-vm-from-user-image/main.tf b/examples/azure-vm-from-user-image/main.tf new file mode 100644 index 000000000..8444377f8 --- /dev/null +++ b/examples/azure-vm-from-user-image/main.tf @@ -0,0 +1,73 @@ +# 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_virtual_network" "vnet" { + name = "${var.hostname}vnet" + location = "${var.location}" + address_space = ["${var.address_space}"] + resource_group_name = "${azurerm_resource_group.rg.name}" +} + +resource "azurerm_subnet" "subnet" { + name = "${var.hostname}subnet" + virtual_network_name = "${azurerm_virtual_network.vnet.name}" + resource_group_name = "${azurerm_resource_group.rg.name}" + address_prefix = "${var.subnet_prefix}" +} + +resource "azurerm_network_interface" "nic" { + name = "${var.hostname}nic" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + + ip_configuration { + name = "${var.hostname}ipconfig" + subnet_id = "${azurerm_subnet.subnet.id}" + private_ip_address_allocation = "Dynamic" + public_ip_address_id = "${azurerm_public_ip.pip.id}" + } +} + +resource "azurerm_public_ip" "pip" { + name = "${var.hostname}-ip" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + public_ip_address_allocation = "Dynamic" + domain_name_label = "${var.hostname}" +} + +resource "azurerm_virtual_machine" "vm" { + name = "${var.hostname}" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + vm_size = "${var.vm_size}" + network_interface_ids = ["${azurerm_network_interface.nic.id}"] + + storage_os_disk { + name = "${var.hostname}-osdisk1" + image_uri = "${var.image_uri}" + vhd_uri = "https://${var.storage_account_name}.blob.core.windows.net/vhds/${var.hostname}osdisk.vhd" + os_type = "${var.os_type}" + caching = "ReadWrite" + create_option = "FromImage" + } + + os_profile { + computer_name = "${var.hostname}" + admin_username = "${var.admin_username}" + admin_password = "${var.admin_password}" + } + + os_profile_linux_config { + disable_password_authentication = false + } +} diff --git a/examples/azure-vm-from-user-image/outputs.tf b/examples/azure-vm-from-user-image/outputs.tf new file mode 100644 index 000000000..58a17046f --- /dev/null +++ b/examples/azure-vm-from-user-image/outputs.tf @@ -0,0 +1,11 @@ +output "hostname" { + value = "${var.hostname}" +} + +output "vm_fqdn" { + value = "${azurerm_public_ip.pip.fqdn}" +} + +output "ssh_command" { + value = "${concat("ssh ", var.admin_username, "@", azurerm_public_ip.pip.fqdn)}" +} diff --git a/examples/azure-vm-from-user-image/variables.tf b/examples/azure-vm-from-user-image/variables.tf new file mode 100644 index 000000000..133c02bbb --- /dev/null +++ b/examples/azure-vm-from-user-image/variables.tf @@ -0,0 +1,55 @@ +variable "resource_group" { + description = "The name of the resource group in which the image to clone resides." + default = "myrg" +} + +variable "image_uri" { + description = "Specifies the image_uri in the form publisherName:offer:skus:version. image_uri can also specify the VHD uri of a custom VM image to clone." +} + +variable "os_type" { + description = "Specifies the operating system Type, valid values are windows, linux." + default = "linux" +} + +variable "location" { + description = "The location/region where the virtual network is created. Changing this forces a new resource to be created." + default = "southcentralus" +} + +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/24" +} + +variable "subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.0.0.0/24" +} + +variable "storage_account_name" { + description = "The name of the storage account in which the image from which you are cloning resides." +} + +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 = "Premium_LRS" +} + +variable "vm_size" { + description = "Specifies the size of the virtual machine. This must be the same as the vm image from which you are copying." + default = "Standard_DS1_v2" +} + +variable "hostname" { + description = "VM name referenced also in storage-related names. This is also used as the label for the Domain Name and 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 "admin_username" { + description = "administrator user name" + default = "vmadmin" +} + +variable "admin_password" { + description = "The Password for the account specified in the 'admin_username' field. We recommend disabling Password Authentication in a Production environment." +} diff --git a/examples/azure-vnet-two-subnets/.gitignore b/examples/azure-vnet-two-subnets/.gitignore deleted file mode 100644 index 4893d38ff..000000000 --- a/examples/azure-vnet-two-subnets/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -terraform.tfstate* -provider.tf -out.tfplan