Skip to content

Commit

Permalink
SQL Always On (#470)
Browse files Browse the repository at this point in the history
This is the terraform template to create the infrastructure needed to deploy MS SQL Always On within OCI. The template implements the infrastructure as defined in the OCI whitepaper about to be published on this subject. New pull request will be submitted once the URL is known.
  • Loading branch information
nelsonse authored and briangustafson committed Mar 16, 2018
1 parent 7c9cab1 commit b5e1872
Show file tree
Hide file tree
Showing 46 changed files with 1,448 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1 +1,42 @@
## Coming Soon!
# ___ ____ _ ____ _ _____
# / _ \| _ \ / \ / ___| | | ____|
# | | | | |_) | / _ \| | | | | _|
# | |_| | _ < / ___ | |___| |___| |___
# \___/|_| \_/_/ \_\____|_____|_____|
***

# MS SQL Always On

This Terraform template implements the infrastructure needed to fully deploy an MS SQL Always On cluster across availability domains. The cluster can be spread across either 2 or 3 ADs, depending on your requirements, but cannot be located in a single AD.

The template is configured by modifying the variables contained in two files:

- configuration.tf - generalized configuration for the environment as a whole.
- sql.tf - configuration specific to the implementation of MS SQL Always On.

To configure, simply edit these two files, apply values that are appropriate to your environment, and run 'terraform plan; terraform apply'. Before attempting to run the template, setup your environment by performing the following:

- Edit the env-vars file.
- Set the values indicated in the file
- Source the file into your existing environment by running:

. ./env-vars

Some items of note:

- This has only been tested using Windows 2012 R2 images. The template and accompanying whitepaper has not been deployed using Windows 2016 Datacenter within the OCI environment.
- The image OCID listed in the configuration.tf file is the one used for testing. You should update this with the image OCID of the latest revision of Windows 2012 R2. For a list of image OCIDs, see https://docs.us-phoenix-1.oraclecloud.com/Content/Resources/Assets/OracleProvidedImageOCIDs.pdf
- If you choose *NOT* to specify an existing compartment in which to deploy MS SQL Always On, one will be created for you. Understand that compartments, once created, *CANNOT* be destroyed.
- Do not edit any of the files other than configuration.tf and sql.tf. Look, but touch at your own peril.
- The template itself has been tested against Terraform version 0.11.3 and OCI Provider 2.0.6. Running against older versions of both Terraform and the provider may provide unpredicable results.
- For this template to work, you must identify your OCI Home Region. This may be different than the region in which you are deploying this template. To identify your home region, do the following:
- Log into the OCI console for the tenancy in which you are going to deploy.
- In the upper left hand side of the console there is a hyperlink that highlights your tenancy name. Click on the hyperlink.
- On the left hand side of the resulting web page is a field labeled "Home Region". This is the value to insert into the env-vars file.
- The infrastructure can be deployed in multiple compartments, or within the same compartment by specifying a unique, non-empty value in the 'label-prefix' variable contained in configuration.tf. If deploying multiple times in the same compartment, this must be done in order to prevent confusion.

A sample ConfigurationFile.ini file has been included for SQL. Use at your own discretion.

Remember, this *ONLY* deploys the infrastructure needed to build MS SQL Always On, and *DOES NOT* perform the installation and configuration needed at the operating system. That is covered as an exercise left to the reader in the OCI SQL Always On Deployment guide (URL TBD).

Enjoy and happy SQL'ing!
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# configuration.tf - General configuration of SQL Always On deployment
# Set variables here to meet your needs within your particular environment
# Check both this file and sql.tf!

# image_id - OCID of the Windows image to use. This image is the basis for
# all instances deployed for SQL Always On
# BE SURE TO UPDATE WITH MOST CURRENT LIST OF WINDOWS 2012 or 2016 IMAGES.
# These are the current images for Windows 2012 R2.
variable "image_id" {
type = "map"
default = {
us-phoenix-1 = "ocid1.image.oc1.phx.aaaaaaaak7y2ojnh6uteltilfcoziymglfordtitx5pixefkymlcxhjjf67q"
us-ashburn-1 = "ocid1.image.oc1.iad.aaaaaaaad53p62uzibzsj6gm7szrbbtap6acgev7funbo7ghr2stcrholqxa"
eu-frankfurt-1 = "ocid1.image.oc1.eu-frankfurt1.aaaaaaaabd3goasbc74pfphlyysurtvgox55ryngz5r6tpwnpkx5kddvud6q"
}
}




# vcn_dns_name - Set the domain zone, e.g. <vcn_dns_name>.oraclevcn.com .
variable "vcn_dns_name" {
default = "SQLAlwaysOn"
}

# label_prefix - Set a unique prefix for all resources. Only required if
# deploying multiple clusters within the same compartment.
variable "label_prefix" {
default = ""
}

# vcn_cidr_block - Set IP address pool for the VCN being created for SQL AO.
variable "vcn_cidr_block" {
default = "10.0.0.0/19"
}

# compartment_name - Set the compartment to use for the configuration.
# If the compartment does not exist, it will be created.
# NOTE: Compartments CANNOT be destroyed once created
variable "compartment_name" {
default = "SQLAlwaysOn"
}

# compartment_description - Set a short description for the compartment.
# Only used for new compartments.
variable "compartment_description" {
default = "Compartment created for SQL Always On deployment"
}

# ad_count - Set number of ADs to use. Minimum 2, Maximum 3.
variable "ad_count" {
default = "3"
}

# local_dns_server - Set the address to use for the local DNS server.
variable "local_dns_server" {
default = "1.1.1.1"
}

# Adminsitrative instance shapes definition.
# Change only if necessary.
# dmz_shape - Shape to use for DMZ server
variable "dmz_shape" {
default = "VM.Standard1.2"
}

# admin_shape - Shape to use for Administrative server.
variable "admin_shape" {
default = "VM.Standard1.4"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
data "oci_identity_availability_domains" "ADs" {
compartment_id = "${var.tenancy_ocid}"
}

data "oci_identity_compartments" "compartment" {
compartment_id = "${var.tenancy_ocid}"
filter {
name = "name"
values = [ "${var.compartment_name}" ]
regex = true
}
}
13 changes: 13 additions & 0 deletions docs/solutions/sql_server_always_on_availability_groups/env-vars
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

# OCI Account authentication information
export TF_VAR_tenancy_ocid=<Tenancy OCID>
export TF_VAR_user_ocid=<OCI User OCID that will deploy SQL AO>
export TF_VAR_region=<Region to deploy SQL AO>
export TF_VAR_private_key_path=<Private portion of API key associated with user>
export TF_VAR_fingerprint=<Fingerprint of public portion of API key>
export TF_VAR_private_key_password=<Private key password, if set, otherwise "">

# Additional information required by TF template
export TF_VAR_home_region=<Home Region - may be different than above>
export TF_VAR_ssh_public_key=<public portion of SSH key used to log into instance>
166 changes: 166 additions & 0 deletions docs/solutions/sql_server_always_on_availability_groups/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
module "vcn" {
source = "./modules/network/vcn"
compartment_ocid = "${module.compartment.id}"
label_prefix = "${var.label_prefix}"
vcn_dns_name = "${var.vcn_dns_name}"
vcn_cidr_block = "${var.vcn_cidr_block}"
local_dns_server = "${var.local_dns_server}"
}

module "compartment" {
source = "./modules/iam/compartment"
compartment_name = "${var.compartment_name}"
compartment_description = "${var.compartment_description}"
}

module "securitylist" {
source = "./modules/network/securitylist"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
DMZ_prefix = "${local.DMZ_prefix}"
ADMIN_prefix = "${local.ADMIN_prefix}"
SQL_prefix = "${local.SQL_prefix}"
}

module "dmz_subnets" {
dns_label = "DMZ"
cidr_block = "${local.DMZ_subnets_cidrs}"
source = "./modules/network/subnet"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
ad_count = "${var.ad_count}"
route_table_id = "${module.vcn.rt_id}"
dhcp_options_id = "${module.vcn.internet_dhcp_options_id}"
security_list_id = ["${module.securitylist.dmz_id}"]
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
}

module "admin_subnets" {
dns_label = "ADMIN"
cidr_block = "${local.ADMIN_subnets_cidrs}"
source = "./modules/network/subnet"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
ad_count = "${var.ad_count}"
route_table_id = "${module.vcn.rt_id}"
dhcp_options_id = "${module.vcn.internet_dhcp_options_id}"
security_list_id = ["${module.securitylist.admin_id}"]
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
private = "true"
}

module "sql_subnets" {
dns_label = "SQL"
cidr_block = "${local.SQL_subnets_cidrs}"
source = "./modules/network/subnet"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
ad_count = "${var.ad_count}"
route_table_id = "${module.vcn.rt_id}"
dhcp_options_id = "${module.vcn.internet_dhcp_options_id}"
security_list_id = ["${module.securitylist.sql_id}"]
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
private = "true"
}

module "witness_subnets" {
dns_label = "Witness"
cidr_block = "${local.Witness_subnets_cidrs}"
source = "./modules/network/subnet"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
ad_count = "1"
route_table_id = "${module.vcn.rt_id}"
dhcp_options_id = "${module.vcn.internet_dhcp_options_id}"
security_list_id = ["${module.securitylist.sql_id}"]
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
private = "true"
ad_deployment = "${var.witness_deployment}"
}

module "volumes" {
source = "./modules/storage/volume"
compartment_ocid = "${module.compartment.id}"
ad_count = "${var.ad_count}"
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
ad_deployment = "${var.witness_deployment}"
sql_db_size = "${var.sql_db_size}"
sql_log_size = "${var.sql_log_size}"
sql_backup_size = "${var.sql_backup_size}"
witness_volume_size = "${var.witness_volume_size}"
ad_deployment = "${var.witness_deployment}"
}

module "dmz_hosts" {
dns_label = "Bastion"
subnets = "${module.dmz_subnets.subnet_id}"
source = "./modules/instances/bastion/"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
ad_count = "${var.ad_count}"
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
image_id = "${var.image_id[var.region]}"
shape = "${var.dmz_shape}"
}

module "admin_hosts" {
dns_label = "DC"
subnets = "${module.admin_subnets.subnet_id}"
source = "./modules/instances/active_directory/"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
ad_count = "${var.ad_count}"
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
image_id = "${var.image_id[var.region]}"
shape = "${var.admin_shape}"
}

module "sql_hosts" {
dns_label = "SQL"
ad_count = "${var.ad_count}"
subnets = "${module.sql_subnets.subnet_id}"
source = "./modules/instances/sql/"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
image_id = "${var.image_id[var.region]}"
shape = "${var.sql_shape}"
db_volumes = "${module.volumes.sql_db_id}"
log_volumes = "${module.volumes.sql_log_id}"
backup_volumes = "${module.volumes.sql_backup_id}"
}

module "witness_hosts" {
dns_label = "WITNESS"
subnets = "${module.witness_subnets.subnet_id}"
source = "./modules/instances/witness/"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
ad_count = "${var.ad_count}"
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
image_id = "${var.image_id[var.region]}"
shape = "${var.witness_shape}"
witness_volumes = "${module.volumes.witness_id}"
ad_deployment = "${var.witness_deployment}"
}

module "secondaryIPs" {
dns_label = "SQL"
subnets = "${module.sql_subnets.subnet_id}"
source = "./modules/network/secondaryip/"
compartment_ocid = "${module.compartment.id}"
vcn_id = "${module.vcn.vcn_id}"
ad_count = "${var.ad_count}"
label_prefix = "${var.label_prefix}"
tenancy_ocid = "${var.tenancy_ocid}"
vnic_ids = "${module.sql_hosts.vnic_ids}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "oci_identity_compartment" "compartment" {
provider = "oci.home"
name = "${var.compartment_name}"
description = "${var.compartment_description}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "id" {
value = "${oci_identity_compartment.compartment.id}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
variable "compartment_name" {}
variable "compartment_description" {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Cloud call to get a list of Availability Domains
data "oci_identity_availability_domains" "ADs" {
compartment_id = "${var.tenancy_ocid}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
resource "oci_core_instance" "instance" {
count = "${var.ad_count}"
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains["${count.index}"],"name")}"
compartment_id = "${var.compartment_ocid}"
display_name = "${var.dns_label}${"${count.index}" + 1}"
hostname_label = "${var.dns_label}${"${count.index}" + 1}"
image = "${var.image_id}"
shape = "${var.shape}"

create_vnic_details {
subnet_id = "${var.subnets["${count.index}"]}"
skip_source_dest_check = true
assign_public_ip = false
}

timeouts {
create = "60m"
}

provisioner "local-exec" {
command = "sleep 10"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "private_ip" {
value = "${oci_core_instance.instance.*.private_ip}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
variable "subnets" {
type = "list"
}

variable "ad_count" {}
variable "label_prefix" {}
variable "compartment_ocid" {}
variable "vcn_id" {}
variable "tenancy_ocid" {}
variable "dns_label" {}
variable "image_id" {}
variable "shape" {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Cloud call to get a list of Availability Domains
data "oci_identity_availability_domains" "ADs" {
compartment_id = "${var.tenancy_ocid}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
resource "oci_core_instance" "instance" {
count = "${var.ad_count}"
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains["${count.index}"],"name")}"
compartment_id = "${var.compartment_ocid}"
display_name = "${var.dns_label}${"${count.index}" + 1}"
hostname_label = "${var.dns_label}${"${count.index}" + 1}"
image = "${var.image_id}"
shape = "${var.shape}"

create_vnic_details {
subnet_id = "${var.subnets["${count.index}"]}"
skip_source_dest_check = true
assign_public_ip = true
}

timeouts {
create = "60m"
}

provisioner "local-exec" {
command = "sleep 10"
}
}

0 comments on commit b5e1872

Please sign in to comment.