{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Kubernetes on EC2", "Mappings": { "RegionMap": { "eu-central-1": {"AMI": "ami-54ccfa49"}, "ap-northeast-1": {"AMI": "ami-f7b08ff6"}, "sa-east-1": {"AMI": "ami-1304b30e"}, "ap-southeast-2": {"AMI": "ami-0f117e35"}, "ap-southeast-1": {"AMI": "ami-c04f6c92"}, "us-east-1": {"AMI": "ami-7ae66812"}, "us-west-2": {"AMI": "ami-e18dc5d1"}, "us-west-1": {"AMI": "ami-45fbec00"}, "eu-west-1": {"AMI": "ami-a27fd5d5"} } }, "Parameters": { "InstanceType": { "Description": "EC2 HVM instance type (m3.medium, etc).", "Type": "String", "Default": "m3.medium", "AllowedValues": [ "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "cc2.8xlarge", "cr1.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "t2.micro", "t2.small", "t2.medium" ], "ConstraintDescription": "Must be a valid EC2 HVM instance type." }, "ClusterSize": { "Description": "Number of nodes in cluster (3-12).", "Default": "3", "MinValue": "3", "MaxValue": "12", "Type": "Number" }, "AllowSSHFrom": { "Description": "The net block (CIDR) that SSH is available to.", "Default": "0.0.0.0/0", "Type": "String" }, "KeyPair" : { "Description": "The name of an EC2 Key Pair to allow SSH access to the instance.", "Type": "String" } }, "Resources": { "KubernetesSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Kubernetes SecurityGroup", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": {"Ref": "AllowSSHFrom"} } ] } }, "KubernetesIngress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupName": {"Ref": "KubernetesSecurityGroup"}, "IpProtocol": "tcp", "FromPort": "1", "ToPort": "65535", "SourceSecurityGroupId": { "Fn::GetAtt" : [ "KubernetesSecurityGroup", "GroupId" ] } } }, "KubernetesIngressUDP": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupName": {"Ref": "KubernetesSecurityGroup"}, "IpProtocol": "udp", "FromPort": "1", "ToPort": "65535", "SourceSecurityGroupId": { "Fn::GetAtt" : [ "KubernetesSecurityGroup", "GroupId" ] } } }, "KubernetesMasterInstance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": {"Fn::FindInMap" : ["RegionMap", {"Ref": "AWS::Region" }, "AMI"]}, "InstanceType": {"Ref": "InstanceType"}, "KeyName": {"Ref": "KeyPair"}, "SecurityGroups": [{"Ref": "KubernetesSecurityGroup"}], "UserData": { "Fn::Base64": {"Fn::Join" : ["", [ "#cloud-config\n\n", "coreos:\n", " fleet:\n", " etcd_servers: http://127.0.0.1:4001\n", " metadata: role=master\n", " etcd:\n", " name: etcd\n", " addr: $private_ipv4:4001\n", " bind-addr: 0.0.0.0\n", " peer-addr: $private_ipv4:7001\n", " cluster-active-size: 1\n", " etcd-http-read-timeout: 86400\n", " snapshot: true\n", " units:\n", " - name: etcd.service\n", " command: start\n", " - name: fleet.service\n", " command: start\n", " - name: flannel.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Requires=etcd.service\n", " After=etcd.service\n", " After=network-online.target\n", " Wants=network-online.target\n", " Description=flannel is an etcd backed overlay network for containers\n\n", " [Service]\n", " Type=notify\n", " ExecStartPre=-/usr/bin/mkdir -p /opt/bin\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/k8s/flanneld\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/flanneld\n", " ExecStartPre=-/usr/bin/etcdctl mk /coreos.com/network/config '{\"Network\":\"10.0.0.0/16\"}'\n", " ExecStart=/opt/bin/flanneld\n", " - name: kube-apiserver.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=Kubernetes API Server\n", " Documentation=https://github.com/GoogleCloudPlatform/kubernetes\n", " Requires=etcd.service\n", " After=etcd.service\n\n", " [Service]\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.5.4/bin/linux/amd64/kube-apiserver\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-apiserver\n", " ExecStart=/opt/bin/kube-apiserver \\\n", " --address=0.0.0.0 \\\n", " --port=8080 \\\n", " --portal_net 10.1.0.0/16 \\\n", " --etcd_servers=http://127.0.0.1:4001 \\\n", " --logtostderr=true\n", " Restart=always\n", " RestartSec=10\n", " - name: kube-controller-manager.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=Kubernetes Controller Manager\n", " Documentation=https://github.com/GoogleCloudPlatform/kubernetes\n", " Requires=kube-apiserver.service\n", " After=kube-apiserver.service\n\n", " [Service]\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.5.4/bin/linux/amd64/kube-controller-manager\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-controller-manager\n", " ExecStart=/opt/bin/kube-controller-manager \\\n", " --master=127.0.0.1:8080 \\\n", " --logtostderr=true\n", " Restart=always\n", " RestartSec=10\n", " - name: kube-scheduler.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=Kubernetes Scheduler\n", " Documentation=https://github.com/GoogleCloudPlatform/kubernetes\n", " Requires=kube-apiserver.service\n", " After=kube-apiserver.service\n\n", " [Service]\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.5.4/bin/linux/amd64/kube-scheduler\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-scheduler\n", " ExecStart=/opt/bin/kube-scheduler --master=127.0.0.1:8080\n", " Restart=always\n", " RestartSec=10\n", " - name: kube-proxy.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=Kubernetes Proxy\n", " Documentation=https://github.com/GoogleCloudPlatform/kubernetes\n", " Requires=etcd.service\n", " After=etcd.service\n\n", " [Service]\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.5.4/bin/linux/amd64/kube-proxy\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-proxy\n", " ExecStart=/opt/bin/kube-proxy \\\n", " --etcd_servers=http://127.0.0.1:4001 \\\n", " --logtostderr=true\n", " Restart=always\n", " RestartSec=10\n", " - name: kube-register.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=Kubernetes Registration Service\n", " Documentation=https://github.com/kelseyhightower/kube-register\n", " Requires=kube-apiserver.service\n", " After=kube-apiserver.service\n\n", " [Service]\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/k8s/kube-register\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-register\n", " ExecStart=/opt/bin/kube-register \\\n", " --metadata=role=knode \\\n", " --fleet-endpoint=unix:///var/run/fleet.sock \\\n", " --api-endpoint=http://127.0.0.1:8080\n", " Restart=always\n", " RestartSec=10\n", " update:\n", " group: alpha\n", " reboot-strategy: off\n" ]]} } } }, "KubernetesNodeLaunchConfig": { "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "ImageId": {"Fn::FindInMap" : ["RegionMap", {"Ref": "AWS::Region" }, "AMI" ]}, "InstanceType": {"Ref": "InstanceType"}, "KeyName": {"Ref": "KeyPair"}, "SecurityGroups": [{"Ref": "KubernetesSecurityGroup"}], "UserData": { "Fn::Base64": {"Fn::Join" : ["", [ "#cloud-config\n\n", "coreos:\n", " fleet:\n", " etcd_servers: http://", {"Fn::GetAtt":["KubernetesMasterInstance" , "PrivateIp"]}, ":4001\n", " metadata: role=knode\n", " units:\n", " - name: etcd.service\n", " mask: true\n", " - name: fleet.service\n", " command: start\n", " - name: flannel.service\n", " command: start\n", " content: |\n", " [Unit]\n", " After=network-online.target\n", " Wants=network-online.target\n", " Description=flannel is an etcd backed overlay network for containers\n\n", " [Service]\n", " Type=notify\n", " ExecStartPre=-/usr/bin/mkdir -p /opt/bin\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/k8s/flanneld\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/flanneld\n", " ExecStart=/opt/bin/flanneld -etcd-endpoints http://", {"Fn::GetAtt" :["KubernetesMasterInstance" , "PrivateIp"]}, ":4001\n", " - name: docker.service\n", " command: start\n", " content: |\n", " [Unit]\n", " After=flannel.service\n", " Wants=flannel.service\n", " Description=Docker Application Container Engine\n", " Documentation=http://docs.docker.io\n\n", " [Service]\n", " EnvironmentFile=/run/flannel/subnet.env\n", " ExecStartPre=/bin/mount --make-rprivate /\n", " ExecStart=/usr/bin/docker -d --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} -s=btrfs -H fd://\n\n", " [Install]\n", " WantedBy=multi-user.target\n", " - name: setup-network-environment.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=Setup Network Environment\n", " Documentation=https://github.com/kelseyhightower/setup-network-environment\n", " Requires=network-online.target\n", " After=network-online.target\n\n", " [Service]\n", " ExecStartPre=-/usr/bin/mkdir -p /opt/bin\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/k8s/setup-network-environment\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/setup-network-environment\n", " ExecStart=/opt/bin/setup-network-environment\n", " RemainAfterExit=yes\n", " Type=oneshot\n", " - name: kube-kubelet.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=Kubernetes Kubelet\n", " Documentation=https://github.com/GoogleCloudPlatform/kubernetes\n", " Requires=setup-network-environment.service\n", " After=setup-network-environment.service\n\n", " [Service]\n", " EnvironmentFile=/etc/network-environment\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.5.4/bin/linux/amd64/kubelet\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/kubelet\n", " ExecStart=/opt/bin/kubelet \\\n", " --address=0.0.0.0 \\\n", " --port=10250 \\\n", " --hostname_override=${DEFAULT_IPV4} \\\n", " --etcd_servers=http://", {"Fn::GetAtt" :["KubernetesMasterInstance" , "PrivateIp"]}, ":4001\\\n", " --logtostderr=true\n", " Restart=always\n", " RestartSec=10\n", " - name: kube-proxy.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=Kubernetes Proxy\n", " Documentation=https://github.com/GoogleCloudPlatform/kubernetes\n", " Requires=setup-network-environment.service\n", " After=setup-network-environment.service\n\n", " [Service]\n", " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.5.4/bin/linux/amd64/kube-proxy\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-proxy\n", " ExecStart=/opt/bin/kube-proxy \\\n", " --etcd_servers=http://", {"Fn::GetAtt" :["KubernetesMasterInstance" , "PrivateIp"]}, ":4001\\\n", " --logtostderr=true\n", " Restart=always\n", " RestartSec=10\n", " update:\n", " group: alpha\n", " reboot-strategy: off\n" ]]} } } }, "KubernetesAutoScalingGroup": { "Type": "AWS::AutoScaling::AutoScalingGroup", "Properties": { "AvailabilityZones": {"Fn::GetAZs": ""}, "LaunchConfigurationName": {"Ref": "KubernetesNodeLaunchConfig"}, "MinSize": "3", "MaxSize": "12", "DesiredCapacity": {"Ref": "ClusterSize"} } } }, "Outputs": { "KubernetesMasterPublicIp": { "Description": "Public Ip of the newly created Kubernetes Master instance", "Value": {"Fn::GetAtt": ["KubernetesMasterInstance" , "PublicIp"]} } } }