diff --git a/contrib/terraform/aws/.gitignore b/contrib/terraform/aws/.gitignore
index 28901e146c00f9876132ca1cff35186e7c7e6b6c..84fcb582197bef46cdb0e87098fb194856f97f52 100644
--- a/contrib/terraform/aws/.gitignore
+++ b/contrib/terraform/aws/.gitignore
@@ -1,2 +1,2 @@
 *.tfstate*
-inventory
+.terraform
diff --git a/contrib/terraform/aws/00-create-infrastructure.tf b/contrib/terraform/aws/00-create-infrastructure.tf
deleted file mode 100755
index 09cfac37c2b6533af6909b67daf539e17dd2c98d..0000000000000000000000000000000000000000
--- a/contrib/terraform/aws/00-create-infrastructure.tf
+++ /dev/null
@@ -1,261 +0,0 @@
-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}"
-}
-
-variable "iam_prefix" {
-  type = "string"
-  description = "Prefix name for IAM profiles"
-}
-
-resource "aws_iam_instance_profile" "kubernetes_master_profile" {
-  name = "${var.iam_prefix}_kubernetes_master_profile"
-  roles = ["${aws_iam_role.kubernetes_master_role.name}"]
-}
-
-resource "aws_iam_role" "kubernetes_master_role" {
-  name = "${var.iam_prefix}_kubernetes_master_role"
-  assume_role_policy = <<EOF
-{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Effect": "Allow",
-      "Principal": { "Service": "ec2.amazonaws.com"},
-      "Action": "sts:AssumeRole"
-    }
-  ]
-}
-EOF
-}
-
-resource "aws_iam_role_policy" "kubernetes_master_policy" {
-    name = "${var.iam_prefix}_kubernetes_master_policy"
-    role = "${aws_iam_role.kubernetes_master_role.id}"
-    policy = <<EOF
-{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Effect": "Allow",
-      "Action": ["ec2:*"],
-      "Resource": ["*"]
-    },
-    {
-      "Effect": "Allow",
-      "Action": ["elasticloadbalancing:*"],
-      "Resource": ["*"]
-    },
-    {
-      "Effect": "Allow",
-      "Action": "s3:*",
-      "Resource": "*"
-    }
-  ]
-}
-EOF
-}
-
-resource "aws_iam_instance_profile" "kubernetes_node_profile" {
-  name = "${var.iam_prefix}_kubernetes_node_profile"
-  roles = ["${aws_iam_role.kubernetes_node_role.name}"]
-}
-
-resource "aws_iam_role" "kubernetes_node_role" {
-  name = "${var.iam_prefix}_kubernetes_node_role"
-  assume_role_policy = <<EOF
-{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Effect": "Allow",
-      "Principal": { "Service": "ec2.amazonaws.com"},
-      "Action": "sts:AssumeRole"
-    }
-  ]
-}
-EOF
-}
-
-resource "aws_iam_role_policy" "kubernetes_node_policy" {
-    name = "${var.iam_prefix}_kubernetes_node_policy"
-    role = "${aws_iam_role.kubernetes_node_role.id}"
-    policy = <<EOF
-{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Effect": "Allow",
-      "Action": "s3:*",
-      "Resource": "*"
-    },
-    {
-      "Effect": "Allow",
-      "Action": "ec2:Describe*",
-      "Resource": "*"
-    },
-    {
-      "Effect": "Allow",
-      "Action": "ec2:AttachVolume",
-      "Resource": "*"
-    },
-    {
-      "Effect": "Allow",
-      "Action": "ec2:DetachVolume",
-      "Resource": "*"
-    }
-  ]
-}
-EOF
-}
-
-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}"
-    iam_instance_profile = "${aws_iam_instance_profile.kubernetes_master_profile.id}"
-    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}"
-    iam_instance_profile = "${aws_iam_instance_profile.kubernetes_node_profile.id}"
-    root_block_device {
-      volume_size = "${var.volSizeNodes}"
-    }
-    tags {
-      Name = "${var.deploymentName}-minion-${count.index + 1}"
-    }
-}
-
-output "kubernetes_master_profile" {
-  value = "${aws_iam_instance_profile.kubernetes_master_profile.id}"
-}
-
-output "kubernetes_node_profile" {
-  value = "${aws_iam_instance_profile.kubernetes_node_profile.id}"
-}
-
-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
deleted file mode 100755
index ce56521810344e462fa5ae183fd7b00ea2ebd650..0000000000000000000000000000000000000000
--- a/contrib/terraform/aws/01-create-inventory.tf
+++ /dev/null
@@ -1,37 +0,0 @@
-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\" >> inventory"
-  }
-}
diff --git a/contrib/terraform/aws/README.md b/contrib/terraform/aws/README.md
index c7ede59ef6f95def8f4c89e4cb47063c28e447e1..03bc4e23eee0293c48d60d1ba1480112d8c066ce 100644
--- a/contrib/terraform/aws/README.md
+++ b/contrib/terraform/aws/README.md
@@ -2,27 +2,34 @@
 
 **Overview:**
 
