From 26aeebb37265e7ec7f990ca728a257b323f64f71 Mon Sep 17 00:00:00 2001 From: Spencer Smith Date: Tue, 7 Jun 2016 12:45:25 -0700 Subject: [PATCH] base functionality to create aws resources --- contrib/terraform/aws/.gitignore | 2 + .../terraform/aws/00-create-infrastructure.tf | 143 ++++++++++++++++++ contrib/terraform/aws/01-create-inventory.tf | 37 +++++ contrib/terraform/aws/README.md | 28 ++++ contrib/terraform/aws/terraform.tfvars | 22 +++ 5 files changed, 232 insertions(+) create mode 100644 contrib/terraform/aws/.gitignore create mode 100755 contrib/terraform/aws/00-create-infrastructure.tf create mode 100755 contrib/terraform/aws/01-create-inventory.tf create mode 100644 contrib/terraform/aws/README.md create mode 100644 contrib/terraform/aws/terraform.tfvars diff --git a/contrib/terraform/aws/.gitignore b/contrib/terraform/aws/.gitignore new file mode 100644 index 000000000..28901e146 --- /dev/null +++ b/contrib/terraform/aws/.gitignore @@ -0,0 +1,2 @@ +*.tfstate* +inventory diff --git a/contrib/terraform/aws/00-create-infrastructure.tf b/contrib/terraform/aws/00-create-infrastructure.tf new file mode 100755 index 000000000..12fcfd2ec --- /dev/null +++ b/contrib/terraform/aws/00-create-infrastructure.tf @@ -0,0 +1,143 @@ +variable "deploymentName" { + type = "string" + description = "The desired name of your deployment." +} + +variable "numControllers"{ + type = "string" + description = "Desired # of controllers." +} + +variable "numEtcd" { + type = "string" + description = "Desired # of etcd nodes. Should be an odd number." +} + +variable "numNodes" { + type = "string" + description = "Desired # of nodes." +} + +variable "volSizeController" { + type = "string" + description = "Volume size for the controllers (GB)." +} + +variable "volSizeEtcd" { + type = "string" + description = "Volume size for etcd (GB)." +} + +variable "volSizeNodes" { + type = "string" + description = "Volume size for nodes (GB)." +} + +variable "subnet" { + type = "string" + description = "The subnet in which to put your cluster." +} + +variable "securityGroups" { + type = "string" + description = "The sec. groups in which to put your cluster." +} + +variable "ami"{ + type = "string" + description = "AMI to use for all VMs in cluster." +} + +variable "SSHKey" { + type = "string" + description = "SSH key to use for VMs." +} + +variable "master_instance_type" { + type = "string" + description = "Size of VM to use for masters." +} + +variable "etcd_instance_type" { + type = "string" + description = "Size of VM to use for etcd." +} + +variable "node_instance_type" { + type = "string" + description = "Size of VM to use for nodes." +} + +variable "terminate_protect" { + type = "string" + default = "false" +} + +variable "awsRegion" { + type = "string" +} + +provider "aws" { + region = "${var.awsRegion}" +} + +resource "aws_instance" "master" { + count = "${var.numControllers}" + ami = "${var.ami}" + instance_type = "${var.master_instance_type}" + subnet_id = "${var.subnet}" + vpc_security_group_ids = ["${var.securityGroups}"] + key_name = "${var.SSHKey}" + disable_api_termination = "${var.terminate_protect}" + root_block_device { + volume_size = "${var.volSizeController}" + } + tags { + Name = "${var.deploymentName}-master-${count.index + 1}" + } +} + +resource "aws_instance" "etcd" { + count = "${var.numEtcd}" + ami = "${var.ami}" + instance_type = "${var.etcd_instance_type}" + subnet_id = "${var.subnet}" + vpc_security_group_ids = ["${var.securityGroups}"] + key_name = "${var.SSHKey}" + disable_api_termination = "${var.terminate_protect}" + root_block_device { + volume_size = "${var.volSizeEtcd}" + } + tags { + Name = "${var.deploymentName}-etcd-${count.index + 1}" + } +} + + +resource "aws_instance" "minion" { + count = "${var.numNodes}" + ami = "${var.ami}" + instance_type = "${var.node_instance_type}" + subnet_id = "${var.subnet}" + vpc_security_group_ids = ["${var.securityGroups}"] + key_name = "${var.SSHKey}" + disable_api_termination = "${var.terminate_protect}" + root_block_device { + volume_size = "${var.volSizeNodes}" + } + tags { + Name = "${var.deploymentName}-minion-${count.index + 1}" + } +} + +output "master-ip" { + value = "${join(", ", aws_instance.master.*.private_ip)}" +} + +output "etcd-ip" { + value = "${join(", ", aws_instance.etcd.*.private_ip)}" +} + +output "minion-ip" { + value = "${join(", ", aws_instance.minion.*.private_ip)}" +} diff --git a/contrib/terraform/aws/01-create-inventory.tf b/contrib/terraform/aws/01-create-inventory.tf new file mode 100755 index 000000000..ee00e7de3 --- /dev/null +++ b/contrib/terraform/aws/01-create-inventory.tf @@ -0,0 +1,37 @@ +variable "SSHUser" { + type = "string" + description = "SSH User for VMs." +} + +resource "null_resource" "ansible-provision" { + + depends_on = ["aws_instance.master","aws_instance.etcd","aws_instance.minion"] + + ##Create Master Inventory + provisioner "local-exec" { + command = "echo \"[kube-master]\" > inventory" + } + provisioner "local-exec" { + command = "echo \"${join("\n",formatlist("%s ansible_ssh_user=%s", aws_instance.master.*.private_ip, var.SSHUser))}\" >> inventory" + } + + ##Create ETCD Inventory + provisioner "local-exec" { + command = "echo \"\n[etcd]\" >> inventory" + } + provisioner "local-exec" { + command = "echo \"${join("\n",formatlist("%s ansible_ssh_user=%s", aws_instance.etcd.*.private_ip, var.SSHUser))}\" >> inventory" + } + + ##Create Nodes Inventory + provisioner "local-exec" { + command = "echo \"\n[kube-node]\" >> inventory" + } + provisioner "local-exec" { + command = "echo \"${join("\n",formatlist("%s ansible_ssh_user=%s", aws_instance.minion.*.private_ip, var.SSHUser))}\" >> inventory" + } + + provisioner "local-exec" { + command = "echo \"\n[k8s-cluster:children]\nkube-node\nkube-master\netcd\" >> inventory" + } +} diff --git a/contrib/terraform/aws/README.md b/contrib/terraform/aws/README.md new file mode 100644 index 000000000..c7ede59ef --- /dev/null +++ b/contrib/terraform/aws/README.md @@ -0,0 +1,28 @@ +## Kubernetes on AWS with Terraform + +**Overview:** + +- This will create nodes in a VPC inside of AWS + +- A dynamic number of masters, etcd, and nodes can be created + +- These scripts currently expect Private IP connectivity with the nodes that are created. This means that you may need a tunnel to your VPC or to run these scripts from a VM inside the VPC. Will be looking into how to work around this later. + +**How to Use:** + +- Export the variables for your Amazon credentials: + +``` +export AWS_ACCESS_KEY_ID="xxx" +export AWS_SECRET_ACCESS_KEY="yyy" +``` + +- Update contrib/terraform/aws/terraform.tfvars with your data + +- Run with `terraform apply` + +- Once the infrastructure is created, you can run the kubespray playbooks and supply contrib/terraform/aws/inventory with the `-i` flag. + +**Future Work:** + +- Update the inventory creation file to be something a little more reasonable. It's just a local-exec from Terraform now, using terraform.py or something may make sense in the future. \ No newline at end of file diff --git a/contrib/terraform/aws/terraform.tfvars b/contrib/terraform/aws/terraform.tfvars new file mode 100644 index 000000000..012babc27 --- /dev/null +++ b/contrib/terraform/aws/terraform.tfvars @@ -0,0 +1,22 @@ +deploymentName="test-kube-deploy" + +numControllers="2" +numEtcd="3" +numNodes="2" + +volSizeController="20" +volSizeEtcd="20" +volSizeNodes="20" + +awsRegion="us-west-2" +subnet="subnet-xxxxx" +ami="ami-32a85152" +securityGroups="sg-xxxxx" +SSHUser="core" +SSHKey="my-key" + +master_instance_type="m3.xlarge" +etcd_instance_type="m3.xlarge" +node_instance_type="m3.xlarge" + +terminate_protect="false"