{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Kubernetes 0.11.1 on EC2", "Mappings": { "RegionMap": { "eu-central-1": {"AMI": "ami-488ebe55"}, "ap-northeast-1": {"AMI": "ami-14273415"}, "sa-east-1": {"AMI": "ami-e7b30efa"}, "ap-southeast-2": {"AMI": "ami-4d2b5e77"}, "ap-southeast-1": {"AMI": "ami-8c032bde"}, "us-east-1": {"AMI": "ami-4c651824"}, "us-west-2": {"AMI": "ami-ff2679cf"}, "us-west-1": {"AMI": "ami-5d4f5118"}, "eu-west-1": {"AMI": "ami-5d71f02a"} } }, "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" }, "VpcId": { "Description": "The ID of the VPC to launch into.", "Type": "String", "Default": "" }, "SubnetId": { "Description": "The ID of the VPC to launch into (that must be within the supplied VPC)", "Type": "String", "Default": "" }, "SubnetAZ": { "Description": "The availability zone of the subnet supplied (for example eu-west-1a)", "Type": "String", "Default": "" } }, "Conditions": { "UseEC2Classic": {"Fn::Equals": [{"Ref": "VpcId"}, ""]} }, "Resources": { "KubernetesSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "VpcId": {"Fn::If": ["UseEC2Classic", {"Ref": "AWS::NoValue"}, {"Ref": "VpcId"}]}, "GroupDescription": "Kubernetes SecurityGroup", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": {"Ref": "AllowSSHFrom"} } ] } }, "KubernetesIngress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupId": {"Fn::GetAtt": ["KubernetesSecurityGroup", "GroupId"]}, "IpProtocol": "tcp", "FromPort": "1", "ToPort": "65535", "SourceSecurityGroupId": { "Fn::GetAtt" : [ "KubernetesSecurityGroup", "GroupId" ] } } }, "KubernetesIngressUDP": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupId": {"Fn::GetAtt": ["KubernetesSecurityGroup", "GroupId"]}, "IpProtocol": "udp", "FromPort": "1", "ToPort": "65535", "SourceSecurityGroupId": { "Fn::GetAtt" : [ "KubernetesSecurityGroup", "GroupId" ] } } }, "KubernetesMasterInstance": { "Type": "AWS::EC2::Instance", "Properties": { "SubnetId": {"Fn::If": ["UseEC2Classic", {"Ref": "AWS::NoValue"}, {"Ref": "SubnetId"}]}, "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", "---\n", "write_files:\n", "- path: /opt/bin/waiter.sh\n", " owner: root\n", " content: |\n", " #! /usr/bin/bash\n", " until curl http://127.0.0.1:4001/v2/machines; do sleep 2; done\n", "coreos:\n", " units:\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: etcd.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=etcd\n", " Requires=setup-network-environment.service\n", " After=setup-network-environment.service\n\n", " [Service]\n", " EnvironmentFile=/etc/network-environment\n", " User=etcd\n", " PermissionsStartOnly=true\n", " ExecStart=/usr/bin/etcd \\\n", " --name $private_ipv4 \\\n", " --addr $private_ipv4:4001 \\\n", " --bind-addr 0.0.0.0 \\\n", " --cluster-active-size 1 \\\n", " --data-dir /var/lib/etcd \\\n", " --http-read-timeout 86400 \\\n", " --peer-addr $private_ipv4:7001 \\\n", " --snapshot true\n", " Restart=always\n", " RestartSec=10s\n", " - name: fleet.socket\n", " command: start\n", " content: |\n", " [Socket]\n", " ListenStream=/var/run/fleet.sock\n", " - name: fleet.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=fleet daemon\n", " Wants=etcd.service\n", " After=etcd.service\n", " Wants=fleet.socket\n", " After=fleet.socket\n\n", " [Service]\n", " Environment=\"FLEET_ETCD_SERVERS=http://127.0.0.1:4001\"\n", " Environment=\"FLEET_METADATA=role=master\"\n", " ExecStart=/usr/bin/fleetd\n", " Restart=always\n", " RestartSec=10s\n", " - name: etcd-waiter.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Description=etcd waiter\n", " Wants=network-online.target\n", " Wants=etcd.service\n", " After=etcd.service\n", " After=network-online.target\n", " Before=flannel.service\n\n", " [Service]\n", " ExecStartPre=/usr/bin/chmod +x /opt/bin/waiter.sh\n", " ExecStart=/usr/bin/bash /opt/bin/waiter.sh\n", " RemainAfterExit=true\n", " Type=oneshot\n", " - name: flannel.service\n", " command: start\n", " content: |\n", " [Unit]\n", " Requires=etcd-waiter.service\n", " After=etcd-waiter.service\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.244.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.11.0/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.100.0.0/16 \\\n", " --etcd_servers=http://127.0.0.1:4001 \\\n", " --public_address_override=$private_ipv4 \\\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.11.0/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.11.0/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-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", " Requires=fleet.service\n", " After=fleet.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": { "SubnetId": {"Fn::If": ["UseEC2Classic", {"Ref": "AWS::NoValue"}, {"Ref": "SubnetId"}]}, "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=overlay -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.11.0/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", " --api_servers=", {"Fn::GetAtt" :["KubernetesMasterInstance" , "PrivateIp"]}, ":8080\\\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.11.0/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::If": ["UseEC2Classic", {"Fn::GetAZs": ""}, [{"Ref": "SubnetAZ"}]]}, "VPCZoneIdentifier": {"Fn::If": ["UseEC2Classic", {"Ref": "AWS::NoValue"}, [{"Ref": "SubnetId"}]]}, "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"]} } } }