-- This will create nodes in a VPC inside of AWS
+This project will create:
+* VPC with Public and Private Subnets in # Availability Zones
+* Bastion Hosts and NAT Gateways in the Public Subnet
+* A dynamic number of masters, etcd, and worker nodes in the Private Subnet
+ * even distributed over the # of Availability Zones
+* AWS ELB in the Public Subnet for accessing the Kubernetes API from the internet
 
-- 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.
+**Requirements**
+- Terraform 0.8.7 or newer
 
 **How to Use:**
 
-- Export the variables for your Amazon credentials:
+- Export the variables for your AWS credentials or edit credentials.tfvars:
 
 ```
-export AWS_ACCESS_KEY_ID="xxx"
-export AWS_SECRET_ACCESS_KEY="yyy"
+export aws_access_key="xxx"
+export aws_secret_key="yyy"
+export aws_ssh_key_name="zzz"
 ```
 
 - Update contrib/terraform/aws/terraform.tfvars with your data
 
-- Run with `terraform apply`
+- Run with `terraform apply -var-file="credentials.tfvars"` or `terraform apply` depending if you exported your AWS credentials
+
+- Once the infrastructure is created, you can run the kargo playbooks and supply inventory/hosts with the `-i` flag.
 
-- Once the infrastructure is created, you can run the kubespray playbooks and supply contrib/terraform/aws/inventory with the `-i` flag.
+**Architecture**
 
-**Future Work:**
+Pictured is an AWS Infrastructure created with this Terraform project distributed over two Availability Zones.
 
