Skip to content

Commit

Permalink
provider/azurerm: Example of Wordpress MySql Replication (#15260)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
anniehedgpeth authored and stack72 committed Jun 13, 2017
1 parent 48e0052 commit b97603f
Show file tree
Hide file tree
Showing 7 changed files with 729 additions and 0 deletions.
41 changes: 41 additions & 0 deletions examples/wordpress-mysql-replication/README.md
Original file line number Diff line number Diff line change
@@ -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/<YOUR-SUB-ID-HERE>/resourceGroups/<existing-resource-group-name>/providers/Microsoft.Network/virtualNetworks/<existing-vnet-name>
```

## 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.
56 changes: 56 additions & 0 deletions examples/wordpress-mysql-replication/deploy.ci.sh
Original file line number Diff line number Diff line change
@@ -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;"
15 changes: 15 additions & 0 deletions examples/wordpress-mysql-replication/deploy.mac.sh
Original file line number Diff line number Diff line change
@@ -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
244 changes: 244 additions & 0 deletions examples/wordpress-mysql-replication/main.tf
Original file line number Diff line number Diff line change
@@ -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 = <<SETTINGS
{
"fileUris": ["${var.artifacts_location}${var.azuremysql_script}"]
}
SETTINGS

protected_settings = <<SETTINGS
{
"commandToExecute": "bash azuremysql.sh ${count.index + 1} 10.0.1.${count.index + 4} ${var.artifacts_location}${var.mysql_cfg_file_path} '${var.mysql_replication_password}' '${var.mysql_root_password}' '${var.mysql_probe_password}' 10.0.1.4 ${var.unique_prefix}wordpress"
}
SETTINGS
}
23 changes: 23 additions & 0 deletions examples/wordpress-mysql-replication/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
output "resource_group" {
value = "${var.resource_group}"
}

output "fqdn" {
value = "${azurerm_public_ip.pip.fqdn}"
}

output "azure_website" {
value = "http://${var.dns_name}.azurewebsites.net"
}

output "ip_address" {
value = "${azurerm_public_ip.pip.ip_address}"
}

output "ssh_command_master" {
value = "ssh ${var.vm_admin_username}@${azurerm_public_ip.pip.ip_address} -p 64001"
}

output "ssh_command_slave" {
value = "ssh ${var.vm_admin_username}@${azurerm_public_ip.pip.ip_address} -p 64002"
}
Loading

0 comments on commit b97603f

Please sign in to comment.