├── variables.tf ├── helm ├── install-helm-tiller.sh └── tiller-rbac-config.yml ├── terraform.tfvars ├── k8s_prep.sh ├── LICENSE ├── main.tf └── README.md /variables.tf: -------------------------------------------------------------------------------- 1 | variable "raspberrypi_ip" {} 2 | variable "username" {} 3 | variable "password" {} 4 | variable "new_hostname" {} 5 | variable "new_password" {} 6 | variable "timezone" {} 7 | variable "static_ip_and_mask" {} 8 | variable "static_router" {} 9 | variable "static_dns" {} -------------------------------------------------------------------------------- /helm/install-helm-tiller.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This installs Helm and Tiller components into an 4 | # existing Raspberri Pi Kubernetes cluster. 5 | 6 | wget https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-arm.tar.gz 7 | tar xvzf helm-v2.12.3-linux-arm.tar.gz 8 | sudo mv linux-arm/helm /bin/helm 9 | Rm -rf linux-arm 10 | 11 | kubectl apply -f tiller-rbac-config.yml 12 | 13 | helm init --tiller-image=clayshek/tiller-arm --service-account tiller 14 | -------------------------------------------------------------------------------- /helm/tiller-rbac-config.yml: -------------------------------------------------------------------------------- 1 | # Kubernetes service account and RBAC config for Tiller 2 | # Run: kubectl apply -f tiller-rbac-config.yml 3 | --- 4 | apiVersion: v1 5 | kind: ServiceAccount 6 | metadata: 7 | name: tiller 8 | namespace: kube-system 9 | --- 10 | apiVersion: rbac.authorization.k8s.io/v1beta1 11 | kind: ClusterRoleBinding 12 | metadata: 13 | name: tiller 14 | roleRef: 15 | apiGroup: rbac.authorization.k8s.io 16 | kind: ClusterRole 17 | name: cluster-admin 18 | subjects: 19 | - kind: ServiceAccount 20 | name: tiller 21 | namespace: kube-system 22 | -------------------------------------------------------------------------------- /terraform.tfvars: -------------------------------------------------------------------------------- 1 | # Terraform Variables 2 | # Customize parameters in this file specific to your deployment. 3 | # Current & new passwords can be supplied here, but safer to supply variables inline when applying config: 4 | # terraform apply -var 'password=PASSWORD' -var 'new_password=NEWPASS' 5 | 6 | # CONNECTION PARAMETERS 7 | raspberrypi_ip = "192.168.1.131" 8 | username = "pi" 9 | password = "raspberry" 10 | 11 | # CONIGURATION PARAMETERS 12 | new_hostname = "" 13 | new_password = "" 14 | # Validate timezone correctness against 'timedatectl list-timezones' 15 | timezone = "America/New_York" 16 | 17 | # NETWORK CONFIGURATION PARAMETERS 18 | # See man dhcpcd.conf for further info and examples. 19 | # Get these right or risk loss of network connectivity. 20 | static_ip_and_mask = "192.168.1.20/24" 21 | static_router = "192.168.1.1" 22 | static_dns = "192.168.1.1" -------------------------------------------------------------------------------- /k8s_prep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This installs the base instructions up to the point of joining / creating a cluster 4 | # Based off of https://gist.github.com/alexellis/fdbc90de7691a1b9edb545c17da2d975 5 | 6 | curl -sSL get.docker.com | sh && \ 7 | sudo usermod pi -aG docker 8 | 9 | sudo dphys-swapfile swapoff && \ 10 | sudo dphys-swapfile uninstall && \ 11 | sudo update-rc.d dphys-swapfile remove 12 | 13 | curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - && \ 14 | echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list && \ 15 | sudo apt-get update -q && \ 16 | sudo apt-get install -qy kubeadm 17 | 18 | echo Adding " cgroup_enable=cpuset cgroup_memory=1" to /boot/cmdline.txt 19 | 20 | sudo cp /boot/cmdline.txt /boot/cmdline_backup.txt 21 | orig="$(head -n1 /boot/cmdline.txt) cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1" 22 | echo $orig | sudo tee /boot/cmdline.txt 23 | 24 | echo Please reboot 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Clay Shekleton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | # Raspberry Pi Terraform Bootstrap Provisioner (Tested with Raspbian Stretch). 2 | # This is a run-once bootstrap Terraform provisioner for a Raspberry Pi. 3 | # Provisioners by default run only at resource creation, additional runs without cleanup may introduce problems. 4 | # https://www.terraform.io/docs/provisioners/index.html 5 | 6 | resource "null_resource" "raspberry_pi_bootstrap" { 7 | connection { 8 | type = "ssh" 9 | user = "${var.username}" 10 | password = "${var.password}" 11 | host = "${var.raspberrypi_ip}" 12 | } 13 | 14 | provisioner "remote-exec" { 15 | inline = [ 16 | # SET HOSTNAME 17 | "sudo hostnamectl set-hostname ${var.new_hostname}", 18 | "echo '127.0.1.1 ${var.new_hostname}' | sudo tee -a /etc/hosts", 19 | 20 | # DATE TIME CONFIG 21 | "sudo timedatectl set-timezone ${var.timezone}", 22 | "sudo timedatectl set-ntp true", 23 | 24 | # CHANGE DEFAULT PASSWORD 25 | "echo 'pi:${var.new_password}' | sudo chpasswd", 26 | 27 | # SYSTEM AND PACKAGE UPDATES 28 | "sudo apt-get update -y", 29 | "sudo apt-get upgrade -y", 30 | "sudo apt-get dist-upgrade -y", 31 | "sudo apt --fix-broken install -y", 32 | 33 | # INSTALL PROMETHEUS NODE EXPORTER 34 | # This step optional, comment out this section if not desired 35 | "sudo apt-get install prometheus-node-exporter -y", 36 | "sudo systemctl enable prometheus-node-exporter.service", 37 | 38 | # NETWORKING - SET STATIC IP 39 | "echo 'interface eth0\nstatic ip_address=${var.static_ip_and_mask}\nstatic routers=${var.static_router}\nstatic domain_name_servers=${var.static_dns}' | cat >> /etc/dhcpcd.conf", 40 | 41 | # COPY KUBERNETES PREP SCRIPT 42 | "curl https://raw.githubusercontent.com/clayshek/terraform-raspberrypi-bootstrap/master/k8s_prep.sh > /home/pi/k8s_prep.sh", 43 | "chmod u+x k8s_prep.sh", 44 | 45 | # COPY HELM & TILLER SETUP 46 | "curl https://raw.githubusercontent.com/clayshek/terraform-raspberrypi-bootstrap/master/helm/tiller-rbac-config.yml > /home/pi/helm/tiller-rbac-config.yml", 47 | "curl https://raw.githubusercontent.com/clayshek/terraform-raspberrypi-bootstrap/master/helm/install-helm-tiller.sh > /home/pi/helm/install-helm-tiller.sh", 48 | "chmod u+x helm/install-helm-tiller.sh", 49 | 50 | # OPTIMIZE GPU MEMORY 51 | "echo 'gpu_mem=16' | sudo tee -a /boot/config.txt", 52 | 53 | # REBOOT 54 | # Changed from 'sudo reboot' to 'sudo shutdown -r +0' to address exit status issue encountered 55 | # after Terraform 0.11.3, see https://github.com/hashicorp/terraform/issues/17844 56 | "sudo shutdown -r +0" 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-raspberrypi-bootstrap 2 | 3 | NOTE: Though still functional, I've replaced this functionality with Ansible and a better provisioning model IMO: https://github.com/clayshek/raspi-ubuntu-ansible 4 | 5 | ## Summary 6 | 7 | Terraform Provisioner for bootstrapping a Raspberry Pi base configuration. This is meant to be a run-once bootstrap Terraform provisioner for a vanilla Raspberry Pi. Provisioners by default run only at resource creation, additional runs without cleanup may introduce problems. 8 | 9 | In addtion to bootstrapping, this provisioner also: 10 | 11 | - Installs Prometheus Node Exporter for Prometheus metrics collection 12 | - Copies the k8s_prep.sh script from this repository to /home/pi/ to optionally install & configure prerequisites for latest ARM release of Kubernetes, including Docker, based off of https://gist.github.com/alexellis/fdbc90de7691a1b9edb545c17da2d975. 13 | - Copies the helm/install-helm-tiller.sh script from this repo which downloads Helm client, configures Kubernetes RBAC prerequisites, and initiates Helm with an ARM compatible Tiller Docker image. 14 | 15 | 16 | ## Requirements 17 | 18 | - Terraform (written with v0.11.3, tested working up to 0.11.11) 19 | - A newly flashed Raspberry Pi (tested with Raspbian Stretch Lite through 2018-11-13 release, should work with prior version Jessie) 20 | - SSH access to Pi, See Enable SSH on a headless Raspberry Pi 21 | 22 | ## Usage 23 | 24 | - Clone the repository 25 | - Customize the parameters in the terraform.tfvars file as applicable for provisioning. 26 | - Run terraform init (required for first run). 27 | - Apply the configuration: 28 | 29 | ``` 30 | terraform apply 31 | ``` 32 | 33 | - Optional, run ./k8s_prep.sh to install Kubernetes and prerequisites, including Docker. 34 | 35 | - Optional, once Kubernetes cluster online and functional, run ./helm/install-helm-tiller.sh to install Helm/Tiller. 36 | 37 | ## To-Do 38 | 39 | - [X] Add Prometheus Node Exporter install. 40 | - [X] Add Helm & Tiller init scripts 41 | - [ ] Possibly add functionality for multiple Raspberry Pi deployments from a single run, using variables with count. 42 | - [ ] Implement tests. 43 | 44 | ## License 45 | 46 | This is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT). 47 | --------------------------------------------------------------------------------