-- 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
+![AWS Infrastructure with Terraform  ](docs/aws_kargo.png)
diff --git a/contrib/terraform/aws/create-infrastructure.tf b/contrib/terraform/aws/create-infrastructure.tf
new file mode 100644
index 0000000000000000000000000000000000000000..14da95492558497c198d8b86ccdb1603b6f2f682
--- /dev/null
+++ b/contrib/terraform/aws/create-infrastructure.tf
@@ -0,0 +1,185 @@
+terraform {
+    required_version = ">= 0.8.7"
+}
+
+provider "aws" {
+    access_key = "${var.AWS_ACCESS_KEY_ID}"
+    secret_key = "${var.AWS_SECRET_ACCESS_KEY}"
+    region = "${var.AWS_DEFAULT_REGION}"
+}
+
+/*
+* Calling modules who create the initial AWS VPC / AWS ELB
+* and AWS IAM Roles for Kubernetes Deployment
+*/
+
+module "aws-vpc" {
+  source = "modules/vpc"
+
+  aws_cluster_name = "${var.aws_cluster_name}"
+  aws_vpc_cidr_block = "${var.aws_vpc_cidr_block}"
+  aws_avail_zones="${var.aws_avail_zones}"
+
+  aws_cidr_subnets_private="${var.aws_cidr_subnets_private}"
+  aws_cidr_subnets_public="${var.aws_cidr_subnets_public}"
+
+}
+
+
+module "aws-elb" {
+  source = "modules/elb"
+
+  aws_cluster_name="${var.aws_cluster_name}"
+  aws_vpc_id="${module.aws-vpc.aws_vpc_id}"
+  aws_avail_zones="${var.aws_avail_zones}"
+  aws_subnet_ids_public="${module.aws-vpc.aws_subnet_ids_public}"
+  aws_elb_api_port = "${var.aws_elb_api_port}"
+  k8s_secure_api_port = "${var.k8s_secure_api_port}"
+
+}
+
+module "aws-iam" {
+  source = "modules/iam"
+
+  aws_cluster_name="${var.aws_cluster_name}"
+}
+
+/*
+* Create Bastion Instances in AWS
+*
+*/
+resource "aws_instance" "bastion-server" {
+    ami = "${var.aws_bastion_ami}"
+    instance_type = "${var.aws_bastion_size}"
+    count = "${length(var.aws_cidr_subnets_public)}"
+    associate_public_ip_address = true
+    availability_zone  = "${element(var.aws_avail_zones,count.index)}"
+    subnet_id = "${element(module.aws-vpc.aws_subnet_ids_public,count.index)}"
+
+
+    vpc_security_group_ids = [ "${module.aws-vpc.aws_security_group}" ]
+
+    key_name = "${var.AWS_SSH_KEY_NAME}"
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-bastion-${count.index}"
+        Cluster = "${var.aws_cluster_name}"
+        Role = "bastion-${var.aws_cluster_name}-${count.index}"
+    }
+}
+
+
+/*
+* Create K8s Master and worker nodes and etcd instances
+*
+*/
+
+resource "aws_instance" "k8s-master" {
+    ami = "${var.aws_cluster_ami}"
+    instance_type = "${var.aws_kube_master_size}"
+
+    count = "${var.aws_kube_master_num}"
+
+
+    availability_zone  = "${element(var.aws_avail_zones,count.index)}"
+    subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
+
+
+    vpc_security_group_ids = [ "${module.aws-vpc.aws_security_group}" ]
+
+
+    iam_instance_profile = "${module.aws-iam.kube-master-profile}"
+    key_name = "${var.AWS_SSH_KEY_NAME}"
+
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-master${count.index}"
+        Cluster = "${var.aws_cluster_name}"
+        Role = "master"
+    }
+}
+
+resource "aws_elb_attachment" "attach_master_nodes" {
+  count = "${var.aws_kube_master_num}"
+  elb      = "${module.aws-elb.aws_elb_api_id}"
+  instance = "${element(aws_instance.k8s-master.*.id,count.index)}"
+}
+
+
+resource "aws_instance" "k8s-etcd" {
+    ami = "${var.aws_cluster_ami}"
+    instance_type = "${var.aws_etcd_size}"
+
+    count = "${var.aws_etcd_num}"
+
+
+    availability_zone = "${element(var.aws_avail_zones,count.index)}"
+    subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
+
+
+    vpc_security_group_ids = [ "${module.aws-vpc.aws_security_group}" ]
+
+    key_name = "${var.AWS_SSH_KEY_NAME}"
+
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-etcd${count.index}"
+        Cluster = "${var.aws_cluster_name}"
+        Role = "etcd"
+    }
+
+}
+
+
+resource "aws_instance" "k8s-worker" {
+    ami = "${var.aws_cluster_ami}"
+    instance_type = "${var.aws_kube_worker_size}"
+
+    count = "${var.aws_kube_worker_num}"
+
+    availability_zone  = "${element(var.aws_avail_zones,count.index)}"
+    subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
+
+    vpc_security_group_ids = [ "${module.aws-vpc.aws_security_group}" ]
+
+    iam_instance_profile = "${module.aws-iam.kube-worker-profile}"
+    key_name = "${var.AWS_SSH_KEY_NAME}"
+
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-worker${count.index}"
+        Cluster = "${var.aws_cluster_name}"
+        Role = "worker"
+    }
+
+}
+
+
+
+/*
+* Create Kargo Inventory File
+*
+*/
+data "template_file" "inventory" {
+    template = "${file("${path.module}/templates/inventory.tpl")}"
+
+    vars {
+        public_ip_address_bastion = "${join("\n",formatlist("bastion ansible_ssh_host=%s" , aws_instance.bastion-server.*.public_ip))}"
+        connection_strings_master = "${join("\n",formatlist("%s ansible_ssh_host=%s",aws_instance.k8s-master.*.tags.Name, aws_instance.k8s-master.*.private_ip))}"
+        connection_strings_node = "${join("\n", formatlist("%s ansible_ssh_host=%s", aws_instance.k8s-worker.*.tags.Name, aws_instance.k8s-worker.*.private_ip))}"
+        connection_strings_etcd = "${join("\n",formatlist("%s ansible_ssh_host=%s", aws_instance.k8s-etcd.*.tags.Name, aws_instance.k8s-etcd.*.private_ip))}"
+        list_master = "${join("\n",aws_instance.k8s-master.*.tags.Name)}"
+        list_node = "${join("\n",aws_instance.k8s-worker.*.tags.Name)}"
+        list_etcd = "${join("\n",aws_instance.k8s-etcd.*.tags.Name)}"
+        elb_api_fqdn = "apiserver_loadbalancer_domain_name=\"${module.aws-elb.aws_elb_api_fqdn}\""
+        elb_api_port = "loadbalancer_apiserver.port=${var.aws_elb_api_port}"
+
+    }
+}
+
+resource "null_resource" "inventories" {
+  provisioner "local-exec" {
+      command = "echo '${data.template_file.inventory.rendered}' > ../../../inventory/hosts"
+  }
+
+}
diff --git a/contrib/terraform/aws/credentials.tfvars.example b/contrib/terraform/aws/credentials.tfvars.example
new file mode 100644
index 0000000000000000000000000000000000000000..19420c5a7d619af797312580a6035350ef0b11a8
--- /dev/null
+++ b/contrib/terraform/aws/credentials.tfvars.example
@@ -0,0 +1,8 @@
+#AWS Access Key
+AWS_ACCESS_KEY_ID = ""
+#AWS Secret Key
+AWS_SECRET_ACCESS_KEY = ""
+#EC2 SSH Key Name
+AWS_SSH_KEY_NAME = ""
+#AWS Region
+AWS_DEFAULT_REGION = "eu-central-1"
diff --git a/contrib/terraform/aws/docs/aws_kargo.png b/contrib/terraform/aws/docs/aws_kargo.png
new file mode 100644
index 0000000000000000000000000000000000000000..40245b845a5094d3cef4500d4f256031329a7b2e
Binary files /dev/null and b/contrib/terraform/aws/docs/aws_kargo.png differ
diff --git a/contrib/terraform/aws/modules/elb/main.tf b/contrib/terraform/aws/modules/elb/main.tf
new file mode 100644
index 0000000000000000000000000000000000000000..270e0cb356401d79d0a43896a780ce897f953985
--- /dev/null
+++ b/contrib/terraform/aws/modules/elb/main.tf
@@ -0,0 +1,50 @@
+resource "aws_security_group" "aws-elb" {
+    name = "kubernetes-${var.aws_cluster_name}-securitygroup-elb"
+    vpc_id = "${var.aws_vpc_id}"
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-securitygroup-elb"
+    }
+}
+
+
+resource "aws_security_group_rule" "aws-allow-api-access" {
+    type = "ingress"
+    from_port = "${var.aws_elb_api_port}"
+    to_port = "${var.k8s_secure_api_port}"
+    protocol = "TCP"
+    cidr_blocks = ["0.0.0.0/0"]
+    security_group_id = "${aws_security_group.aws-elb.id}"
+}
+
+
+# Create a new AWS ELB for K8S API
+resource "aws_elb" "aws-elb-api" {
+  name = "kubernetes-elb-${var.aws_cluster_name}"
+  subnets = ["${var.aws_subnet_ids_public}"]
+  security_groups = ["${aws_security_group.aws-elb.id}"]
+
+  listener {
+    instance_port = "${var.k8s_secure_api_port}"
+    instance_protocol = "tcp"
+    lb_port = "${var.aws_elb_api_port}"
+    lb_protocol = "tcp"
+  }
+
+  health_check {
+    healthy_threshold = 2
+    unhealthy_threshold = 2
+    timeout = 3
+    target = "HTTP:8080/"
+    interval = 30
+  }
+
+  cross_zone_load_balancing = true
+  idle_timeout = 400
+  connection_draining = true
+  connection_draining_timeout = 400
+
+  tags {
+    Name = "kubernetes-${var.aws_cluster_name}-elb-api"
+  }
+}
diff --git a/contrib/terraform/aws/modules/elb/outputs.tf b/contrib/terraform/aws/modules/elb/outputs.tf
new file mode 100644
index 0000000000000000000000000000000000000000..075c751e4eb642795493c7e51a84fa8918aae6e5
--- /dev/null
+++ b/contrib/terraform/aws/modules/elb/outputs.tf
@@ -0,0 +1,7 @@
+output "aws_elb_api_id" {
+    value = "${aws_elb.aws-elb-api.id}"
+}
+
+output "aws_elb_api_fqdn" {
+    value = "${aws_elb.aws-elb-api.dns_name}"
+}
diff --git a/contrib/terraform/aws/modules/elb/variables.tf b/contrib/terraform/aws/modules/elb/variables.tf
new file mode 100644
index 0000000000000000000000000000000000000000..c7f86847d1a85aa819c4f73b86bb0c7f5ad35e6d
--- /dev/null
+++ b/contrib/terraform/aws/modules/elb/variables.tf
@@ -0,0 +1,28 @@
+variable "aws_cluster_name" {
+    description = "Name of Cluster"
+}
+
+variable "aws_vpc_id" {
+    description = "AWS VPC ID"
+}
+
+variable "aws_elb_api_port" {
+    description = "Port for AWS ELB"
+}
+
+variable "k8s_secure_api_port" {
+    description = "Secure Port of K8S API Server"
+}
+
+
+
+variable "aws_avail_zones" {
+    description = "Availability Zones Used"
+    type = "list"
+}
+
+
+variable "aws_subnet_ids_public" {
+    description = "IDs of Public Subnets"
+    type = "list"
+}
diff --git a/contrib/terraform/aws/modules/iam/main.tf b/contrib/terraform/aws/modules/iam/main.tf
new file mode 100644
index 0000000000000000000000000000000000000000..88da00d90a336f6dec888795fde575d07d6bab09
--- /dev/null
+++ b/contrib/terraform/aws/modules/iam/main.tf
@@ -0,0 +1,138 @@
+#Add AWS Roles for Kubernetes
+
+resource "aws_iam_role" "kube-master" {
+    name = "kubernetes-${var.aws_cluster_name}-master"
+    assume_role_policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Effect": "Allow",
+      "Action": "sts:AssumeRole",
+      "Principal": {
+        "Service": "ec2.amazonaws.com"
+      }
+      }
+  ]
+}
+EOF
+}
+
+resource "aws_iam_role" "kube-worker" {
+    name = "kubernetes-${var.aws_cluster_name}-node"
+    assume_role_policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Effect": "Allow",
+      "Action": "sts:AssumeRole",
+      "Principal": {
+        "Service": "ec2.amazonaws.com"
+      }
+      }
+  ]
+}
+EOF
+}
+
+#Add AWS Policies for Kubernetes
+
+resource "aws_iam_role_policy" "kube-master" {
+    name = "kubernetes-${var.aws_cluster_name}-master"
+    role = "${aws_iam_role.kube-master.id}"
+    policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Effect": "Allow",
+      "Action": ["ec2:*"],
+      "Resource": ["*"]
+    },
+    {
+      "Effect": "Allow",
+      "Action": ["elasticloadbalancing:*"],
+      "Resource": ["*"]
+    },
+    {
+      "Effect": "Allow",
+      "Action": ["route53:*"],
+      "Resource": ["*"]
+    },
+    {
+      "Effect": "Allow",
+      "Action": "s3:*",
+      "Resource": [
+        "arn:aws:s3:::kubernetes-*"
+      ]
+    }
+  ]
+}
+EOF
+}
+
+resource "aws_iam_role_policy" "kube-worker" {
+    name = "kubernetes-${var.aws_cluster_name}-node"
+    role = "${aws_iam_role.kube-worker.id}"
+    policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+        {
+          "Effect": "Allow",
+          "Action": "s3:*",
+          "Resource": [
+            "arn:aws:s3:::kubernetes-*"
+          ]
+        },
+        {
+          "Effect": "Allow",
+          "Action": "ec2:Describe*",
+          "Resource": "*"
+        },
+        {
+          "Effect": "Allow",
+          "Action": "ec2:AttachVolume",
+          "Resource": "*"
+        },
+        {
+          "Effect": "Allow",
+          "Action": "ec2:DetachVolume",
+          "Resource": "*"
+        },
+        {
+          "Effect": "Allow",
+          "Action": ["route53:*"],
+          "Resource": ["*"]
+        },
+        {
+          "Effect": "Allow",
+          "Action": [
+            "ecr:GetAuthorizationToken",
+            "ecr:BatchCheckLayerAvailability",
+            "ecr:GetDownloadUrlForLayer",
+            "ecr:GetRepositoryPolicy",
+            "ecr:DescribeRepositories",
+            "ecr:ListImages",
+            "ecr:BatchGetImage"
+          ],
+          "Resource": "*"
+        }
+      ]
+}
+EOF
+}
+
+
+#Create AWS Instance Profiles
+
+resource "aws_iam_instance_profile" "kube-master" {
+    name = "kube_${var.aws_cluster_name}_master_profile"
+    roles = ["${aws_iam_role.kube-master.name}"]
+}
+
+resource "aws_iam_instance_profile" "kube-worker" {
+    name = "kube_${var.aws_cluster_name}_node_profile"
+    roles = ["${aws_iam_role.kube-worker.name}"]
+}
diff --git a/contrib/terraform/aws/modules/iam/outputs.tf b/contrib/terraform/aws/modules/iam/outputs.tf
new file mode 100644
index 0000000000000000000000000000000000000000..a6ccf88474584433f5e62fee51c73bceb3ab9211
--- /dev/null
+++ b/contrib/terraform/aws/modules/iam/outputs.tf
@@ -0,0 +1,7 @@
+output "kube-master-profile" {
+    value = "${aws_iam_instance_profile.kube-master.name }"
+}
+
+output "kube-worker-profile" {
+    value = "${aws_iam_instance_profile.kube-worker.name }"
+}
diff --git a/contrib/terraform/aws/modules/iam/variables.tf b/contrib/terraform/aws/modules/iam/variables.tf
new file mode 100644
index 0000000000000000000000000000000000000000..690fbe75617e91c0c3aca663310aafcd241bab53
--- /dev/null
+++ b/contrib/terraform/aws/modules/iam/variables.tf
@@ -0,0 +1,3 @@
+variable "aws_cluster_name" {
+    description = "Name of Cluster"
+}
diff --git a/contrib/terraform/aws/modules/vpc/main.tf b/contrib/terraform/aws/modules/vpc/main.tf
new file mode 100644
index 0000000000000000000000000000000000000000..c1ea1dc11a9050fa7ac211726e62a94297f5711f
--- /dev/null
+++ b/contrib/terraform/aws/modules/vpc/main.tf
@@ -0,0 +1,138 @@
+
+resource "aws_vpc" "cluster-vpc" {
+    cidr_block = "${var.aws_vpc_cidr_block}"
+
+    #DNS Related Entries
+    enable_dns_support = true
+    enable_dns_hostnames = true
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-vpc"
+    }
+}
+
+
+resource "aws_eip" "cluster-nat-eip" {
+  count    = "${length(var.aws_cidr_subnets_public)}"
+  vpc      = true
+}
+
+
+
+resource "aws_internet_gateway" "cluster-vpc-internetgw" {
+  vpc_id = "${aws_vpc.cluster-vpc.id}"
+
+  tags {
+      Name = "kubernetes-${var.aws_cluster_name}-internetgw"
+  }
+}
+
+resource "aws_subnet" "cluster-vpc-subnets-public" {
+    vpc_id = "${aws_vpc.cluster-vpc.id}"
+    count="${length(var.aws_avail_zones)}"
+    availability_zone = "${element(var.aws_avail_zones, count.index)}"
+    cidr_block = "${element(var.aws_cidr_subnets_public, count.index)}"
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-${element(var.aws_avail_zones, count.index)}-public"
+    }
+}
+
+resource "aws_nat_gateway" "cluster-nat-gateway" {
+    count = "${length(var.aws_cidr_subnets_public)}"
+    allocation_id = "${element(aws_eip.cluster-nat-eip.*.id, count.index)}"
+    subnet_id = "${element(aws_subnet.cluster-vpc-subnets-public.*.id, count.index)}"
+
+}
+
+resource "aws_subnet" "cluster-vpc-subnets-private" {
+    vpc_id = "${aws_vpc.cluster-vpc.id}"
+    count="${length(var.aws_avail_zones)}"
+    availability_zone = "${element(var.aws_avail_zones, count.index)}"
+    cidr_block = "${element(var.aws_cidr_subnets_private, count.index)}"
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-${element(var.aws_avail_zones, count.index)}-private"
+    }
+}
+
+#Routing in VPC
+
+#TODO: Do we need two routing tables for each subnet for redundancy or is one enough?
+
+resource "aws_route_table" "kubernetes-public" {
+    vpc_id = "${aws_vpc.cluster-vpc.id}"
+    route {
+        cidr_block = "0.0.0.0/0"
+        gateway_id = "${aws_internet_gateway.cluster-vpc-internetgw.id}"
+    }
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-routetable-public"
+    }
+}
+
+resource "aws_route_table" "kubernetes-private" {
+    count = "${length(var.aws_cidr_subnets_private)}"
+    vpc_id = "${aws_vpc.cluster-vpc.id}"
+    route {
+        cidr_block = "0.0.0.0/0"
+        gateway_id = "${element(aws_nat_gateway.cluster-nat-gateway.*.id, count.index)}"
+    }
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-routetable-private-${count.index}"
+    }
+}
+
+resource "aws_route_table_association" "kubernetes-public" {
+    count = "${length(var.aws_cidr_subnets_public)}"
+    subnet_id = "${element(aws_subnet.cluster-vpc-subnets-public.*.id,count.index)}"
+    route_table_id = "${aws_route_table.kubernetes-public.id}"
+
+}
+
+resource "aws_route_table_association" "kubernetes-private" {
+    count = "${length(var.aws_cidr_subnets_private)}"
+    subnet_id = "${element(aws_subnet.cluster-vpc-subnets-private.*.id,count.index)}"
+    route_table_id = "${element(aws_route_table.kubernetes-private.*.id,count.index)}"
+
+}
+
+
+#Kubernetes Security Groups
+
+resource "aws_security_group" "kubernetes" {
+    name = "kubernetes-${var.aws_cluster_name}-securitygroup"
+    vpc_id = "${aws_vpc.cluster-vpc.id}"
+
+    tags {
+        Name = "kubernetes-${var.aws_cluster_name}-securitygroup"
+    }
+}
+
+resource "aws_security_group_rule" "allow-all-ingress" {
+    type = "ingress"
+    from_port = 0
+    to_port = 65535
+    protocol = "-1"
+    cidr_blocks= ["${var.aws_vpc_cidr_block}"]
+    security_group_id = "${aws_security_group.kubernetes.id}"
+}
+
+resource "aws_security_group_rule" "allow-all-egress" {
+    type = "egress"
+    from_port = 0
+    to_port = 65535
+    protocol = "-1"
+    cidr_blocks = ["0.0.0.0/0"]
+    security_group_id = "${aws_security_group.kubernetes.id}"
+}
+
+
+resource "aws_security_group_rule" "allow-ssh-connections" {
+    type = "ingress"
+    from_port = 22
+    to_port = 22
+    protocol = "TCP"
+    cidr_blocks = ["0.0.0.0/0"]
+    security_group_id = "${aws_security_group.kubernetes.id}"
+}
diff --git a/contrib/terraform/aws/modules/vpc/outputs.tf b/contrib/terraform/aws/modules/vpc/outputs.tf
new file mode 100644
index 0000000000000000000000000000000000000000..950462a486e3d32790924f0583568c0e5db0364b
--- /dev/null
+++ b/contrib/terraform/aws/modules/vpc/outputs.tf
@@ -0,0 +1,16 @@
+output "aws_vpc_id" {
+    value = "${aws_vpc.cluster-vpc.id}"
+}
+
+output "aws_subnet_ids_private" {
+    value = ["${aws_subnet.cluster-vpc-subnets-private.*.id}"]
+}
+
+output "aws_subnet_ids_public" {
+    value = ["${aws_subnet.cluster-vpc-subnets-public.*.id}"]
+}
+
+output "aws_security_group" {
+    value = ["${aws_security_group.kubernetes.*.id}"]
+
+}
diff --git a/contrib/terraform/aws/modules/vpc/variables.tf b/contrib/terraform/aws/modules/vpc/variables.tf
new file mode 100644
index 0000000000000000000000000000000000000000..55adf2be315b7f0655f4a7b28bdafd94688b7b7d
--- /dev/null
+++ b/contrib/terraform/aws/modules/vpc/variables.tf
@@ -0,0 +1,24 @@
+variable "aws_vpc_cidr_block" {
+    description = "CIDR Blocks for AWS VPC"
+}
+
+
+variable "aws_cluster_name" {
+    description = "Name of Cluster"
+}
+
+
+variable "aws_avail_zones" {
+    description = "AWS Availability Zones Used"
+    type = "list"
+}
+
+variable "aws_cidr_subnets_private" {
+  description = "CIDR Blocks for private subnets in Availability zones"
+  type    = "list"
+}
+
+variable "aws_cidr_subnets_public" {
+  description = "CIDR Blocks for public subnets in Availability zones"
+  type    = "list"
+}
diff --git a/contrib/terraform/aws/output.tf b/contrib/terraform/aws/output.tf
new file mode 100644
index 0000000000000000000000000000000000000000..fbe74f2622c7fb697bbecffd9a05c6a738c7b7b7
--- /dev/null
+++ b/contrib/terraform/aws/output.tf
@@ -0,0 +1,20 @@
+output "bastion_ip" {
+    value = "${join("\n", aws_instance.bastion-server.*.public_ip)}"
+}
+
+output "masters" {
+    value = "${join("\n", aws_instance.k8s-master.*.private_ip)}"
+}
+
+output "workers" {
+    value = "${join("\n", aws_instance.k8s-worker.*.private_ip)}"
+}
+
+output "etcd" {
+    value = "${join("\n", aws_instance.k8s-etcd.*.private_ip)}"
+}
+
+
+output "aws_elb_api_fqdn" {
+    value = "${module.aws-elb.aws_elb_api_fqdn}:${var.aws_elb_api_port}"
+}
diff --git a/contrib/terraform/aws/templates/inventory.tpl b/contrib/terraform/aws/templates/inventory.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..4140aa768e5a029234d815c5d1d56207140499d3
--- /dev/null
+++ b/contrib/terraform/aws/templates/inventory.tpl
@@ -0,0 +1,27 @@
+${connection_strings_master}
+${connection_strings_node}
+${connection_strings_etcd}
+
+
+${public_ip_address_bastion}
+
+[kube-master]
+${list_master}
+
+
+[kube-node]
+${list_node}
+
+
+[etcd]
+${list_etcd}
+
+
+[k8s-cluster:children]
+kube-node
+kube-master
+
+
+[k8s-cluster:vars]
+${elb_api_fqdn}
+${elb_api_port}
diff --git a/contrib/terraform/aws/terraform.tfvars b/contrib/terraform/aws/terraform.tfvars
index 012babc27f57c36f3202e017224848c235dce56b..214ef89db2fd84a6002f3fd0c237278dbf2a65c9 100644
--- a/contrib/terraform/aws/terraform.tfvars
+++ b/contrib/terraform/aws/terraform.tfvars
@@ -1,22 +1,32 @@
-deploymentName="test-kube-deploy"
+#Global Vars
+aws_cluster_name = "devtest"
+aws_region = "eu-central-1"
 
