From 87be64b1ac9ee24977af80239ab7d6c0706cf75a Mon Sep 17 00:00:00 2001 From: Annie Hedgpeth Date: Tue, 13 Jun 2017 08:28:42 -0500 Subject: [PATCH] provider/azurerm: Example of Wordpress MySql Replication (#15260) * initial commit - 101-vm-from-user-image * changed branch name * not deploying - storage problems * provisions vm but image not properly prepared * storage not correct * provisions properly * changed main.tf to azuredeploy.tf * added tfvars and info for README * tfvars ignored and corrected file ext * added CI config; added sane defaults for variables; updated deployment script, added mac specific deployment for local testing * deploy.sh to be executable * executable deploy files * added CI files; changed vars * prep for PR * removal of old folder * prep for PR * wrong args for travis * more PR prep * updated README * commented out variables in terraform.tfvars * Topic 101 vm from user image (#2) * initial commit - 101-vm-from-user-image * added tfvars and info for README * added CI config; added sane defaults for variables; updated deployment script, added mac specific deployment for local testing * prep for PR * added new template * oops, left off master * prep for PR * correct repository for destination * renamed scripts to be more intuitive; added check for docker * merge vm simple; vm from image * initial commit * deploys locally * updated deploy * consolidated deploy and after_deploy into a single script; simplified ci process; added os_profile_linux_config * added terraform show * changed to allow http & https (like ARM tmplt) * changed host_name & host_name variable desc * added az cli check * on this branch, only build test_dir; master will aggregate all the examples * merge master * added new constructs/naming for deploy scripts, etc. * suppress az login output * suppress az login output * forgot about line breaks * breaking build as an example * fixing broken build example * merge of CI config * fixed grammar in readme * prep for PR * took out armviz button and minor README changes * changed host_name * fixed merge conflicts * changed host_name variable * updating Hashicorp's changes to merged simple linux branch * updating files to merge w/master and prep for Hashicorp pr * Revert "updating files to merge w/master and prep for Hashicorp pr" This reverts commit b850cd5d2a858eff073fc5a1097a6813d0f8b362. * Revert "updating Hashicorp's changes to merged simple linux branch" This reverts commit dbaf8d14a9cdfcef0281919671357f6171ebd4e6. * removing vm from user image example from this branch * removed old branch * azure-2-vms-loadbalancer-lbrules (#13) * initial commit * need to change lb_rule & nic * deploys locally * updated README * updated travis and deploy scripts for Hari's repo * renamed deploy script * clean up * prep for PR * updated readme * fixing conflict in .travis.yml * initial commit; in progress * in progress * in progress; encryption fails * in progress * deploys successfully locally * clean up; deploy typo fixed * merging hashi master into this branch * troubleshooting deploy * added missing vars to deploy script * updated README, outputs, and added graph * simplified outputs * provisions locally * cleaned up vars * fixed chart on README * prepping for pr * fixed merge conflict * initial commit * provisions locally; but azuremysql.sh script fails * commented out provider * commenting out provider vars * tf fmt / uncommented Ext - will fail * testing other examples * changed os version for script compatability; changed command * removed ssh from output (no nsg) * changed travis to test only this topic's dir * added nsg * testing encrypt-running-linux * fixed IPs and validation * cleanup merge conflicts * updated validation cmd; reverted non-topic ci changes * reverting to Hashicorp's .travis.yml * removing return line * returned return lines to travis.yml * return lines * return lines * travis --- .../README.md | 41 +++ .../deploy.ci.sh | 56 ++++ .../deploy.mac.sh | 15 ++ .../azure-wordpress-mysql-replication/main.tf | 244 ++++++++++++++++++ .../outputs.tf | 23 ++ .../variables.tf | 210 +++++++++++++++ .../website.tf | 140 ++++++++++ 7 files changed, 729 insertions(+) create mode 100644 examples/azure-wordpress-mysql-replication/README.md create mode 100755 examples/azure-wordpress-mysql-replication/deploy.ci.sh create mode 100755 examples/azure-wordpress-mysql-replication/deploy.mac.sh create mode 100644 examples/azure-wordpress-mysql-replication/main.tf create mode 100644 examples/azure-wordpress-mysql-replication/outputs.tf create mode 100644 examples/azure-wordpress-mysql-replication/variables.tf create mode 100644 examples/azure-wordpress-mysql-replication/website.tf diff --git a/examples/azure-wordpress-mysql-replication/README.md b/examples/azure-wordpress-mysql-replication/README.md new file mode 100644 index 000000000..75ad2dcbc --- /dev/null +++ b/examples/azure-wordpress-mysql-replication/README.md @@ -0,0 +1,41 @@ +# Deploys a WordPress web site backed by MySQL master-slave replication + +This Terraform template was based on [this](https://github.com/Azure/azure-quickstart-templates/tree/master/wordpress-mysql-replication) Azure Quickstart Template. Changes to the ARM template that may have occurred since the creation of this example may not be reflected here. + +This template deploys a WordPress site in Azure backed by MySQL replication with one master and one slave server. It has the following capabilities: + +- Installs and configures GTID based MySQL replication on CentOS 6 +- Deploys a load balancer in front of the 2 MySQL VMs +- MySQL, SSH, and MySQL probe ports are exposed through the load balancer using Network Security Group rules. +- WordPress accesses MySQL through the load balancer. +- Configures an http based health probe for each MySQL instance that can be used to monitor MySQL health. +- WordPress deployment starts immediately after MySQL deployment finishes. +- Details about MySQL management, including failover, can be found [here](https://github.com/Azure/azure-quickstart-templates/tree/master/mysql-replication). + +If you would like to leverage an existing VNET, then please see the [documentation here](https://www.terraform.io/docs/import/index.html) to learn about importing existing resources into Terraform and bringing them under state management by this template. To import your existing VNET, you may use this command. + +``` +terraform import azurerm_virtual_network.testNetwork /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks/ +``` + +## main.tf +The `main.tf` file contains the resources necessary for the MySql replication deployment that will be created. It also contains the Azure Resource Group definition and any defined variables. + +## website.tf +The `website.tf` contains an `azurerm_template_deployment` that will deploy the Wordpress website. + +## outputs.tf +This data is outputted when `terraform apply` is called, and can be queried using the `terraform output` command. + +## provider.tf +You may leave the provider block in the `main.tf`, as it is in this template, or you can create a file called `provider.tf` and add it to your `.gitignore` file. + +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-wordpress-mysql-replication/deploy.ci.sh b/examples/azure-wordpress-mysql-replication/deploy.ci.sh new file mode 100755 index 000000000..2cf7c0ec5 --- /dev/null +++ b/examples/azure-wordpress-mysql-replication/deploy.ci.sh @@ -0,0 +1,56 @@ +#!/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 resource_group=$KEY \ + -var unique_prefix=$KEY \ + -var site_name=$KEY \ + -var dns_name=$KEY \ + -var hosting_plan_name=$KEY \ + -var mysql_root_password=$PASSWORD \ + -var mysql_replication_password=$PASSWORD \ + -var mysql_probe_password=$PASSWORD \ + -var vm_admin_username=$KEY \ + -var vm_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 vm list -g $KEY; \ + az webapp show -n $KEY -g $KEY" + +# 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 resource_group=$KEY \ + -var unique_prefix=$KEY \ + -var site_name=$KEY \ + -var dns_name=$KEY \ + -var hosting_plan_name=$KEY \ + -var mysql_root_password=$PASSWORD \ + -var mysql_replication_password=$PASSWORD \ + -var mysql_probe_password=$PASSWORD \ + -var vm_admin_username=$KEY \ + -var vm_admin_password=$PASSWORD;" \ No newline at end of file diff --git a/examples/azure-wordpress-mysql-replication/deploy.mac.sh b/examples/azure-wordpress-mysql-replication/deploy.mac.sh new file mode 100755 index 000000000..cf5cdc322 --- /dev/null +++ b/examples/azure-wordpress-mysql-replication/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-wordpress-mysql-replication/main.tf b/examples/azure-wordpress-mysql-replication/main.tf new file mode 100644 index 000000000..a91933b1d --- /dev/null +++ b/examples/azure-wordpress-mysql-replication/main.tf @@ -0,0 +1,244 @@ +# provider "azurerm" { +# subscription_id = "${var.subscription_id}" +# client_id = "${var.client_id}" +# client_secret = "${var.client_secret}" +# tenant_id = "${var.tenant_id}" +# } + +# ********************** MYSQL REPLICATION ********************** # + +resource "azurerm_resource_group" "rg" { + name = "${var.resource_group}" + location = "${var.location}" +} + +# ********************** VNET / SUBNET ********************** # +resource "azurerm_virtual_network" "vnet" { + name = "${var.virtual_network_name}" + resource_group_name = "${azurerm_resource_group.rg.name}" + location = "${azurerm_resource_group.rg.location}" + address_space = ["${var.vnet_address_prefix}"] +} + +resource "azurerm_subnet" "db_subnet" { + name = "${var.db_subnet_name}" + virtual_network_name = "${azurerm_virtual_network.vnet.name}" + resource_group_name = "${azurerm_resource_group.rg.name}" + network_security_group_id = "${azurerm_network_security_group.nsg.id}" + address_prefix = "${var.db_subnet_address_prefix}" + depends_on = ["azurerm_virtual_network.vnet"] +} + +# ********************** STORAGE ACCOUNTS ********************** # +resource "azurerm_storage_account" "stor" { + name = "${var.unique_prefix}${var.storage_account_name}" + resource_group_name = "${azurerm_resource_group.rg.name}" + location = "${azurerm_resource_group.rg.location}" + account_type = "${var.storage_account_type}" +} + +# ********************** NETWORK SECURITY GROUP ********************** # +resource "azurerm_network_security_group" "nsg" { + name = "${var.unique_prefix}-nsg" + resource_group_name = "${azurerm_resource_group.rg.name}" + location = "${azurerm_resource_group.rg.location}" + + security_rule { + name = "allow-ssh" + description = "Allow SSH" + priority = 100 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "Internet" + destination_address_prefix = "*" + } + + security_rule { + name = "MySQL" + description = "MySQL" + priority = 110 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "3306" + source_address_prefix = "*" + destination_address_prefix = "*" + } +} + +# ********************** PUBLIC IP ADDRESSES ********************** # +resource "azurerm_public_ip" "pip" { + name = "${var.public_ip_name}" + location = "${azurerm_resource_group.rg.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + public_ip_address_allocation = "Static" + domain_name_label = "${var.dns_name}" +} + +# ********************** AVAILABILITY SET ********************** # +resource "azurerm_availability_set" "availability_set" { + name = "${var.dns_name}-set" + location = "${azurerm_resource_group.rg.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" +} + +# ********************** NETWORK INTERFACES ********************** # +resource "azurerm_network_interface" "nic" { + name = "${var.nic_name}${count.index}" + location = "${azurerm_resource_group.rg.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + network_security_group_id = "${azurerm_network_security_group.nsg.id}" + count = "${var.node_count}" + depends_on = ["azurerm_virtual_network.vnet", "azurerm_public_ip.pip", "azurerm_lb.lb"] + + ip_configuration { + name = "ipconfig${count.index}" + subnet_id = "${azurerm_subnet.db_subnet.id}" + private_ip_address_allocation = "Static" + private_ip_address = "10.0.1.${count.index + 4}" + 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.NatRule0.*.id, count.index)}", + "${element(azurerm_lb_nat_rule.MySQLNatRule0.*.id, count.index)}", + "${element(azurerm_lb_nat_rule.ProbeNatRule0.*.id, count.index)}", + ] + } +} + +# ********************** LOAD BALANCER ********************** # +resource "azurerm_lb" "lb" { + name = "${var.dns_name}-lb" + location = "${azurerm_resource_group.rg.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + depends_on = ["azurerm_public_ip.pip"] + + frontend_ip_configuration { + name = "${var.dns_name}-sshIPCfg" + public_ip_address_id = "${azurerm_public_ip.pip.id}" + } +} + +resource "azurerm_lb_backend_address_pool" "backend_pool" { + resource_group_name = "${azurerm_resource_group.rg.name}" + loadbalancer_id = "${azurerm_lb.lb.id}" + name = "${var.dns_name}-ilbBackendPool" +} + +# ********************** LOAD BALANCER INBOUND NAT RULES ********************** # +resource "azurerm_lb_nat_rule" "NatRule0" { + name = "${var.dns_name}-NatRule-${count.index}" + resource_group_name = "${azurerm_resource_group.rg.name}" + loadbalancer_id = "${azurerm_lb.lb.id}" + protocol = "tcp" + frontend_port = "6400${count.index + 1}" + backend_port = 22 + frontend_ip_configuration_name = "${var.dns_name}-sshIPCfg" + count = "${var.node_count}" + depends_on = ["azurerm_lb.lb"] +} + +resource "azurerm_lb_nat_rule" "MySQLNatRule0" { + name = "${var.dns_name}-MySQLNatRule-${count.index}" + resource_group_name = "${azurerm_resource_group.rg.name}" + loadbalancer_id = "${azurerm_lb.lb.id}" + protocol = "tcp" + frontend_port = "330${count.index + 6}" + backend_port = 3306 + frontend_ip_configuration_name = "${var.dns_name}-sshIPCfg" + count = "${var.node_count}" + depends_on = ["azurerm_lb.lb"] +} + +resource "azurerm_lb_nat_rule" "ProbeNatRule0" { + name = "${var.dns_name}-ProbeNatRule-${count.index}" + resource_group_name = "${azurerm_resource_group.rg.name}" + loadbalancer_id = "${azurerm_lb.lb.id}" + protocol = "tcp" + frontend_port = "920${count.index}" + backend_port = 9200 + frontend_ip_configuration_name = "${var.dns_name}-sshIPCfg" + count = "${var.node_count}" + depends_on = ["azurerm_lb.lb"] +} + +# ********************** VIRTUAL MACHINES ********************** # +resource "azurerm_virtual_machine" "vm" { + name = "${var.dns_name}${count.index}" + resource_group_name = "${azurerm_resource_group.rg.name}" + location = "${azurerm_resource_group.rg.location}" + vm_size = "${var.vm_size}" + network_interface_ids = ["${element(azurerm_network_interface.nic.*.id, count.index)}"] + count = "${var.node_count}" + availability_set_id = "${azurerm_availability_set.availability_set.id}" + depends_on = ["azurerm_availability_set.availability_set", "azurerm_network_interface.nic", "azurerm_storage_account.stor"] + + storage_image_reference { + publisher = "${var.image_publisher}" + offer = "${var.image_offer}" + sku = "${var.os_version}" + version = "latest" + } + + storage_os_disk { + name = "osdisk${count.index}" + vhd_uri = "https://${azurerm_storage_account.stor.name}.blob.core.windows.net/vhds/${var.dns_name}${count.index}-osdisk.vhd" + create_option = "FromImage" + caching = "ReadWrite" + } + + os_profile { + computer_name = "${var.dns_name}${count.index}" + admin_username = "${var.vm_admin_username}" + admin_password = "${var.vm_admin_password}" + } + + storage_data_disk { + name = "datadisk1" + vhd_uri = "https://${azurerm_storage_account.stor.name}.blob.core.windows.net/vhds/${var.dns_name}${count.index}-datadisk1.vhd" + disk_size_gb = "1000" + create_option = "Empty" + lun = 0 + } + + storage_data_disk { + name = "datadisk2" + vhd_uri = "https://${azurerm_storage_account.stor.name}.blob.core.windows.net/vhds/${var.dns_name}${count.index}-datadisk2.vhd" + disk_size_gb = "1000" + create_option = "Empty" + lun = 1 + } + + os_profile_linux_config { + disable_password_authentication = false + } +} + +resource "azurerm_virtual_machine_extension" "setup_mysql" { + name = "${var.dns_name}-${count.index}-setupMySQL" + resource_group_name = "${azurerm_resource_group.rg.name}" + location = "${azurerm_resource_group.rg.location}" + virtual_machine_name = "${element(azurerm_virtual_machine.vm.*.name, count.index)}" + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + auto_upgrade_minor_version = true + count = "${var.node_count}" + depends_on = ["azurerm_virtual_machine.vm", "azurerm_lb_nat_rule.ProbeNatRule0"] + + settings = <