Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new demo module #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
73 changes: 73 additions & 0 deletions gcp/demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# PTFE (External Services) resource provisioner - GCP

Provisions the necessary GCP resources for the External Services installation type.

## Resources

* google_compute_instance.ptfe1
* google_compute_instance.ptfe2
* google_sql_database_instance.pes
* google_storage_bucket.pes

## Architecture

### Application Layer

The `network` module uses a data source to discover healthy availability zones and returns them as a list:

```hcl
data "google_compute_zones" "main" {
status = "UP"
}
```

The resulting list is passed into the `pes` module as the `zone` variable. The first two availability zones in the list are used as locations for two VM instances (**ptfe1** and **ptfe2**) ensuring they are in different availability zones:

```hcl
resource "google_compute_instance" "ptfe1" {
zone = "${var.zone[0]}"
}

resource "google_compute_instance" "ptfe2" {
zone = "${var.zone[1]}"
}
```

Conditional logic is used to assign an active alias IP to the active VM instance, which is defined by a Terraform variable:

```hcl
variable "active_ptfe_instance" {
description = "The active PTFE instance ie ptfe1 or ptfe2"
default = "ptfe1"
}

variable "active_alias_ip" {
description = "Alias IP attached to the active PTFE VM instance"
}

variable "standby_alias_ip" {
description = "Alias IP attached to the standby PTFE VM instance"
}

resource "google_compute_instance" "ptfe1" {
network_interface {
alias_ip_range = {
ip_cidr_range = "${var.active_ptfe_instance == "ptfe1" ? var.active_alias_ip : var.standby_alias_ip}/32"
}
}
}

resource "google_compute_instance" "ptfe2" {
network_interface {
alias_ip_range = {
ip_cidr_range = "${var.active_ptfe_instance == "ptfe2" ? var.active_alias_ip : var.standby_alias_ip}/32"
}
}
}
```

Using the above conditional logic, the `active_alias_ip` can be switched between `ptfe1` and `ptfe2` by changing the value of `active_ptfe_instance` and performing a Terraform run. This could be done manually or automatically following an availability zone failure. Note that the Terraform run would likely produce an error as it will fail to update the configuration of the compute VM instance in the failed availability zone, but the change to the available compute VM instance would succeed.

### Storage Layer

Google Cloud SQL (PostgreSQL) and Google Cloud Storage are configured with `REGIONAL` availability and resiliency, resulting in both services remaining available in the event of an availability zone failure. The Google Cloud Platform documentation provides more information on the exact behaviour of each service during an availability zone failure.
39 changes: 39 additions & 0 deletions gcp/demo/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#------------------------------------------------------------------------------
# production external-services ptfe resources
#------------------------------------------------------------------------------

locals {
namespace = "${var.namespace}-demo"
}

resource "google_compute_instance" "ptfe" {
name = "${local.namespace}-instance-ptfe"
machine_type = "${var.gcp_machine_type}"
zone = "${var.zone[0]}"

boot_disk {
initialize_params {
size = 100
image = "${var.gcp_machine_image}"
}
}

network_interface {
access_config = {}
subnetwork = "${var.subnetwork}"
}

metadata_startup_script = "${var.startup_script}"

service_account {
scopes = ["https://www.googleapis.com/auth/sqlservice.admin"]
}

allow_stopping_for_update = true

provisioner "local-exec" {
command = " gcloud compute ssh --zone ${var.zone[0]} ${google_compute_instance.ptfe.name} --command 'sudo /tmp/install_ptfe.sh no-proxy bypass-storagedriver-warnings ' "
}


}
3 changes: 3 additions & 0 deletions gcp/demo/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "vm_instance_name" {
value = "${google_compute_instance.ptfe.name}"
}
14 changes: 14 additions & 0 deletions gcp/demo/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
variable "namespace" {}
variable "region" {}

variable "zone" {
type = "list"
}

variable "gcp_machine_image" {}
variable "gcp_machine_type" {}
variable "subnetwork" {}
variable "active_ptfe_instance" {}
variable "active_alias_ip" {}
variable "standby_alias_ip" {}
variable "startup_script" {}
78 changes: 43 additions & 35 deletions gcp/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ terraform {
}

provider "google" {
credentials = "${file("service_account.json")}"
project = "${var.project}"
region = "${var.region}"
#credentials = "${file("service_account.json")}"
project = "${var.project}"
region = "${var.region}"
}

resource "google_compute_project_metadata_item" "ssh_key" {
Expand All @@ -30,22 +30,25 @@ module "network" {
# demo/poc ptfe
#------------------------------------------------------------------------------

#module "demo" {
# source = "demo/"
# namespace = "${var.namespace}"
# aws_instance_ami = "${var.aws_instance_ami}"
# aws_instance_type = "${var.aws_instance_type}"
# subnet_id = "${module.network.subnet_ids[0]}"
# vpc_security_group_ids = "${module.network.security_group_id}"
# user_data = ""
# ssh_key_name = "${var.ssh_key_name}"
# hashidemos_zone_id = "${data.aws_route53_zone.hashidemos.zone_id}"
#}
module "demo" {
source = "demo/"
namespace = "${var.namespace}"
region = "${var.region}"
zone = "${module.network.available_zones}"
subnetwork = "${module.network.private_subnet_self_link}"
active_ptfe_instance = "${var.active_ptfe_instance}"
active_alias_ip = "${var.active_alias_ip}"
standby_alias_ip = "${var.standby_alias_ip}"
gcp_machine_type = "${var.gcp_machine_type}"
gcp_machine_image = "${var.gcp_machine_image}"
startup_script = "${var.startup_script}"
}

#------------------------------------------------------------------------------
# production mounted disk ptfe
#------------------------------------------------------------------------------


#module "pmd" {
# source = "pmd/"
# namespace = "${var.namespace}"
Expand All @@ -58,33 +61,38 @@ module "network" {
# hashidemos_zone_id = "${data.aws_route53_zone.hashidemos.zone_id}"
#}


#------------------------------------------------------------------------------
# production external-services ptfe
#------------------------------------------------------------------------------

module "pes" {
source = "pes/"
namespace = "${var.namespace}"
region = "${var.region}"
zone = "${module.network.available_zones}"
subnetwork = "${module.network.private_subnet_self_link}"
active_ptfe_instance = "${var.active_ptfe_instance}"
active_alias_ip = "${var.active_alias_ip}"
standby_alias_ip = "${var.standby_alias_ip}"
gcp_machine_type = "${var.gcp_machine_type}"
gcp_machine_image = "${var.gcp_machine_image}"
}

#module "pes" {
# source = "pes/"
# namespace = "${var.namespace}"
# region = "${var.region}"
# zone = "${module.network.available_zones}"
# subnetwork = "${module.network.private_subnet_self_link}"
# active_ptfe_instance = "${var.active_ptfe_instance}"
# active_alias_ip = "${var.active_alias_ip}"
# standby_alias_ip = "${var.standby_alias_ip}"
# gcp_machine_type = "${var.gcp_machine_type}"
# gcp_machine_image = "${var.gcp_machine_image}"
#}


#------------------------------------------------------------------------------
# bastion host
#------------------------------------------------------------------------------

module "bastion" {
source = "bastion/"
namespace = "${var.namespace}"
region = "${var.region}"
zone = "${module.network.available_zones}"
subnetwork = "${module.network.private_subnet_self_link}"
gcp_machine_type = "${var.gcp_machine_type}"
gcp_machine_image = "${var.gcp_machine_image}"
}

#module "bastion" {
# source = "bastion/"
# namespace = "${var.namespace}"
# region = "${var.region}"
# zone = "${module.network.available_zones}"
# subnetwork = "${module.network.private_subnet_self_link}"
# gcp_machine_type = "${var.gcp_machine_type}"
# gcp_machine_image = "${var.gcp_machine_image}"
#}

2 changes: 2 additions & 0 deletions gcp/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/*
output "private_subnet_id" {
value = "${module.network.private_subnet_id}"
}

output "db_connection_name" {
value = "${module.pes.db_connection_name}"
}
*/
10 changes: 10 additions & 0 deletions gcp/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
region = "europe-west1"
project = "gb-playground"
namespace = "guy-ptfe"
gcp_machine_image = "debian-cloud/debian-9-stretch-v20180814"
gcp_machine_type = "n1-standard-4"
ssh_user = "guy"
ssh_public_key_file = "/Users/guy/.ssh/id_rsa.pub"
active_ptfe_instance = "ptfe1"
active_alias_ip = "10.1.0.5"
standby_alias_ip = "10.1.0.6"
10 changes: 10 additions & 0 deletions gcp/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,13 @@ variable "ssh_user" {
variable "ssh_public_key_file" {
description = "Path to SSH public key file for VM instance access eg /home/user/.ssh/id_rsa.pub"
}

variable "startup_script" {
description = "what to run at startup"
type = "string"
default = <<EOS
#!/bin/bash -xe
curl https://install.terraform.io/ptfe/stable > /tmp/install_ptfe.sh
sudo chmod 500 /tmp/install_ptfe.sh
EOS
}