-numControllers="2"
-numEtcd="3"
-numNodes="2"
+#VPC Vars
+aws_vpc_cidr_block = "10.250.192.0/18"
+aws_cidr_subnets_private = ["10.250.192.0/20","10.250.208.0/20"]
+aws_cidr_subnets_public = ["10.250.224.0/20","10.250.240.0/20"]
+aws_avail_zones = ["eu-central-1a","eu-central-1b"]
 
-volSizeController="20"
-volSizeEtcd="20"
-volSizeNodes="20"
+#Bastion Host
+aws_bastion_ami = "ami-5900cc36"
+aws_bastion_size = "t2.small"
 
-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"
+#Kubernetes Cluster
 
-terminate_protect="false"
+aws_kube_master_num = 3
+aws_kube_master_size = "t2.medium"
+
+aws_etcd_num = 3
+aws_etcd_size = "t2.medium"
+
+aws_kube_worker_num = 4
+aws_kube_worker_size = "t2.medium"
+
+aws_cluster_ami = "ami-903df7ff"
+
+#Settings AWS ELB
+
+aws_elb_api_port = 443
+k8s_secure_api_port = 443
diff --git a/contrib/terraform/aws/variables.tf b/contrib/terraform/aws/variables.tf
new file mode 100644
index 0000000000000000000000000000000000000000..90f356d4bf9e544757922226193c637eb404c11a
--- /dev/null
+++ b/contrib/terraform/aws/variables.tf
@@ -0,0 +1,97 @@
+variable "AWS_ACCESS_KEY_ID" {
+  description = "AWS Access Key"
+}
+
+variable "AWS_SECRET_ACCESS_KEY" {
+  description = "AWS Secret Key"
+}
+
+variable "AWS_SSH_KEY_NAME" {
+  description = "Name of the SSH keypair to use in AWS."
+}
+
+variable "AWS_DEFAULT_REGION" {
+  description = "AWS Region"
+}
+
+//General Cluster Settings
+
+variable "aws_cluster_name" {
+  description = "Name of AWS Cluster"
+}
+
+
+//AWS VPC Variables
+
+variable "aws_vpc_cidr_block" {
+  description = "CIDR Block for VPC"
+}
+
+variable "aws_avail_zones" {
+  description = "Availability Zones Used"
+  type = "list"
+}
+
+variable "aws_cidr_subnets_private" {
+  description = "CIDR Blocks for private subnets in Availability zones1"
+  type = "list"
+}
+
+variable "aws_cidr_subnets_public" {
+  description = "CIDR Blocks for public subnets in Availability zones1"
+  type = "list"
+}
+
+//AWS EC2 Settings
+
+variable "aws_bastion_ami" {
+    description = "AMI ID for Bastion Host in chosen AWS Region"
+}
+
+variable "aws_bastion_size" {
+    description = "EC2 Instance Size of Bastion Host"
+}
+
+/*
+* AWS EC2 Settings
+* The number should be divisable by the number of used
+* AWS Availability Zones without an remainder.
+*/
+variable "aws_kube_master_num" {
+    description = "Number of Kubernetes Master Nodes"
+}
+
+variable "aws_kube_master_size" {
+    description = "Instance size of Kube Master Nodes"
+}
+
+variable "aws_etcd_num" {
+    description = "Number of etcd Nodes"
+}
+
+variable "aws_etcd_size" {
+    description = "Instance size of etcd Nodes"
+}
+
+variable "aws_kube_worker_num" {
+    description = "Number of Kubernetes Worker Nodes"
+}
+
+variable "aws_kube_worker_size" {
+    description = "Instance size of Kubernetes Worker Nodes"
+}
+
+variable "aws_cluster_ami" {
+    description = "AMI ID for Kubernetes Cluster"
+}
+/*
+* AWS ELB Settings
+*
+*/
+variable "aws_elb_api_port" {
+    description = "Port for AWS ELB"
+}
+
+variable "k8s_secure_api_port" {
+    description = "Secure Port of K8S API Server"
+}