Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Okstad <pokstad@gitlab.com>2020-03-20 17:56:04 +0300
committerPaul Okstad <pokstad@gitlab.com>2020-03-20 17:56:04 +0300
commitf7c8c91595cb70cdf7ab3c808e834dbebcc62eb7 (patch)
tree0eb9d3a81658a23949c38b5afbc2b2e77cc76e35
parente5a36f23ce83b498ae4f125f49c9539fcf776ede (diff)
parent26bc162bf9c66eaf26b9453e744136d8e580aa18 (diff)
Merge branch 'jv-terraform' into 'master'
Automate some of the Gitaly HA demo setup See merge request gitlab-org/gitaly!1902
-rw-r--r--_support/terraform/.gitignore3
-rw-r--r--_support/terraform/README.md60
-rwxr-xr-x_support/terraform/create-demo-cluster69
-rwxr-xr-x_support/terraform/destroy-demo-cluster12
-rw-r--r--_support/terraform/helper.rb12
-rw-r--r--_support/terraform/main.tf189
-rwxr-xr-x_support/terraform/print-info12
-rw-r--r--_support/terraform/terraform.tfvars.erb5
8 files changed, 362 insertions, 0 deletions
diff --git a/_support/terraform/.gitignore b/_support/terraform/.gitignore
new file mode 100644
index 000000000..5a6a4426c
--- /dev/null
+++ b/_support/terraform/.gitignore
@@ -0,0 +1,3 @@
+/.terraform*
+/*.tfstate*
+/terraform.tfvars
diff --git a/_support/terraform/README.md b/_support/terraform/README.md
new file mode 100644
index 000000000..75aafe8fa
--- /dev/null
+++ b/_support/terraform/README.md
@@ -0,0 +1,60 @@
+# terraform for gitaly ha demo
+
+## Creating a demo cluster
+
+### 1. Install Google Cloud SDK
+
+- For most platforms, including macOS, use the [official
+ guide](https://cloud.google.com/sdk/docs/quickstarts)
+- For Arch Linux, go to [this
+ AUR](https://aur.archlinux.org/packages/google-cloud-sdk)
+
+### 2. Install Terraform
+
+On macOS with homebrew, use `brew install terraform`. For other
+platforms see [the Terraform download
+page](https://www.terraform.io/downloads.html).
+
+### 3. Run the script
+
+```
+./create-demo-cluster
+```
+
+This will open a browser to sign into GCP if necessary. Terraform will
+print a plan and ask you to confirm it before it creates anything in
+GCP.
+
+When the script is done, `apt-get install gitlab-ee` is still busy
+running in the background on your new VM's.
+
+### 4. Manually create a CloudSQL instance
+
+In principle Terraform can also create a CloudSQL instance for
+Praefect but this is still work in progress. In the meantime, please
+use the GCP web UI to create a CloudSQL Postgres instance for
+Praefect.
+
+### 5. Use SSH to manually configure the hosts
+
+Updating the config for all the demo cluster hosts is not yet
+automated. Please follow the documentation at
+https://docs.gitlab.com/ee/administration/gitaly/praefect.html.
+
+To see the list of IP's for your machines, run:
+
+```
+./print-info
+```
+
+## Destroying a demo cluster
+
+When you run the command below Terraform will print a plan of things
+to destroy, that you then have to confirm (or abort with Ctrl-C).
+
+Be careful! Double check how many nodes are being destroyed, and what
+their names are.
+
+```
+./destroy-demo-cluster
+```
diff --git a/_support/terraform/create-demo-cluster b/_support/terraform/create-demo-cluster
new file mode 100755
index 000000000..4c59c9163
--- /dev/null
+++ b/_support/terraform/create-demo-cluster
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require 'erb'
+require 'etc'
+
+require_relative 'helper.rb'
+
+TFVARS = 'terraform.tfvars'
+
+def main
+ unless gcloud_appliction_default_logged_in?
+ run!(%w[gcloud auth application-default login])
+ end
+
+ unless terraform_initialized?
+ run!(%w[terraform init])
+ end
+
+ unless File.exist?(TFVARS)
+ render!(TFVARS, 'terraform.tfvars.erb')
+ end
+
+ run!(%w[terraform apply])
+end
+
+def praefect_demo_cluster_name
+ default_name = "#{username}-#{Time.now.utc.strftime('%Y%m%d')}"
+ get_input('Enter a name for your demo cluster', default_name)
+end
+
+def username
+ Etc.getlogin
+end
+
+def ssh_pubkey
+ default_path = File.join(Etc.getpwnam(username).dir, '.ssh/id_rsa.pub')
+ pubkey_path = get_input('Enter the path to your SSH public key', default_path)
+ pubkey = File.read(pubkey_path).chomp
+
+ unless pubkey.start_with?('ssh-')
+ # Protect against accidentally using the private key
+ abort "contents of #{path} do not look like an SSH pubkey"
+ end
+
+ pubkey
+end
+
+def get_input(prompt, default)
+ puts "#{prompt} (default: #{default})."
+ print "> "
+
+ input = gets.chomp
+ input.empty? ? default : input
+end
+
+def render!(file, template_path)
+ IO.write(file, ERB.new(File.read(template_path)).result(binding))
+end
+
+def gcloud_appliction_default_logged_in?
+ system(
+ *%w[gcloud auth application-default print-access-token],
+ out: '/dev/null',
+ err: '/dev/null'
+ )
+end
+
+main
diff --git a/_support/terraform/destroy-demo-cluster b/_support/terraform/destroy-demo-cluster
new file mode 100755
index 000000000..88e7f81f7
--- /dev/null
+++ b/_support/terraform/destroy-demo-cluster
@@ -0,0 +1,12 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require_relative 'helper.rb'
+
+def main
+ return unless terraform_any_machines?
+
+ run!(%w[terraform destroy])
+end
+
+main
diff --git a/_support/terraform/helper.rb b/_support/terraform/helper.rb
new file mode 100644
index 000000000..eddccbf33
--- /dev/null
+++ b/_support/terraform/helper.rb
@@ -0,0 +1,12 @@
+require 'json'
+
+require_relative '../run.rb'
+
+def terraform_initialized?
+ File.exist?('.terraform')
+end
+
+def terraform_any_machines?
+ state = JSON.parse(capture!(%w[terraform show -json]))
+ state.has_key?('values')
+end
diff --git a/_support/terraform/main.tf b/_support/terraform/main.tf
new file mode 100644
index 000000000..66c6b594f
--- /dev/null
+++ b/_support/terraform/main.tf
@@ -0,0 +1,189 @@
+variable "demo_region" { default = "us-east4" }
+variable "demo_zone" { default = "us-east4-c" }
+variable "praefect_demo_cluster_name" { }
+variable "ssh_user" {}
+variable "ssh_pubkey" { }
+variable "os_image" { default = "ubuntu-os-cloud/ubuntu-1804-lts" }
+variable "startup_script" {
+ default = <<EOF
+ set -e
+ if [ -d /opt/gitlab ] ; then exit; fi
+
+ curl -s https://packages.gitlab.com/install/repositories/gitlab/nightly-builds/script.deb.sh | sudo bash
+ sudo apt-get install -y gitlab-ee
+ EOF
+}
+variable "gitaly_machine_type" { default = "n1-standard-2" }
+#variable "praefect_sql_password" {}
+
+provider "google" {
+ version = "~> 3.12"
+
+ project = "gitlab-internal-153318"
+ region = var.demo_region
+ zone = var.demo_zone
+}
+
+# resource "google_sql_database_instance" "praefect_sql" {
+# name = format("%s-praefect-postgresql", var.praefect_demo_cluster_name)
+# database_version = "POSTGRES_9_6"
+# region = var.demo_region
+#
+# settings {
+# # Second-generation instance tiers are based on the machine
+# # type. See argument reference below.
+# tier = "db-f1-micro"
+# }
+# }
+#
+# output "praefect_postgresql_ip" {
+# value = google_sql_database_instance.praefect_sql.public_ip_address
+# }
+
+# resource "google_sql_user" "users" {
+# name = "praefect"
+# instance = google_sql_database_instance.praefect_sql.name
+# password = var.praefect_sql_password
+# }
+
+resource "google_compute_instance" "gitlab" {
+ name = format("%s-gitlab", var.praefect_demo_cluster_name)
+ machine_type = "n1-standard-2"
+
+ boot_disk {
+ initialize_params {
+ image = var.os_image
+ }
+ }
+
+ network_interface {
+ subnetwork = "default"
+ access_config {}
+ }
+
+ metadata = {
+ ssh-keys = format("%s:%s", var.ssh_user, var.ssh_pubkey)
+ startup-script = var.startup_script
+ }
+
+ tags = ["http-server", "https-server"]
+}
+
+output "gitlab_internal_ip" {
+ value = google_compute_instance.gitlab.network_interface[0].network_ip
+}
+output "gitlab_external_ip" {
+ value = google_compute_instance.gitlab.network_interface[0].access_config[0].nat_ip
+}
+
+resource "google_compute_instance" "praefect" {
+ name = format("%s-praefect", var.praefect_demo_cluster_name)
+ machine_type = "n1-standard-1"
+
+ boot_disk {
+ initialize_params {
+ image = var.os_image
+ }
+ }
+
+ network_interface {
+ subnetwork = "default"
+ access_config {}
+ }
+
+ metadata = {
+ ssh-keys = format("%s:%s", var.ssh_user, var.ssh_pubkey)
+ startup-script = var.startup_script
+ }
+}
+
+output "praefect_internal_ip" {
+ value = google_compute_instance.praefect.network_interface[0].network_ip
+}
+output "praefect_ssh_ip" {
+ value = google_compute_instance.praefect.network_interface[0].access_config[0].nat_ip
+}
+
+resource "google_compute_instance" "gitaly_1" {
+ name = format("%s-gitaly-1", var.praefect_demo_cluster_name)
+ machine_type = var.gitaly_machine_type
+
+ boot_disk {
+ initialize_params {
+ image = var.os_image
+ }
+ }
+
+ network_interface {
+ subnetwork = "default"
+ access_config {}
+ }
+
+ metadata = {
+ ssh-keys = format("%s:%s", var.ssh_user, var.ssh_pubkey)
+ startup-script = var.startup_script
+ }
+}
+
+output "gitaly_1_internal_ip" {
+ value = google_compute_instance.gitaly_1.network_interface[0].network_ip
+}
+output "gitaly_1_ssh_ip" {
+ value = google_compute_instance.gitaly_1.network_interface[0].access_config[0].nat_ip
+}
+
+resource "google_compute_instance" "gitaly_2" {
+ name = format("%s-gitaly-2", var.praefect_demo_cluster_name)
+ machine_type = var.gitaly_machine_type
+
+ boot_disk {
+ initialize_params {
+ image = var.os_image
+ }
+ }
+
+ network_interface {
+ subnetwork = "default"
+ access_config {}
+ }
+
+ metadata = {
+ ssh-keys = format("%s:%s", var.ssh_user, var.ssh_pubkey)
+ startup-script = var.startup_script
+ }
+}
+
+output "gitaly_2_internal_ip" {
+ value = google_compute_instance.gitaly_2.network_interface[0].network_ip
+}
+output "gitaly_2_ssh_ip" {
+ value = google_compute_instance.gitaly_2.network_interface[0].access_config[0].nat_ip
+}
+
+resource "google_compute_instance" "gitaly_3" {
+ name = format("%s-gitaly-3", var.praefect_demo_cluster_name)
+ machine_type = var.gitaly_machine_type
+
+ boot_disk {
+ initialize_params {
+ image = var.os_image
+ }
+ }
+
+ network_interface {
+ subnetwork = "default"
+ access_config {}
+ }
+
+ metadata = {
+ ssh-keys = format("%s:%s", var.ssh_user, var.ssh_pubkey)
+ startup-script = var.startup_script
+ }
+}
+
+output "gitaly_3_internal_ip" {
+ value = google_compute_instance.gitaly_3.network_interface[0].network_ip
+}
+output "gitaly_3_ssh_ip" {
+ value = google_compute_instance.gitaly_3.network_interface[0].access_config[0].nat_ip
+}
diff --git a/_support/terraform/print-info b/_support/terraform/print-info
new file mode 100755
index 000000000..852404725
--- /dev/null
+++ b/_support/terraform/print-info
@@ -0,0 +1,12 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require_relative 'helper.rb'
+
+def main
+ return unless terraform_any_machines?
+
+ run!(%w[terraform output])
+end
+
+main
diff --git a/_support/terraform/terraform.tfvars.erb b/_support/terraform/terraform.tfvars.erb
new file mode 100644
index 000000000..73bd7778b
--- /dev/null
+++ b/_support/terraform/terraform.tfvars.erb
@@ -0,0 +1,5 @@
+# This variable will be prefixed to all machines created by terraform
+praefect_demo_cluster_name = "<%= praefect_demo_cluster_name %>"
+
+ssh_user = "<%= username %>"
+ssh_pubkey = "<%= ssh_pubkey %>"