Skip to content

Instantly share code, notes, and snippets.

@smithclay
Created July 19, 2017 19:57
Show Gist options
  • Save smithclay/2d11c2fc2f4584a87ac97574262f91c9 to your computer and use it in GitHub Desktop.
Save smithclay/2d11c2fc2f4584a87ac97574262f91c9 to your computer and use it in GitHub Desktop.
Multi-Cloud New Relic Blog Post: Terraform Configuration of AWS, Azure and GCP Load Balancers with Instance Groups (Autoscaling enabled)
variable "aws_region" {
description = "EC2 Region for the VPC"
default = "us-west-2"
}
variable "aws_availability_zones" {
default = "us-west-2a,us-west-2b,us-west-2c"
description = "List of availability zones, use AWS CLI to find your "
}
# TODO: replace with local file
variable "aws_key_name" {
description = "Desired name of AWS key pair"
default = "cloudrace"
}
# Custom AMI Created with Packer
variable "aws_amis" {
default = {
us-west-2 = "ami-7d342804"
}
}
# Specify the provider and access details
provider "aws" {
region = "${var.aws_region}"
}
# Create a VPC to launch our instances into
resource "aws_vpc" "default" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
}
# Create an internet gateway to give our subnet access to the outside world
resource "aws_internet_gateway" "default" {
vpc_id = "${aws_vpc.default.id}"
}
# Grant the VPC internet access on its main route table
resource "aws_route" "internet_access" {
route_table_id = "${aws_vpc.default.main_route_table_id}"
destination_cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.default.id}"
}
# Create a subnet to launch our instances into
resource "aws_subnet" "default" {
vpc_id = "${aws_vpc.default.id}"
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
}
resource "aws_security_group" "elb" {
name = "web_elb_sg"
vpc_id = "${aws_vpc.default.id}"
# HTTP access from anywhere
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# outbound internet access
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
# ensure the VPC has an Internet gateway or this step will fail
depends_on = ["aws_internet_gateway.default"]
}
resource "aws_elb" "web_elb" {
name = "webelb"
# The same availability zone as our instances
/*availability_zones = ["${split(",", var.aws_availability_zones)}"]*/
subnets = ["${aws_subnet.default.id}"]
security_groups = ["${aws_security_group.elb.id}"]
listener {
instance_port = "${var.cloudrace_service_port}"
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
health_check {
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 3
target = "HTTP:${var.cloudrace_service_port}/health"
interval = 10
}
}
resource "aws_autoscaling_group" "web_asg" {
#availability_zones = ["${split(",", var.aws_availability_zones)}"]
name = "web_asg"
max_size = "3"
min_size = "1"
desired_capacity = "${var.instances_count}"
force_delete = true
launch_configuration = "${aws_launch_configuration.web_lc.name}"
load_balancers = ["${aws_elb.web_elb.name}"]
vpc_zone_identifier = ["${aws_subnet.default.id}"]
tag {
key = "Name"
value = "awsweb_asg"
propagate_at_launch = "true"
}
}
data "aws_ami" "custom" {
most_recent = true
filter {
name = "name"
values = ["ubuntu-host-cloudrace*"]
}
}
resource "aws_launch_configuration" "web_lc" {
name = "web_lc"
image_id = "${data.aws_ami.custom.image_id}"
instance_type = "t2.nano"
# Security group
security_groups = ["${aws_security_group.default.id}"]
key_name = "${var.aws_key_name}"
}
# Our default security group to access
# the instances over SSH and HTTP
resource "aws_security_group" "default" {
name = "terraform_example_sg"
vpc_id = "${aws_vpc.default.id}"
# SSH access from anywhere
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# HTTP access from anywhere
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# HTTP access from anywhere
ingress {
from_port = "${var.cloudrace_service_port}"
to_port = "${var.cloudrace_service_port}"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# outbound internet access
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
variable "azure_subscription_id" {}
variable "azure_client_id" {}
variable "azure_client_secret" {}
variable "azure_tenant_id" {}
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."
default = "azweb"
}
variable "location" {
description = "The location/region where the virtual network is created. Changing this forces a new resource to be created."
default = "westcentralus"
}
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 = "Standard_LRS"
}
variable "image_uri" {
description = "packer-created VHD for the VM"
default = "https://tfimages.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.c8c51b67-99b1-43cf-86be-2e550994b6b4.vhd"
}
variable "vmss_name" {
description = "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended."
default = "azweb0"
}
variable "vm_size" {
description = "Specifies the size of the virtual machine."
default = "Standard_A0"
}
variable "admin_username" {
description = "administrator user name"
default = "ubuntu"
}
variable "admin_password" {
description = "administrator password (recommended to disable password auth)"
default = "insert-secure-password-here"
}
provider "azurerm" {
subscription_id = "${var.azure_subscription_id}"
client_id = "${var.azure_client_id}"
client_secret = "${var.azure_client_secret}"
tenant_id = "${var.azure_tenant_id}"
}
resource "azurerm_resource_group" "rg" {
name = "cloudrace_rg"
location = "${var.location}"
}
resource "azurerm_virtual_network" "vnet" {
name = "${var.rg_prefix}vnet"
location = "${azurerm_resource_group.rg.location}"
address_space = ["10.0.0.0/16"]
resource_group_name = "${azurerm_resource_group.rg.name}"
}
resource "azurerm_subnet" "subnet" {
name = "subnet"
address_prefix = "10.0.0.0/24"
resource_group_name = "${azurerm_resource_group.rg.name}"
virtual_network_name = "${azurerm_virtual_network.vnet.name}"
}
resource "azurerm_public_ip" "pip" {
name = "${var.hostname}-pip"
location = "${azurerm_resource_group.rg.location}"
resource_group_name = "${azurerm_resource_group.rg.name}"
public_ip_address_allocation = "Dynamic"
domain_name_label = "${var.hostname}"
}
resource "azurerm_lb" "weblb" {
name = "LoadBalancer"
location = "${azurerm_resource_group.rg.location}"
resource_group_name = "${azurerm_resource_group.rg.name}"
depends_on = ["azurerm_public_ip.pip"]
frontend_ip_configuration {
name = "LBFrontEnd"
public_ip_address_id = "${azurerm_public_ip.pip.id}"
}
}
resource "azurerm_lb_backend_address_pool" "backlb" {
name = "BackEndAddressPool"
resource_group_name = "${azurerm_resource_group.rg.name}"
loadbalancer_id = "${azurerm_lb.weblb.id}"
}
resource "azurerm_lb_nat_pool" "np" {
resource_group_name = "${azurerm_resource_group.rg.name}"
loadbalancer_id = "${azurerm_lb.weblb.id}"
name = "NATPool"
protocol = "Tcp"
frontend_port_start = 50000
frontend_port_end = 50119
backend_port = 22
frontend_ip_configuration_name = "LBFrontEnd"
}
resource "azurerm_lb_rule" "web" {
resource_group_name = "${azurerm_resource_group.rg.name}"
loadbalancer_id = "${azurerm_lb.weblb.id}"
name = "LBRule"
protocol = "Tcp"
frontend_port = 80
backend_port = "${var.cloudrace_service_port}"
backend_address_pool_id = "${azurerm_lb_backend_address_pool.backlb.id}"
frontend_ip_configuration_name = "LBFrontEnd"
probe_id = "${azurerm_lb_probe.lb_probe.id}"
depends_on = ["azurerm_lb_probe.lb_probe", "azurerm_lb_backend_address_pool.backlb"]
}
resource "azurerm_lb_probe" "lb_probe" {
resource_group_name = "${azurerm_resource_group.rg.name}"
loadbalancer_id = "${azurerm_lb.weblb.id}"
name = "httpProbe"
protocol = "Http"
request_path = "/health"
port = "${var.cloudrace_service_port}"
interval_in_seconds = 10
number_of_probes = 2
}
resource "azurerm_virtual_machine_scale_set" "scalesetd" {
name = "azwebscale"
location = "${azurerm_resource_group.rg.location}"
resource_group_name = "${azurerm_resource_group.rg.name}"
upgrade_policy_mode = "Manual"
overprovision = true
depends_on = ["azurerm_lb.weblb", "azurerm_virtual_network.vnet"]
sku {
name = "${var.vm_size}"
tier = "Standard"
capacity = "${var.instances_count}"
}
os_profile {
computer_name_prefix = "${var.vmss_name}"
admin_username = "${var.admin_username}"
admin_password = "${var.admin_password}"
}
os_profile_linux_config {
disable_password_authentication = false
}
network_profile {
name = "${var.hostname}-nic"
primary = true
ip_configuration {
name = "${var.hostname}ipconfig"
subnet_id = "${azurerm_subnet.subnet.id}"
load_balancer_backend_address_pool_ids = ["${azurerm_lb_backend_address_pool.backlb.id}"]
load_balancer_inbound_nat_rules_ids = ["${element(azurerm_lb_nat_pool.np.*.id, count.index)}"]
}
}
storage_profile_os_disk {
name = "packer-osDisk.247bd425-f041-48cc-acc0-48848e6842e0.vhd"
caching = "ReadWrite"
create_option = "FromImage"
image = "${var.image_uri}"
os_type = "linux"
}
}
variable "region" {
default = "us-central1"
}
variable "region_zone" {
default = "us-central1-f"
}
variable "project_name" {
description = "The ID of the Google Cloud project"
default = "c4-cloud-test"
}
# Custom Image created via Packer
variable "gcp_image_name" {
description = "image name"
default = "packer-1500055284"
}
variable "credentials_file_path" {
description = "Path to the JSON file used to describe your account credentials"
default = "~/.ssh/compute-engine-google.json"
}
variable "public_key_path" {
description = "Path to file containing public key"
default = "~/.ssh/id_rsa_cloudrace.pub"
}
variable "private_key_path" {
description = "Path to file containing private key"
default = "~/.ssh/id_rsa_cloudrace"
}
provider "google" {
region = "${var.region}"
project = "${var.project_name}"
credentials = "${file("${var.credentials_file_path}")}"
}
resource "google_compute_network" "cloudrace-network" {
name = "cloudrace-network"
}
resource "google_compute_subnetwork" "cloudrace-subnet" {
name = "cloudrace-subnet"
ip_cidr_range = "10.0.2.0/24"
network = "${google_compute_network.cloudrace-network.self_link}"
region = "${var.region}"
}
resource "google_compute_firewall" "allow-all-internal" {
name = "allow-all-10-2-0-0-20"
network = "${google_compute_network.cloudrace-network.name}"
allow {
protocol = "tcp"
}
allow {
protocol = "udp"
}
allow {
protocol = "icmp"
}
source_ranges = ["10.0.2.0/24"]
}
resource "google_compute_backend_service" "cloudrace_backend" {
name = "cloudracebackend"
port_name = "http"
protocol = "HTTP"
timeout_sec = 10
enable_cdn = false
backend {
group = "${google_compute_instance_group_manager.cloudrace_webservers.instance_group}"
}
health_checks = ["${google_compute_http_health_check.default.self_link}"]
}
resource "google_compute_http_health_check" "default" {
name = "http-test"
request_path = "/health"
port = "${var.cloudrace_service_port}"
timeout_sec = 3
check_interval_sec = 10
healthy_threshold = 2
unhealthy_threshold = 2
}
resource "google_compute_instance_group_manager" "cloudrace_webservers" {
name = "gcpweb"
instance_template = "${google_compute_instance_template.web_template.self_link}"
base_instance_name = "gcpweb"
zone = "${var.region_zone}"
target_size = "${var.instances_count}"
named_port {
name = "http"
port = "${var.cloudrace_service_port}"
}
}
resource "google_compute_instance_template" "web_template" {
name = "gcpweb"
machine_type = "f1-micro"
region = "${var.region}"
tags = ["web"]
disk {
source_image = "${var.gcp_image_name}"
auto_delete = true
boot = true
}
network_interface {
subnetwork = "${google_compute_subnetwork.cloudrace-subnet.name}"
access_config {
# Ephemeral
}
}
metadata {
ssh-keys = "root:${file("${var.public_key_path}")}"
}
}
resource "google_compute_firewall" "allow-ssh-http-icmp" {
name = "allow-tcp22-tcp80-tcp8080-icmp"
network = "${google_compute_network.cloudrace-network.name}"
allow {
protocol = "tcp"
ports = ["22", "80", "8080"]
}
allow {
protocol = "icmp"
}
source_ranges = ["0.0.0.0/0"]
target_tags = ["web"]
}
resource "google_compute_global_forwarding_rule" "default" {
name = "tf-www-forwarding-rule"
target = "${google_compute_target_http_proxy.default.self_link}"
port_range = "80"
}
resource "google_compute_target_http_proxy" "default" {
name = "test-proxy"
description = "a description"
url_map = "${google_compute_url_map.default.self_link}"
}
resource "google_compute_url_map" "default" {
name = "url-map"
description = "a description"
default_service = "${google_compute_backend_service.cloudrace_backend.self_link}"
}
@SARUNAR
Copy link

SARUNAR commented Nov 29, 2017

have you tried spinning all the three clouds with one command

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment