├── .gitignore ├── resources ├── server.hcl └── install.sh ├── variables.tf.example ├── nomad.tf └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | nomad.plan 2 | terraform.tfstate 3 | terraform.tfstate.backup 4 | variables.tf 5 | 6 | -------------------------------------------------------------------------------- /resources/server.hcl: -------------------------------------------------------------------------------- 1 | # Increase log verbosity 2 | log_level = "DEBUG" 3 | 4 | # Setup data dir 5 | data_dir = "/tmp/server" 6 | 7 | # Enable the server 8 | server { 9 | enabled = true 10 | 11 | # Self-elect, should be 3 or 5 for production 12 | bootstrap_expect = 3 13 | } 14 | 15 | client { 16 | enabled = true 17 | } 18 | 19 | -------------------------------------------------------------------------------- /resources/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | NOMAD_VERSION=`curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/attributes/nomad_version"` 3 | 4 | # Update apt and get dependencies 5 | sudo apt-get update 6 | sudo apt-get install -y unzip curl wget 7 | 8 | # Install Docker 9 | sudo curl -sSL https://get.docker.com/ | sh 10 | 11 | # Download Nomad 12 | echo Fetching Nomad... 13 | cd /tmp/ 14 | wget https://releases.hashicorp.com/nomad/${NOMAD_VERSION}/nomad_${NOMAD_VERSION}_linux_amd64.zip -O nomad.zip 15 | 16 | echo Installing Nomad... 17 | unzip nomad.zip 18 | sudo chmod +x nomad 19 | sudo mv nomad /usr/bin/nomad 20 | 21 | sudo mkdir /etc/nomad.d 22 | sudo chmod a+w /etc/nomad.d 23 | 24 | -------------------------------------------------------------------------------- /variables.tf.example: -------------------------------------------------------------------------------- 1 | ## credential stuff 2 | # path to the account file 3 | variable "account_file" { 4 | default = "/path/to/account.json" 5 | } 6 | # the username to connect with 7 | variable "gce_ssh_user" { 8 | default = "user" 9 | } 10 | # the private key of the user 11 | variable "gce_ssh_private_key_file" { 12 | default = "/home/user/.ssh/google_compute_engine" 13 | } 14 | 15 | ## google project stuff 16 | # the google region where the cluster should be created 17 | variable "region" { 18 | default = "europe-west1" 19 | } 20 | # the google zone where the cluster should be created 21 | variable "zone" { 22 | default = "europe-west1-d" 23 | } 24 | # the name of the google project 25 | variable "project" { 26 | default = "myproject" 27 | } 28 | # image to use for installation 29 | variable "image" { 30 | default = "ubuntu-os-cloud/ubuntu-1504-vivid-v20150911" 31 | } 32 | variable "machine_type" { 33 | default = "g1-small" 34 | } 35 | 36 | ## network stuff 37 | # the address of the subnet in CIDR 38 | variable "network" { 39 | default = "10.11.12.0/24" 40 | } 41 | # public local address for unlimited access to the cluster, in CIDR 42 | variable "localaddress" { 43 | default = "0.0.0.0" 44 | } 45 | 46 | # the name of the cluster 47 | variable "name" { 48 | default = "nomad" 49 | } 50 | 51 | # the version of nomad to use 52 | variable "nomad_version" { 53 | default = "0.1.0" 54 | } 55 | 56 | -------------------------------------------------------------------------------- /nomad.tf: -------------------------------------------------------------------------------- 1 | # provider stuff for connecting to google 2 | provider "google" { 3 | credentials = "${file("${var.credentials}")}" 4 | project = "${var.project}" 5 | region = "${var.region}" 6 | } 7 | 8 | # the instance 9 | resource "google_compute_instance" "nomad-node" { 10 | count = "${var.numberofnodes}" 11 | name = "nomad${count.index+1}" 12 | machine_type = "${var.machine_type}" 13 | zone = "${var.zone}" 14 | 15 | disk { 16 | image = "${var.image}" 17 | type = "pd-ssd" 18 | } 19 | 20 | # network interface 21 | network_interface { 22 | network = "${google_compute_network.nomad-net.name}" 23 | access_config { 24 | // ephemeral address 25 | } 26 | } 27 | 28 | # nomad version 29 | metadata { 30 | nomad_version = "${var.nomad_version}" 31 | } 32 | 33 | # define default connection for remote provisioners 34 | connection { 35 | user = "${var.gce_ssh_user}" 36 | key_file = "${var.gce_ssh_private_key_file}" 37 | agent = "false" 38 | } 39 | 40 | # copy files 41 | provisioner "file" { 42 | source = "resources/server.hcl" 43 | destination = "/home/${var.gce_ssh_user}/server.hcl" 44 | } 45 | 46 | # install 47 | provisioner "remote-exec" { 48 | scripts = [ 49 | "resources/install.sh" 50 | ] 51 | } 52 | } 53 | 54 | resource "google_compute_network" "nomad-net" { 55 | name = "${var.name}-net" 56 | ipv4_range ="${var.network}" 57 | } 58 | 59 | resource "google_compute_firewall" "nomad-ssh" { 60 | name = "${var.name}-nomad-ssh" 61 | network = "${google_compute_network.nomad-net.name}" 62 | 63 | allow { 64 | protocol = "tcp" 65 | ports = ["22"] 66 | } 67 | 68 | target_tags = ["ssh"] 69 | source_ranges = ["0.0.0.0/0"] 70 | } 71 | 72 | resource "google_compute_firewall" "nomad-internal" { 73 | name = "${var.name}-nomad-internal" 74 | network = "${google_compute_network.nomad-net.name}" 75 | 76 | allow { 77 | protocol = "tcp" 78 | ports = ["1-65535"] 79 | } 80 | allow { 81 | protocol = "udp" 82 | ports = ["1-65535"] 83 | } 84 | allow { 85 | protocol = "icmp" 86 | } 87 | 88 | source_ranges = ["${google_compute_network.nomad-net.ipv4_range}","${var.localaddress}"] 89 | 90 | } 91 | 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Container Solutions Terraform Nomad 2 | 3 | How to set up a Nomad cluster on the Google Cloud using Terraform 4 | 5 | ### Install Terraform 6 | 7 | * These scripts require Terraform 0.6.3 or greater 8 | * Follow the instructions on to set up Terraform on your machine. 9 | 10 | ### Get your Google Cloud JSON Key 11 | - Visit https://console.developers.google.com 12 | - Navigate to APIs & Auth -> Credentials -> Service Account -> Generate new JSON key 13 | - The file will be downloaded to your machine 14 | 15 | ### Get Google Cloud SDK 16 | - Visit https://cloud.google.com/sdk/ 17 | - Install the SDK, login and authenticate with your Google Account. 18 | 19 | ### Add your SSH key to the Project Metadata 20 | - Back in the Developer Console, go to Compute - Compute Engine - Metadata and click the SSH Keys tab. Add your public SSH key there. 21 | - Use the path to the private key and the username in the next step as `gce_ssh_user` and `gce_ssh_private_key_file` 22 | 23 | ### Prepare variables.tf 24 | 25 | Copy the`variables.tf.example` file to `varables.tf` and adjust to your situation 26 | 27 | ### Create Terraform plan 28 | 29 | Create the plan and save it to a file. 30 | 31 | ``` 32 | terraform plan -out my.plan 33 | ``` 34 | 35 | ### Create the cluster 36 | 37 | Once you are satisfied with the plan, apply it. 38 | 39 | ``` 40 | terraform apply my.plan 41 | ``` 42 | 43 | ### Start nomad on every node 44 | 45 | Log in to every node. There is a default server.hcl there, copied from the resources dir, that you can use to start the node. 46 | Start the agent, specifying the address of eth0 to bind to. 47 | 48 | `sudo nomad agent -config server.hcl -bind=10.11.12.4` 49 | 50 | Execute this on every node, the agent needs to be running on all of them. 51 | 52 | ### Join the nodes 53 | 54 | From one of the nodes, connect to the others. 55 | 56 | `nomad server-join -address http://$OTHER_SERVER:4646 $MYADDRESS` 57 | 58 | You should see the node joining in the logs. Repeat this step for all nodes in the cluster. 59 | 60 | ### Set environment variable 61 | 62 | To be able to reach the agent, export the NOMAD_ADDR variable. 63 | 64 | `export NOMAD_ADDR="http://nomad1:4646"` 65 | 66 | ### Destroy the cluster 67 | When you're done, clean up the cluster with 68 | ``` 69 | terraform destroy 70 | ``` 71 | 72 | ## To do 73 | 74 | - Automate starting of nomad daemon 75 | - Discover other nodes 76 | - Automating joining of other nodes 77 | 78 | 79 | --------------------------------------------------------------------------------