├── .gitignore ├── LICENSE ├── README.md ├── main.tf ├── master.sh ├── outputs.tf ├── variables.tf └── worker.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.tfstate 2 | *.backup 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, UPMC Enterprises 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name UPMC Enterprises nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL UPMC ENTERPRISES BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## kubeadm quickstart on aws 2 | 3 | This is a quickstart to get running with the new kubeadm tool which delivered in Kubernetes 1.4. Please see docs here for information about this new tool: http://kubernetes.io/docs/getting-started-guides/kubeadm/ 4 | 5 | The goal of this project is to build out a simple cluster on AWS utilizing Terraform to build out infrastructure, then use kubeadm to bootstrap a Kubernetes cluster. 6 | 7 | ### How it works 8 | 9 | The terraform script builds out a new VPC in your account and 3 corresponding subnets. It will also provision an internet gateway and setup a routing table to allow internet access. 10 | 11 | #### _NOTE: This isn't ready for production!_ 12 | 13 | ### Run it! 14 | 15 | 1. Clone the repo: `git clone https://github.com/upmc-enterprises/kubeadm-aws.git` 16 | - [Install Terraform](https://www.terraform.io/intro/getting-started/install.html) 17 | - Generate token: `python -c 'import random; print "%0x.%0x" % (random.SystemRandom().getrandbits(3*8), random.SystemRandom().getrandbits(8*8))'` 18 | - Generate ssh keys: `ssh-keygen -f k8s-test` 19 | - Run terraform plan: `terraform plan -var k8s-ssh-key="$(cat k8s-test.pub)" -var 'k8stoken='` 20 | - Build out infrastructure: `terraform apply -var k8s-ssh-key="$(cat k8s-test.pub)" -var 'k8stoken='` 21 | - ssh to kube master and run something: `ssh ubuntu@$(terraform output master_dns) -i k8s-test` 22 | - Done! 23 | 24 | ### About 25 | 26 | Built by UPMC Enterprises in Pittsburgh, PA. http://enterprises.upmc.com/ 27 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright (c) 2016, UPMC Enterprises 4 | All rights reserved. 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name UPMC Enterprises nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL UPMC ENTERPRISES BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PR) 21 | OCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | */ 26 | 27 | provider "aws" { 28 | access_key = "${var.access_key}" 29 | secret_key = "${var.secret_key}" 30 | region = "${var.region}" 31 | } 32 | 33 | # Key pair for the instances 34 | resource "aws_key_pair" "ssh-key" { 35 | key_name = "k8s" 36 | public_key = "${var.k8s-ssh-key}" 37 | 38 | lifecycle { 39 | create_before_destroy = true 40 | } 41 | } 42 | 43 | resource "aws_vpc" "main" { 44 | cidr_block = "10.0.0.0/16" 45 | enable_dns_hostnames = true 46 | 47 | tags { 48 | Name = "TF_VPC" 49 | } 50 | } 51 | 52 | resource "aws_internet_gateway" "gw" { 53 | vpc_id = "${aws_vpc.main.id}" 54 | 55 | tags { 56 | Name = "TF_main" 57 | } 58 | } 59 | 60 | resource "aws_route_table" "r" { 61 | vpc_id = "${aws_vpc.main.id}" 62 | route { 63 | cidr_block = "0.0.0.0/0" 64 | gateway_id = "${aws_internet_gateway.gw.id}" 65 | } 66 | 67 | depends_on = ["aws_internet_gateway.gw"] 68 | 69 | tags { 70 | Name = "TF_main" 71 | } 72 | } 73 | 74 | resource "aws_route_table_association" "publicA" { 75 | subnet_id = "${aws_subnet.publicA.id}" 76 | route_table_id = "${aws_route_table.r.id}" 77 | } 78 | 79 | resource "aws_route_table_association" "publicB" { 80 | subnet_id = "${aws_subnet.publicB.id}" 81 | route_table_id = "${aws_route_table.r.id}" 82 | } 83 | 84 | resource "aws_route_table_association" "publicC" { 85 | subnet_id = "${aws_subnet.publicC.id}" 86 | route_table_id = "${aws_route_table.r.id}" 87 | } 88 | 89 | resource "aws_subnet" "publicA" { 90 | vpc_id = "${aws_vpc.main.id}" 91 | cidr_block = "10.0.100.0/24" 92 | availability_zone = "us-east-1c" 93 | map_public_ip_on_launch = true 94 | 95 | tags { 96 | Name = "TF_PubSubnetA" 97 | } 98 | } 99 | 100 | resource "aws_subnet" "publicB" { 101 | vpc_id = "${aws_vpc.main.id}" 102 | cidr_block = "10.0.101.0/24" 103 | availability_zone = "us-east-1d" 104 | map_public_ip_on_launch = true 105 | 106 | tags { 107 | Name = "TF_PubSubnetB" 108 | } 109 | } 110 | 111 | resource "aws_subnet" "publicC" { 112 | vpc_id = "${aws_vpc.main.id}" 113 | cidr_block = "10.0.102.0/24" 114 | availability_zone = "us-east-1e" 115 | map_public_ip_on_launch = true 116 | 117 | tags { 118 | Name = "TF_PubSubnetC" 119 | } 120 | } 121 | 122 | resource "aws_security_group" "kubernetes" { 123 | name = "kubernetes" 124 | description = "Allow inbound ssh traffic" 125 | vpc_id = "${aws_vpc.main.id}" 126 | 127 | ingress { 128 | from_port = 22 129 | to_port = 22 130 | protocol = "tcp" 131 | cidr_blocks = ["0.0.0.0/0"] 132 | } 133 | 134 | ingress { 135 | from_port = 0 136 | to_port = 0 137 | protocol = "-1" 138 | cidr_blocks = ["10.0.0.0/16"] 139 | } 140 | 141 | 142 | egress { 143 | from_port = 0 144 | to_port = 0 145 | protocol = "-1" 146 | cidr_blocks = ["0.0.0.0/0"] 147 | } 148 | 149 | tags { 150 | Name = "kubernetes" 151 | } 152 | } 153 | 154 | data "template_file" "master-userdata" { 155 | template = "${file("${var.master-userdata}")}" 156 | 157 | vars { 158 | k8stoken = "${var.k8stoken}" 159 | } 160 | } 161 | 162 | data "template_file" "worker-userdata" { 163 | template = "${file("${var.worker-userdata}")}" 164 | 165 | vars { 166 | k8stoken = "${var.k8stoken}" 167 | masterIP = "${aws_instance.k8s-master.private_ip}" 168 | } 169 | } 170 | 171 | resource "aws_instance" "k8s-master" { 172 | ami = "ami-2ef48339" 173 | instance_type = "t2.medium" 174 | subnet_id = "${aws_subnet.publicA.id}" 175 | user_data = "${data.template_file.master-userdata.rendered}" 176 | key_name = "${aws_key_pair.ssh-key.key_name}" 177 | associate_public_ip_address = true 178 | vpc_security_group_ids = ["${aws_security_group.kubernetes.id}"] 179 | 180 | depends_on = ["aws_internet_gateway.gw"] 181 | 182 | tags { 183 | Name = "[TF] k8s-master" 184 | } 185 | } 186 | 187 | resource "aws_instance" "k8s-worker1" { 188 | ami = "ami-2ef48339" 189 | instance_type = "t2.medium" 190 | subnet_id = "${aws_subnet.publicA.id}" 191 | user_data = "${data.template_file.worker-userdata.rendered}" 192 | key_name = "${aws_key_pair.ssh-key.key_name}" 193 | associate_public_ip_address = true 194 | vpc_security_group_ids = ["${aws_security_group.kubernetes.id}"] 195 | 196 | depends_on = ["aws_internet_gateway.gw"] 197 | 198 | tags { 199 | Name = "worker0" 200 | } 201 | } 202 | 203 | resource "aws_instance" "k8s-worker2" { 204 | ami = "ami-2ef48339" 205 | instance_type = "t2.medium" 206 | subnet_id = "${aws_subnet.publicA.id}" 207 | user_data = "${data.template_file.worker-userdata.rendered}" 208 | key_name = "${aws_key_pair.ssh-key.key_name}" 209 | associate_public_ip_address = true 210 | vpc_security_group_ids = ["${aws_security_group.kubernetes.id}"] 211 | 212 | depends_on = ["aws_internet_gateway.gw"] 213 | 214 | tags { 215 | Name = "worker1" 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /master.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -v 2 | 3 | curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - 4 | cat < /etc/apt/sources.list.d/kubernetes.list 5 | deb http://apt.kubernetes.io/ kubernetes-xenial main 6 | EOF 7 | apt-get update 8 | apt-get install -y kubelet kubeadm kubectl kubernetes-cni 9 | curl -sSL https://get.docker.com/ | sh 10 | systemctl start docker 11 | 12 | kubeadm init --token=${k8stoken} 13 | 14 | kubectl apply -f https://git.io/weave-kube 15 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016, UPMC Enterprises 3 | All rights reserved. 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name UPMC Enterprises nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL UPMC ENTERPRISES BE LIABLE FOR ANY 18 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PR) 20 | OCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | */ 25 | 26 | output "master_dns" { 27 | value = "${aws_instance.k8s-master.public_dns}" 28 | } 29 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016, UPMC Enterprises 3 | All rights reserved. 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name UPMC Enterprises nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL UPMC ENTERPRISES BE LIABLE FOR ANY 18 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PR) 20 | OCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | */ 25 | 26 | variable "k8stoken" {} 27 | 28 | variable "access_key" { 29 | default = "" 30 | } 31 | 32 | variable "secret_key" { 33 | default = "" 34 | } 35 | 36 | variable "k8s-ssh-key" {} 37 | 38 | variable "region" { 39 | default = "us-east-1" 40 | } 41 | 42 | variable "master-userdata" { 43 | default = "master.sh" 44 | } 45 | 46 | variable "worker-userdata" { 47 | default = "worker.sh" 48 | } 49 | -------------------------------------------------------------------------------- /worker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -v 2 | 3 | curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - 4 | cat < /etc/apt/sources.list.d/kubernetes.list 5 | deb http://apt.kubernetes.io/ kubernetes-xenial main 6 | EOF 7 | apt-get update 8 | apt-get install -y kubelet kubeadm kubectl kubernetes-cni 9 | curl -sSL https://get.docker.com/ | sh 10 | systemctl start docker 11 | 12 | for i in {1..50}; do kubeadm join --token=${k8stoken} ${masterIP} && break || sleep 15; done 13 | --------------------------------------------------------------------------------