Browse Source
Rewrote AWS Terraform for Kargo
Rewrote AWS Terraform for Kargo
Rewrote AWS Terraform deployment for AWS Kargo. It supports now multiple Availability Zones, AWS Loadbalancer for Kubernetes API, Bastion Host, ... For more information see READMEpull/1105/head
Vincent Schwarzer
7 years ago
20 changed files with 794 additions and 327 deletions
Split View
Diff Options
-
2contrib/terraform/aws/.gitignore
-
261contrib/terraform/aws/00-create-infrastructure.tf
-
37contrib/terraform/aws/01-create-inventory.tf
-
29contrib/terraform/aws/README.md
-
185contrib/terraform/aws/create-infrastructure.tf
-
8contrib/terraform/aws/credentials.tfvars.example
-
BINcontrib/terraform/aws/docs/aws_kargo.png
-
50contrib/terraform/aws/modules/elb/main.tf
-
7contrib/terraform/aws/modules/elb/outputs.tf
-
28contrib/terraform/aws/modules/elb/variables.tf
-
138contrib/terraform/aws/modules/iam/main.tf
-
7contrib/terraform/aws/modules/iam/outputs.tf
-
3contrib/terraform/aws/modules/iam/variables.tf
-
138contrib/terraform/aws/modules/vpc/main.tf
-
16contrib/terraform/aws/modules/vpc/outputs.tf
-
24contrib/terraform/aws/modules/vpc/variables.tf
-
20contrib/terraform/aws/output.tf
-
27contrib/terraform/aws/templates/inventory.tpl
-
44contrib/terraform/aws/terraform.tfvars
-
97contrib/terraform/aws/variables.tf
@ -1,2 +1,2 @@ |
|||
*.tfstate* |
|||
inventory |
|||
.terraform |
@ -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)}" |
|||
} |
|||
|
|||
|
@ -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" |
|||
} |
|||
} |
@ -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" |
|||
} |
|||
|
|||
} |
@ -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" |
@ -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" |
|||
} |
|||
} |
@ -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}" |
|||
} |
@ -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" |
|||
} |
@ -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}"] |
|||
} |
@ -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 }" |
|||
} |
@ -0,0 +1,3 @@ |
|||
variable "aws_cluster_name" { |
|||
description = "Name of Cluster" |
|||
} |
@ -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}" |
|||
} |
@ -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}"] |
|||
|
|||
} |
@ -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" |
|||
} |
@ -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}" |
|||
} |
@ -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} |
@ -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 |
@ -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" |
|||
} |
Write
Preview
Loading…
Cancel
Save