Skip to content

Commit 0422294

Browse files
committed
Initial commit
Signed-off-by: solidnerd <[email protected]>
0 parents  commit 0422294

File tree

11 files changed

+371
-0
lines changed

11 files changed

+371
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.terraform.*
2+
.terraform/
3+
terraform.tfstate*
4+
terraform.tfvars
5+
.auto.tfvars
6+
.DS_Store
7+
secrets/

README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Terraform Kubernetes on Hetzner Cloud
2+
3+
This repository will help to setup an opionated Kubernetes Cluster with [kubeadm](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/) on [Hetzner Cloud](https://www.hetzner.com/cloud?country=us).
4+
5+
## Usage
6+
7+
```
8+
$ git clone https://github.com/solidnerd/terraform-k8s-hcloud.git
9+
$ ./install-plugin.sh
10+
$ terraform init
11+
$ terraform apply
12+
```
13+
14+
## Example
15+
16+
```
17+
$ ./install-plugin.sh
18+
$ terraform init
19+
$ terraform apply
20+
$ KUBECONFIG=secrets/admin.conf kubectl get nodes
21+
$ KUBECONFIG=secrets/admin.conf kubectl apply -f https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml
22+
$ KUBECONFIG=secrets/admin.conf kubectl get pods --namespace=kube-system -o wide
23+
$ KUBECONFIG=secrets/admin.conf kubectl run nginx --image=nginx
24+
$ KUBECONFIG=secrets/admin.conf kubectl expose deploy nginx --port=80 --type NodePort
25+
```
26+
27+
## Variables
28+
29+
| Name | Default | Description | Required |
30+
|:-------------------------|:-------------|:----------------------------------------------------------------------------------|:--------:|
31+
| `hcloud_token` | `` |API Token that will be generated through your hetzner cloud project https://console.hetzner.cloud/projects | Yes |
32+
| `master_count` | `1` | Amount of masters that will be created | No |
33+
| `master_image` | `ubuntu-16.04` | Predefined Image that will be used to spin up the machines (Currently supported: ubuntu-16.04, debian-9,centos-7,fedora-27) | No |
34+
| `master_type` | `cx11` | Machine type for more types have a look at https://www.hetzner.de/cloud | No |
35+
| `node_count` | `1` | Amount of nodes that will be created | No |
36+
| `node_image` | `ubuntu-16.04` | Predefined Image that will be used to spin up the machines (Currently supported: ubuntu-16.04, debian-9,centos-7,fedora-27) |
37+
| `node_type` | `cx11` | Machine type for more types have a look at https://www.hetzner.de/cloud | No |
38+
| `ssh_private_key` | `~/.ssh/id_ed25519` | Private Key to access the machines |
39+
| `ssh_public_key` | `~/.ssh/id_ed25519.pub` | Public Key to authorized the access for the machines | No |
40+
| `docker_version` | `17.03` | Docker CE version that will be installed | No |
41+
| `kubernetes_version` | `1.10.0` | Kubernetes version that will be installed | No |
42+
| `core_dns` | `false` | Enables CoreDNS as Service Discovery | No |
43+
44+
All variables cloud be passed through `environment variables` or a `tfvars` file.
45+
46+
An example for a `tfvars` file would be the following `terraform.tfvars`
47+
48+
```toml
49+
# terraform.tfvars
50+
hcloud_token = "<yourgeneratedtoken>"
51+
master_type = "cx21"
52+
master_count = 1
53+
node_type = "cx31"
54+
node_count = 2
55+
kubernetes_version = "1.9.6"
56+
docker_version = "17.03"
57+
```
58+
59+
Or passing directly via Arguments
60+
61+
```console
62+
$ terraform apply \
63+
-var hcloud_token="<yourgeneratedtoken>"
64+
-var docker_version=17.03
65+
-var kubernetes_version=1.9.6
66+
-var master_type=cx21
67+
-var master_count=1
68+
-var node_type=cx31
69+
-var node_count=2
70+
```
71+
72+
73+
## Contributing
74+
75+
### Bug Reports & Feature Requests
76+
77+
Please use the [issue tracker](https://github.com/solidnerd/terraform-k8s-hcloud/issues) to report any bugs or file feature requests.
78+
79+
80+
**Tested with**
81+
- Terraform [v0.11.5](https://github.com/hashicorp/terraform/tree/v0.11.5)
82+
- provider.hcloud [v1.1.0](https://github.com/hetznercloud/terraform-provider-hcloud/tree/v1.1.0)

files/10-kubeadm.conf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[Service]
2+
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cgroup-driver=cgroupfs"
3+
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true"
4+
Environment="KUBELET_NETWORK_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
5+
Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10 --cluster-domain=cluster.local"
6+
Environment="KUBELET_AUTHZ_ARGS=--authorization-mode=Webhook --client-ca-file=/etc/kubernetes/pki/ca.crt"
7+
Environment="KUBELET_CADVISOR_ARGS=--cadvisor-port=0"
8+
Environment="KUBELET_CERTIFICATE_ARGS=--rotate-certificates=true --cert-dir=/var/lib/kubelet/pki"
9+
ExecStart=
10+
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_AUTHZ_ARGS $KUBELET_CADVISOR_ARGS $KUBELET_CERTIFICATE_ARGS $KUBELET_EXTRA_ARGS

install-plugin.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
set -eu
3+
OS=${OS:-darwin}
4+
HCLOUD_VERSION=${HCLOUD_VERSION:-1.1.0}
5+
HCLOUD_TERRAFORM_URL=${HCLOUD_TERRAFORM_URL:-"https://github.com/hetznercloud/terraform-provider-hcloud/releases/download/v${HCLOUD_VERSION}/terraform-provider-hcloud_v${HCLOUD_VERSION}_${OS}_amd64.zip"}
6+
echo "Install Terraform plugin from:"
7+
echo "$HCLOUD_TERRAFORM_URL"
8+
curl -sSL $HCLOUD_TERRAFORM_URL -o terraform-provider-hcloud_v${HCLOUD_VERSION}_${OS}_amd64.zip
9+
10+
unzip -d /tmp/terraform-provider-hcloud_v${HCLOUD_VERSION}_${OS}_amd64 terraform-provider-hcloud_v${HCLOUD_VERSION}_${OS}_amd64.zip
11+
12+
mkdir -p ~/.terraform.d/plugins/
13+
14+
mv -v /tmp/terraform-provider-hcloud_v${HCLOUD_VERSION}_${OS}_amd64/terraform-provider-hcloud ~/.terraform.d/plugins/terraform-provider-hcloud

main.tf

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
provider "hcloud" {
2+
token = "${var.hcloud_token}"
3+
}
4+
5+
resource "hcloud_ssh_key" "k8s_admin" {
6+
name = "k8s_admin"
7+
public_key = "${file(var.ssh_public_key)}"
8+
}
9+
10+
resource "hcloud_server" "master" {
11+
count = "${var.master_count}"
12+
name = "master-${count.index + 1}"
13+
server_type = "${var.master_type}"
14+
image = "${var.master_image}"
15+
ssh_keys = ["${hcloud_ssh_key.k8s_admin.id}"]
16+
17+
connection {
18+
private_key = "${file(var.ssh_private_key)}"
19+
}
20+
21+
provisioner "file" {
22+
source = "files/10-kubeadm.conf"
23+
destination = "/root/10-kubeadm.conf"
24+
}
25+
26+
provisioner "file" {
27+
source = "scripts/bootstrap.sh"
28+
destination = "/root/bootstrap.sh"
29+
}
30+
31+
provisioner "remote-exec" {
32+
inline = "DOCKER_VERSION=${var.docker_version} KUBERNETES_VERSION=${var.kubernetes_version} bash /root/bootstrap.sh"
33+
}
34+
35+
provisioner "file" {
36+
source = "scripts/master.sh"
37+
destination = "/root/master.sh"
38+
}
39+
40+
provisioner "remote-exec" {
41+
inline = "CORE_DNS=${var.core_dns} bash /root/master.sh"
42+
}
43+
44+
provisioner "local-exec" {
45+
command = "bash scripts/copy-kubeadm-token.sh"
46+
47+
environment {
48+
SSH_PRIVATE_KEY = "${var.ssh_private_key}"
49+
SSH_USERNAME = "root"
50+
SSH_HOST = "${hcloud_server.master.ipv4_address}"
51+
TARGET = "${path.module}/secrets/"
52+
}
53+
}
54+
}
55+
56+
resource "hcloud_server" "node" {
57+
count = "${var.node_count}"
58+
name = "node-${count.index + 1}"
59+
server_type = "${var.node_type}"
60+
image = "${var.node_image}"
61+
depends_on = ["hcloud_server.master"]
62+
ssh_keys = ["${hcloud_ssh_key.k8s_admin.id}"]
63+
64+
connection {
65+
private_key = "${file(var.ssh_private_key)}"
66+
}
67+
68+
provisioner "file" {
69+
source = "files/10-kubeadm.conf"
70+
destination = "/root/10-kubeadm.conf"
71+
}
72+
73+
provisioner "file" {
74+
source = "scripts/bootstrap.sh"
75+
destination = "/root/bootstrap.sh"
76+
}
77+
78+
provisioner "remote-exec" {
79+
inline = "DOCKER_VERSION=${var.docker_version} KUBERNETES_VERSION=${var.kubernetes_version} bash /root/bootstrap.sh"
80+
}
81+
82+
provisioner "file" {
83+
source = "${path.module}/secrets/kubeadm_join"
84+
destination = "/tmp/kubeadm_join"
85+
86+
connection {
87+
type = "ssh"
88+
user = "root"
89+
private_key = "${file(var.ssh_private_key)}"
90+
}
91+
}
92+
93+
provisioner "file" {
94+
source = "scripts/node.sh"
95+
destination = "/root/node.sh"
96+
}
97+
98+
provisioner "remote-exec" {
99+
inline = "bash /root/node.sh"
100+
}
101+
}

outputs.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
output "node_ips" {
2+
value = ["${hcloud_server.node.*.ipv4_address}"]
3+
}
4+
5+
output "master_ips" {
6+
value = ["${hcloud_server.master.*.ipv4_address}"]
7+
}
8+

scripts/bootstrap.sh

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/bash
2+
set -eu
3+
DOCKER_VERSION=${DOCKER_VERSION:-}
4+
KUBERNETES_VERSION=${KUBERNETES_VERSION:-}
5+
6+
echo "
7+
Package: docker-ce
8+
Pin: version ${DOCKER_VERSION}.*
9+
Pin-Priority: 1000
10+
" > /etc/apt/preferences.d/docker-ce
11+
sleep 30
12+
apt-get -qq update
13+
apt-get -qq install -y \
14+
apt-transport-https \
15+
ca-certificates \
16+
curl \
17+
software-properties-common
18+
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
19+
add-apt-repository \
20+
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
21+
$(lsb_release -cs) \
22+
stable"
23+
apt-get -qq update && apt-get -qq install -y docker-ce
24+
25+
cat > /etc/docker/daemon.json <<EOF
26+
{
27+
"storage-driver":"overlay2"
28+
}
29+
EOF
30+
31+
systemctl restart docker.service
32+
33+
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
34+
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
35+
deb http://apt.kubernetes.io/ kubernetes-xenial main
36+
EOF
37+
38+
echo "
39+
Package: kubelet
40+
Pin: version ${KUBERNETES_VERSION}-*
41+
Pin-Priority: 1000
42+
" > /etc/apt/preferences.d/kubelet
43+
44+
echo "
45+
Package: kubeadm
46+
Pin: version ${KUBERNETES_VERSION}-*
47+
Pin-Priority: 1000
48+
" > /etc/apt/preferences.d/kubeadm
49+
50+
apt-get -qq update
51+
apt-get -qq install -y kubelet kubeadm
52+
53+
mv -v /root/10-kubeadm.conf /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
54+
55+
56+
systemctl daemon-reload
57+
systemctl restart kubelet

scripts/copy-kubeadm-token.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
set -eu
3+
SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY:-}
4+
SSH_USERNAME=${SSH_USERNAME:-}
5+
SSH_HOST=${SSH_HOST:-}
6+
7+
TARGET=${TARGET:-}
8+
9+
mkdir -p ${TARGET}
10+
11+
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
12+
-i ${SSH_PRIVATE_KEY} \
13+
${SSH_USERNAME}@${SSH_HOST}:"/tmp/kubeadm_join" \
14+
${TARGET}
15+
16+
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
17+
-i ${SSH_PRIVATE_KEY} \
18+
${SSH_USERNAME}@${SSH_HOST}:"/etc/kubernetes/admin.conf" \
19+
${TARGET}

scripts/master.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/bash
2+
set -eu
3+
4+
KUBERNETES_VERSION=${KUBERNETES_VERSION:-}
5+
CORE_DNS=${CORE_DNS:-}
6+
7+
echo "
8+
Package: kubectl
9+
Pin: version ${KUBERNETES_VERSION}-*
10+
Pin-Priority: 1000
11+
" > /etc/apt/preferences.d/kubectl
12+
13+
apt-get install -qq -y kubectl
14+
15+
# Initialize Cluster
16+
kubeadm init --feature-gates CoreDNS=$CORE_DNS
17+
18+
systemctl enable docker kubelet
19+
20+
# used to join nodes to the cluster
21+
kubeadm token create --print-join-command > /tmp/kubeadm_join

scripts/node.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/bash
2+
set -eu
3+
4+
eval $(cat /tmp/kubeadm_join)
5+
systemctl enable docker kubelet

0 commit comments

Comments
 (0)