From afb164b79a65e560be1a03a4644bd1f9ca36dd5f Mon Sep 17 00:00:00 2001 From: Scott Nowicki Date: Mon, 24 Apr 2017 14:57:28 -0500 Subject: [PATCH] Topic 101 vm simple linux (#1) * added .travis.yml and deploy.sh * added deploy script, updated travis.yml to build topic- branches * generate random string for hostname * plan now produces output plan, apply now consumes outputted plan * cleanup; sane defaults * explicit build dirs --- .travis.yml | 32 +++-- examples/azure-vm-simple-linux/.gitignore | 3 + examples/azure-vm-simple-linux/README.md | 36 ++++++ .../azure-vm-simple-linux/after_deploy.sh | 9 ++ examples/azure-vm-simple-linux/deploy.mac.sh | 14 +++ examples/azure-vm-simple-linux/deploy.sh | 17 +++ examples/azure-vm-simple-linux/main.tf | 112 ++++++++++++++++++ examples/azure-vm-simple-linux/outputs.tf | 11 ++ .../azure-vm-simple-linux/provider.tf.example | 6 + .../terraform.tfvars.example | 6 + examples/azure-vm-simple-linux/variables.tf | 75 ++++++++++++ 11 files changed, 303 insertions(+), 18 deletions(-) create mode 100644 examples/azure-vm-simple-linux/.gitignore create mode 100644 examples/azure-vm-simple-linux/README.md create mode 100755 examples/azure-vm-simple-linux/after_deploy.sh create mode 100755 examples/azure-vm-simple-linux/deploy.mac.sh create mode 100755 examples/azure-vm-simple-linux/deploy.sh create mode 100644 examples/azure-vm-simple-linux/main.tf create mode 100644 examples/azure-vm-simple-linux/outputs.tf create mode 100644 examples/azure-vm-simple-linux/provider.tf.example create mode 100644 examples/azure-vm-simple-linux/terraform.tfvars.example create mode 100644 examples/azure-vm-simple-linux/variables.tf diff --git a/.travis.yml b/.travis.yml index c340136965a8..9bf07f695d76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,36 +1,32 @@ +sudo: required + +services: + - docker + language: generic # establish environment variables env: - - TEST_DIR=examples/101-vm-simple-linux -# global: -# - GH_USER_NAME="travis-ci" -# - GH_USER_EMAIL="mikedball@gmail.com" -# - GH_REPO="10thmagnitude/terraform" -# # encrypted GH_TOKEN and AWS credentials -# - secure: "EBtNoRGUNjgom7lk6+O7Zh9A33X/251Cg7j5C+HqfkPMQcQwS6MEAXPT1vbnh1HoQixR1e6VTHdXxvWyE/14+98qtJiHnSbGiY67ZvQNDuFLb2+PKx7xhhl9heNj8Xk1K1SYJtfYQZIvZNl32V9db6eR3r7kKlWlpUVmnSnXrnm4ztI8se45OX/XPjAnARdBvkpbcTSprrAf7Qudc5R86ain18tJah6PICd12TIH4Cpdcr6CVL8kRK808VH+AS2oii7QcKXc084gBOJJLCiwa2DrcSEPOOk0AIn5ft+XVcaCsV6oOc6NliFKEPoJkaxbYWtunDlnqgB6epuaGrf99TfCg4E9R8sXBFqJwdMGDu3xM6Nddw87tMj/oCbUmjrNnl4qAxIMBD2TdjwFS1lNaXAML8W/jx3bNGSEg5MAYrqLL32eJta/vxRJwpCVnXUHxef9JcZMNZcvuKMdHC98JQIYbGRRFZ0cFtqMe63tgWafCi3WS+FIqSWnGdiKZ7dS110ANHaiQkDAZKTlh/9YJpzR9LyOoq7xXYtQIUovyDD2j498mAkcgByEbyZ39k6xMvLHHXsdUq25tdaMvqE3ZUASIDWqDk1QPfxkXX6n62Tj2X1HCA+3JI/DKyEfzt3QV4rntiP4Qv9jSuxNpd47rgsgVFg+HGJmko9QzAA/g+E=" + - TEST_DIR=examples/azure-vm-simple-linux branches: only: - master - /^(?i:topic)-.*$/ - -##todo: switch to before_script and script - # install terraform before_deploy: - - curl -fSL "https://releases.hashicorp.com/terraform/0.9.3/terraform_0.9.3_linux_amd64.zip" -o terraform.zip - - sudo unzip terraform.zip -d /opt/terraform - - sudo ln -s /opt/terraform/terraform /usr/bin/terraform - - rm -f terraform.zip + - export KEY=$(cat /dev/urandom | tr -cd 'a-z' | head -c 12) + - export PASSWORD=$KEY$(cat /dev/urandom | tr -cd 'A-Z' | head -c 2)$(cat /dev/urandom | tr -cd '0-9' | head -c 2) -# terraform apply +# terraform deploy script deploy: - provider: script skip_cleanup: true - script: cd $TEST_DIR && "./deploy.sh" + script: cd $TRAVIS_BUILD_DIR/$TEST_DIR && ./deploy.sh on: repo: 10thmagnitude/terraform - branch: 101-vm-simple-linux - condition: false # re-enable when examples exist in master + branch: topic-101-vm-simple-linux + +# destroy resources with Azure CLI +after_deploy: cd $TRAVIS_BUILD_DIR/$TEST_DIR && ./after_deploy.sh \ No newline at end of file diff --git a/examples/azure-vm-simple-linux/.gitignore b/examples/azure-vm-simple-linux/.gitignore new file mode 100644 index 000000000000..7773fa9ecc5d --- /dev/null +++ b/examples/azure-vm-simple-linux/.gitignore @@ -0,0 +1,3 @@ +terraform.tfstate* +terraform.tfvars +provider.tf diff --git a/examples/azure-vm-simple-linux/README.md b/examples/azure-vm-simple-linux/README.md new file mode 100644 index 000000000000..a0ab5f63451e --- /dev/null +++ b/examples/azure-vm-simple-linux/README.md @@ -0,0 +1,36 @@ +# Very simple deployment of a Linux VM + + + + + + + + +This template allows you to deploy a simple Linux VM using a few different options for the Ubuntu version, using the latest patched version. This will deploy a A1 size VM in the resource group location and return the FQDN of the VM. + +This template takes a minimum amount of parameters and deploys a Linux VM, using the latest patched version. + +## 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. + +## variables.tf +The `variables.tf` file contains all of the input parameters that the user can specify when deploying this Terraform template. + +## .gitignore +If you are committing this template to source control, please insure that the following files are added to your `.gitignore` file. + +``` +terraform.tfstate* +terraform.tfvars +provider.tf* +``` \ No newline at end of file diff --git a/examples/azure-vm-simple-linux/after_deploy.sh b/examples/azure-vm-simple-linux/after_deploy.sh new file mode 100755 index 000000000000..245aba38045e --- /dev/null +++ b/examples/azure-vm-simple-linux/after_deploy.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -o errexit -o nounset + +# cleanup deployed azure resources +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; \ + az group delete -y -n $KEY" diff --git a/examples/azure-vm-simple-linux/deploy.mac.sh b/examples/azure-vm-simple-linux/deploy.mac.sh new file mode 100755 index 000000000000..f0bb60f8bb8b --- /dev/null +++ b/examples/azure-vm-simple-linux/deploy.mac.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -o errexit -o nounset + +# 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.sh + +# 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; \ +# az group delete -y -n $KEY" diff --git a/examples/azure-vm-simple-linux/deploy.sh b/examples/azure-vm-simple-linux/deploy.sh new file mode 100755 index 000000000000..5347f3a838c6 --- /dev/null +++ b/examples/azure-vm-simple-linux/deploy.sh @@ -0,0 +1,17 @@ +#!/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 resource_group=$KEY -var admin_password=$PASSWORD; \ + /bin/terraform apply out.tfplan" diff --git a/examples/azure-vm-simple-linux/main.tf b/examples/azure-vm-simple-linux/main.tf new file mode 100644 index 000000000000..cf931d0f9e4e --- /dev/null +++ b/examples/azure-vm-simple-linux/main.tf @@ -0,0 +1,112 @@ +resource "azurerm_resource_group" "rg" { + name = "${var.resource_group}" + location = "${var.location}" +} + +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_network_interface" "nic" { + name = "${var.rg_prefix}nic" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + + ip_configuration { + name = "${var.rg_prefix}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.rg_prefix}-ip" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + public_ip_address_allocation = "dynamic" + domain_name_label = "${var.dns_name}" +} + +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_storage_container" "storc" { + name = "${var.hostname}-vhds" + resource_group_name = "${azurerm_resource_group.rg.name}" + storage_account_name = "${azurerm_storage_account.stor.name}" + container_access_type = "private" +} + +resource "azurerm_managed_disk" "disk1" { + name = "${var.hostname}-osdisk1" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + storage_account_type = "Standard_LRS" + create_option = "Empty" + disk_size_gb = "30" +} + +resource "azurerm_managed_disk" "disk2" { + name = "${var.hostname}-disk2" + location = "${var.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + storage_account_type = "Standard_LRS" + create_option = "Empty" + disk_size_gb = "1023" +} + +resource "azurerm_virtual_machine" "vm" { + name = "${var.rg_prefix}vm" + 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_image_reference { + publisher = "${var.image_publisher}" + offer = "${var.image_offer}" + sku = "${var.image_sku}" + version = "${var.image_version}" + } + + storage_os_disk { + name = "${var.hostname}-osdisk1" + vhd_uri = "${azurerm_storage_account.stor.primary_blob_endpoint}${azurerm_storage_container.storc.name}/${var.hostname}-osdisk1.vhd" + caching = "ReadWrite" + create_option = "FromImage" + } + + storage_data_disk { + name = "${var.hostname}-disk2" + vhd_uri = "${azurerm_storage_account.stor.primary_blob_endpoint}${azurerm_storage_container.storc.name}/${var.hostname}-disk2.vhd" + disk_size_gb = "1023" + create_option = "Empty" + lun = 0 + } + + os_profile { + computer_name = "${var.hostname}" + admin_username = "${var.admin_username}" + admin_password = "${var.admin_password}" + } + + boot_diagnostics { + enabled = "true" + storage_uri = "${azurerm_storage_account.stor.primary_blob_endpoint}" + } +} diff --git a/examples/azure-vm-simple-linux/outputs.tf b/examples/azure-vm-simple-linux/outputs.tf new file mode 100644 index 000000000000..9e3c2f0712bc --- /dev/null +++ b/examples/azure-vm-simple-linux/outputs.tf @@ -0,0 +1,11 @@ +output "hostname" { + value = "${var.hostname}" +} + +output "vm_fqdn" { + value = "${azurerm_public_ip.pip.fqdn}" +} + +output "sshCommand" { + value = "ssh ${var.admin_username}@${azurerm_public_ip.pip.fqdn}" +} diff --git a/examples/azure-vm-simple-linux/provider.tf.example b/examples/azure-vm-simple-linux/provider.tf.example new file mode 100644 index 000000000000..327ceb55eefa --- /dev/null +++ b/examples/azure-vm-simple-linux/provider.tf.example @@ -0,0 +1,6 @@ +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" +} \ No newline at end of file diff --git a/examples/azure-vm-simple-linux/terraform.tfvars.example b/examples/azure-vm-simple-linux/terraform.tfvars.example new file mode 100644 index 000000000000..262093ba52f9 --- /dev/null +++ b/examples/azure-vm-simple-linux/terraform.tfvars.example @@ -0,0 +1,6 @@ +resource_group = "myresourcegroup" +rg_prefix = "rg" +hostname = "myvm" +dns_name = "mydnsname" +location = "southcentralus" +admin_password = "T3rr@f0rmP@ssword" diff --git a/examples/azure-vm-simple-linux/variables.tf b/examples/azure-vm-simple-linux/variables.tf new file mode 100644 index 000000000000..6d65a0277060 --- /dev/null +++ b/examples/azure-vm-simple-linux/variables.tf @@ -0,0 +1,75 @@ +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 "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 = "Specifies the name of the storage account. Changing this forces a new resource to be created. This must be unique across the entire Azure service, not just within the resource group." + default = "Standard_LRS" +} + +variable "vm_size" { + description = "Specifies the name of the virtual machine resource. Changing this forces a new resource to be created." + default = "Standard_A0" +} + +variable "image_publisher" { + description = "name of the publisher of the image (az vm image list)" + default = "Canonical" +} + +variable "image_offer" { + description = "the name of the offer (az vm image list)" + default = "UbuntuServer" +} + +variable "image_sku" { + description = "image sku to apply (az vm image list)" + default = "16.04-LTS" +} + +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)" +}