From fa1290fa544ce1f9f7a48ad38c91b21599791cbd Mon Sep 17 00:00:00 2001 From: aknysh Date: Wed, 25 Sep 2019 15:48:40 -0400 Subject: [PATCH 01/10] Convert to TF 0.12 --- .gitignore | 3 - .travis.yml | 16 -- examples/complete/main.tf | 92 ++++++------ examples/complete/outputs.tf | 31 ++-- examples/complete/variables.tf | 101 +++++++------ examples/complete/versions.tf | 8 + main.tf | 262 +++++++++++++++++---------------- outputs.tf | 35 ++--- variables.tf | 124 ++++++++-------- versions.tf | 8 + 10 files changed, 350 insertions(+), 330 deletions(-) delete mode 100644 .travis.yml create mode 100644 examples/complete/versions.tf create mode 100644 versions.tf diff --git a/.gitignore b/.gitignore index f083a21..0c6f3c5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,6 @@ *.tfstate *.tfstate.* -# .tfvars files -*.tfvars - **/.idea **/*.iml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 241026e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -addons: - apt: - packages: - - git - - make - - curl - -install: - - make init - -script: - - make terraform/install - - make terraform/get-plugins - - make terraform/get-modules - - make terraform/lint - - make terraform/validate diff --git a/examples/complete/main.tf b/examples/complete/main.tf index d87371f..5d9ab70 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -1,65 +1,65 @@ provider "aws" { - region = "${var.region}" + region = var.region } locals { # The usage of the specific kubernetes.io/cluster/* resource tags below are required # for EKS and Kubernetes to discover and manage networking resources # https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#base-vpc-networking - tags = "${merge(var.tags, map("kubernetes.io/cluster/${var.cluster_name}", "shared"))}" + tags = merge( + var.tags, + { + "kubernetes.io/cluster/${var.cluster_name}" = "shared" + } + ) } -data "aws_availability_zones" "available" {} - module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=master" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${local.tags}" - cidr_block = "10.0.0.0/16" + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.0" + namespace = var.namespace + stage = var.stage + name = var.name + cidr_block = "172.16.0.0/16" } module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=master" - availability_zones = ["${data.aws_availability_zones.available.names}"] - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${local.tags}" - region = "${var.region}" - vpc_id = "${module.vpc.vpc_id}" - igw_id = "${module.vpc.igw_id}" - cidr_block = "${module.vpc.vpc_cidr_block}" - nat_gateway_enabled = "true" + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.0" + availability_zones = var.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = false + nat_instance_enabled = false } module "eks_workers" { - source = "git::https://github.com/cloudposse/terraform-aws-eks-workers.git?ref=master" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${var.tags}" - image_id = "${var.image_id}" - eks_worker_ami_name_filter = "${var.eks_worker_ami_name_filter}" - instance_type = "${var.instance_type}" - vpc_id = "${module.vpc.vpc_id}" - subnet_ids = ["${module.subnets.public_subnet_ids}"] - health_check_type = "${var.health_check_type}" - min_size = "${var.min_size}" - max_size = "${var.max_size}" - wait_for_capacity_timeout = "${var.wait_for_capacity_timeout}" - associate_public_ip_address = "${var.associate_public_ip_address}" - cluster_name = "${var.cluster_name}" - cluster_endpoint = "${var.cluster_endpoint}" - cluster_certificate_authority_data = "${var.cluster_certificate_authority_data}" - cluster_security_group_id = "${var.cluster_security_group_id}" + source = "../../" + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + tags = var.tags + image_id = var.image_id + eks_worker_ami_name_filter = var.eks_worker_ami_name_filter + instance_type = var.instance_type + vpc_id = module.vpc.vpc_id + subnet_ids = [module.subnets.public_subnet_ids] + health_check_type = var.health_check_type + min_size = var.min_size + max_size = var.max_size + wait_for_capacity_timeout = var.wait_for_capacity_timeout + associate_public_ip_address = var.associate_public_ip_address + cluster_name = var.cluster_name + cluster_endpoint = var.cluster_endpoint + cluster_certificate_authority_data = var.cluster_certificate_authority_data + cluster_security_group_id = var.cluster_security_group_id # Auto-scaling policies and CloudWatch metric alarms - autoscaling_policies_enabled = "${var.autoscaling_policies_enabled}" - cpu_utilization_high_threshold_percent = "${var.cpu_utilization_high_threshold_percent}" - cpu_utilization_low_threshold_percent = "${var.cpu_utilization_low_threshold_percent}" + autoscaling_policies_enabled = var.autoscaling_policies_enabled + cpu_utilization_high_threshold_percent = var.cpu_utilization_high_threshold_percent + cpu_utilization_low_threshold_percent = var.cpu_utilization_low_threshold_percent } + diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 9dfda4c..b532455 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -1,74 +1,75 @@ output "launch_template_id" { description = "ID of the launch template" - value = "${module.eks_workers.launch_template_id}" + value = module.eks_workers.launch_template_id } output "launch_template_arn" { description = "ARN of the launch template" - value = "${module.eks_workers.launch_template_arn}" + value = module.eks_workers.launch_template_arn } output "autoscaling_group_id" { description = "The AutoScaling Group ID" - value = "${module.eks_workers.autoscaling_group_id}" + value = module.eks_workers.autoscaling_group_id } output "autoscaling_group_name" { description = "The AutoScaling Group name" - value = "${module.eks_workers.autoscaling_group_name}" + value = module.eks_workers.autoscaling_group_name } output "autoscaling_group_arn" { description = "ARN of the AutoScaling Group" - value = "${module.eks_workers.autoscaling_group_arn}" + value = module.eks_workers.autoscaling_group_arn } output "autoscaling_group_min_size" { description = "The minimum size of the AutoScaling Group" - value = "${module.eks_workers.autoscaling_group_min_size}" + value = module.eks_workers.autoscaling_group_min_size } output "autoscaling_group_max_size" { description = "The maximum size of the AutoScaling Group" - value = "${module.eks_workers.autoscaling_group_max_size}" + value = module.eks_workers.autoscaling_group_max_size } output "autoscaling_group_desired_capacity" { description = "The number of Amazon EC2 instances that should be running in the group" - value = "${module.eks_workers.autoscaling_group_desired_capacity}" + value = module.eks_workers.autoscaling_group_desired_capacity } output "autoscaling_group_default_cooldown" { description = "Time between a scaling activity and the succeeding scaling activity" - value = "${module.eks_workers.autoscaling_group_default_cooldown}" + value = module.eks_workers.autoscaling_group_default_cooldown } output "autoscaling_group_health_check_grace_period" { description = "Time after instance comes into service before checking health" - value = "${module.eks_workers.autoscaling_group_health_check_grace_period}" + value = module.eks_workers.autoscaling_group_health_check_grace_period } output "autoscaling_group_health_check_type" { description = "`EC2` or `ELB`. Controls how health checking is done" - value = "${module.eks_workers.autoscaling_group_health_check_type}" + value = module.eks_workers.autoscaling_group_health_check_type } output "security_group_id" { description = "ID of the worker nodes Security Group" - value = "${module.eks_workers.security_group_id}" + value = module.eks_workers.security_group_id } output "security_group_arn" { description = "ARN of the worker nodes Security Group" - value = "${module.eks_workers.security_group_arn}" + value = module.eks_workers.security_group_arn } output "security_group_name" { description = "Name of the worker nodes Security Group" - value = "${module.eks_workers.security_group_name}" + value = module.eks_workers.security_group_name } output "config_map_aws_auth" { description = "Kubernetes ConfigMap configuration for worker nodes to join the EKS cluster. https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes" - value = "${module.eks_workers.config_map_aws_auth}" + value = module.eks_workers.config_map_aws_auth } + diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index 63d0802..0930dc9 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -1,103 +1,108 @@ variable "namespace" { - type = "string" + type = string default = "eg" description = "Namespace, which could be your organization name, e.g. 'eg' or 'cp'" } variable "stage" { - type = "string" + type = string default = "testing" description = "Stage, e.g. 'prod', 'staging', 'dev', or 'test'" } variable "environment" { - type = "string" + type = string default = "" description = "Environment, e.g. 'testing', 'UAT'" } variable "name" { - type = "string" + type = string default = "test" description = "Solution name, e.g. 'app' or 'cluster'" } variable "delimiter" { - type = "string" + type = string default = "-" description = "Delimiter to be used between `namespace`, `stage`, `name` and `attributes`" } variable "attributes" { - type = "list" + type = list(string) default = [] description = "Additional attributes (e.g. `1`)" } variable "tags" { - type = "map" + type = map(string) default = {} description = "Additional tags (e.g. `{ BusinessUnit = \"XYZ\" }`" } variable "enabled" { - type = "string" + type = string description = "Whether to create the resources. Set to `false` to prevent the module from creating any resources" default = "true" } variable "region" { - type = "string" + type = string default = "us-west-2" description = "AWS Region" } +variable "availability_zones" { + type = list(string) + description = "List of availability zones" +} + variable "cluster_name" { - type = "string" + type = string description = "The name of the EKS cluster" } variable "cluster_endpoint" { - type = "string" + type = string description = "EKS cluster endpoint" } variable "cluster_certificate_authority_data" { - type = "string" + type = string description = "The base64 encoded certificate data required to communicate with the cluster" } variable "cluster_security_group_id" { - type = "string" + type = string description = "Security Group ID of the EKS cluster" } variable "instance_initiated_shutdown_behavior" { - type = "string" + type = string description = "Shutdown behavior for the instances. Can be `stop` or `terminate`" default = "terminate" } variable "image_id" { - type = "string" + type = string description = "EC2 image ID to launch. If not provided, the module will lookup the most recent EKS AMI. See https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html for more details on EKS-optimized images" default = "" } variable "eks_worker_ami_name_filter" { - type = "string" + type = string description = "AMI name filter to lookup the most recent EKS AMI if `image_id` is not provided" default = "amazon-eks-node-v*" } variable "instance_type" { - type = "string" + type = string default = "t2.medium" description = "Instance type to launch" } variable "key_name" { - type = "string" + type = string description = "The SSH key name that should be used for the instance" default = "" } @@ -119,31 +124,31 @@ variable "ebs_optimized" { variable "block_device_mappings" { description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" - type = "list" + type = list(string) default = [] } variable "instance_market_options" { description = "The market (purchasing) option for the instances" - type = "list" + type = list(string) default = [] } variable "placement" { description = "The placement specifications of the instances" - type = "list" + type = list(string) default = [] } variable "credit_specification" { description = "Customize the credit specification of the instances" - type = "list" + type = list(string) default = [] } variable "elastic_gpu_specifications" { description = "Specifications of Elastic GPU to attach to the instances" - type = "list" + type = list(string) default = [] } @@ -173,7 +178,7 @@ variable "health_check_grace_period" { } variable "health_check_type" { - type = "string" + type = string description = "Controls how health checking is done. Valid values are `EC2` or `ELB`" default = "EC2" } @@ -184,44 +189,44 @@ variable "force_delete" { } variable "load_balancers" { - type = "list" + type = list(string) description = "A list of elastic load balancer names to add to the autoscaling group names. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead" default = [] } variable "target_group_arns" { - type = "list" + type = list(string) description = "A list of aws_alb_target_group ARNs, for use with Application Load Balancing" default = [] } variable "termination_policies" { description = "A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default`" - type = "list" + type = list(string) default = ["Default"] } variable "suspended_processes" { - type = "list" + type = list(string) description = "A list of processes to suspend for the AutoScaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your autoscaling group from functioning properly." default = [] } variable "placement_group" { - type = "string" + type = string description = "The name of the placement group into which to launch the instances, if any" default = "" } variable "metrics_granularity" { - type = "string" + type = string description = "The granularity to associate with the metrics to collect. The only valid value is 1Minute" default = "1Minute" } variable "enabled_metrics" { description = "A list of metrics to collect. The allowed values are `GroupMinSize`, `GroupMaxSize`, `GroupDesiredCapacity`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupTerminatingInstances`, `GroupTotalInstances`" - type = "list" + type = list(string) default = [ "GroupMinSize", @@ -236,7 +241,7 @@ variable "enabled_metrics" { } variable "wait_for_capacity_timeout" { - type = "string" + type = string description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. (See also Waiting for Capacity below.) Setting this to '0' causes Terraform to skip all Capacity Waiting behavior" default = "10m" } @@ -257,19 +262,19 @@ variable "protect_from_scale_in" { } variable "service_linked_role_arn" { - type = "string" + type = string description = "The ARN of the service-linked role that the ASG will use to call other AWS services" default = "" } variable "autoscaling_policies_enabled" { - type = "string" + type = string default = "true" description = "Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling" } variable "scale_up_cooldown_seconds" { - type = "string" + type = string default = "300" description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" } @@ -280,19 +285,19 @@ variable "scale_up_scaling_adjustment" { } variable "scale_up_adjustment_type" { - type = "string" + type = string default = "ChangeInCapacity" description = "Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity`" } variable "scale_up_policy_type" { - type = "string" + type = string default = "SimpleScaling" description = "The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling`" } variable "scale_down_cooldown_seconds" { - type = "string" + type = string default = "300" description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" } @@ -303,61 +308,61 @@ variable "scale_down_scaling_adjustment" { } variable "scale_down_adjustment_type" { - type = "string" + type = string default = "ChangeInCapacity" description = "Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity`" } variable "scale_down_policy_type" { - type = "string" + type = string default = "SimpleScaling" description = "The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling`" } variable "cpu_utilization_high_evaluation_periods" { - type = "string" + type = string default = "2" description = "The number of periods over which data is compared to the specified threshold" } variable "cpu_utilization_high_period_seconds" { - type = "string" + type = string default = "300" description = "The period in seconds over which the specified statistic is applied" } variable "cpu_utilization_high_threshold_percent" { - type = "string" + type = string default = "90" description = "The value against which the specified statistic is compared" } variable "cpu_utilization_high_statistic" { - type = "string" + type = string default = "Average" description = "The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum`" } variable "cpu_utilization_low_evaluation_periods" { - type = "string" + type = string default = "2" description = "The number of periods over which data is compared to the specified threshold" } variable "cpu_utilization_low_period_seconds" { - type = "string" + type = string default = "300" description = "The period in seconds over which the specified statistic is applied" } variable "cpu_utilization_low_threshold_percent" { - type = "string" + type = string default = "10" description = "The value against which the specified statistic is compared" } variable "cpu_utilization_low_statistic" { - type = "string" + type = string default = "Average" description = "The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum`" } diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf new file mode 100644 index 0000000..d945c37 --- /dev/null +++ b/examples/complete/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + } +} diff --git a/main.tf b/main.tf index 96e0070..3e58ea2 100644 --- a/main.tf +++ b/main.tf @@ -1,26 +1,31 @@ locals { - tags = "${merge(var.tags, map("kubernetes.io/cluster/${var.cluster_name}", "owned"))}" + tags = merge( + var.tags, + { + "kubernetes.io/cluster/${var.cluster_name}" = "owned" + } + ) } module "label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.2.1" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - delimiter = "${var.delimiter}" - attributes = ["${compact(concat(var.attributes, list("workers")))}"] - tags = "${local.tags}" - enabled = "${var.enabled}" + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.15.0" + namespace = var.namespace + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = [compact(concat(var.attributes, ["workers"]))] + tags = local.tags + enabled = var.enabled } data "aws_iam_policy_document" "assume_role" { - count = "${var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0}" + count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 statement { effect = "Allow" actions = ["sts:AssumeRole"] - principals = { + principals { type = "Service" identifiers = ["ec2.amazonaws.com"] } @@ -28,206 +33,215 @@ data "aws_iam_policy_document" "assume_role" { } resource "aws_iam_role" "default" { - count = "${var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0}" - name = "${module.label.id}" - assume_role_policy = "${join("", data.aws_iam_policy_document.assume_role.*.json)}" + count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 + name = module.label.id + assume_role_policy = join("", data.aws_iam_policy_document.assume_role.*.json) } resource "aws_iam_role_policy_attachment" "amazon_eks_worker_node_policy" { - count = "${var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0}" + count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" - role = "${join("", aws_iam_role.default.*.name)}" + role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "amazon_eks_cni_policy" { - count = "${var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0}" + count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" - role = "${join("", aws_iam_role.default.*.name)}" + role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "amazon_ec2_container_registry_read_only" { - count = "${var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0}" + count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" - role = "${join("", aws_iam_role.default.*.name)}" + role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "existing_policies_attach_to_eks_workers_role" { - count = "${var.enabled == "true" && var.use_existing_aws_iam_instance_profile== "false" ? var.workers_role_policy_arns_count : 0}" - policy_arn = "${element(var.workers_role_policy_arns, count.index)}" - role = "${join("", aws_iam_role.default.*.name)}" + count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? var.workers_role_policy_arns_count : 0 + policy_arn = element(var.workers_role_policy_arns, count.index) + role = join("", aws_iam_role.default.*.name) } resource "aws_iam_instance_profile" "default" { - count = "${var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0}" - name = "${module.label.id}" - role = "${join("", aws_iam_role.default.*.name)}" + count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 + name = module.label.id + role = join("", aws_iam_role.default.*.name) } resource "aws_security_group" "default" { - count = "${var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0}" - name = "${module.label.id}" + count = var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0 + name = module.label.id description = "Security Group for EKS worker nodes" - vpc_id = "${var.vpc_id}" - tags = "${module.label.tags}" + vpc_id = var.vpc_id + tags = module.label.tags } resource "aws_security_group_rule" "egress" { - count = "${var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0}" + count = var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0 description = "Allow all egress traffic" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] - security_group_id = "${join("", aws_security_group.default.*.id)}" + security_group_id = join("", aws_security_group.default.*.id) type = "egress" } resource "aws_security_group_rule" "ingress_self" { - count = "${var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0}" + count = var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0 description = "Allow nodes to communicate with each other" from_port = 0 to_port = 65535 protocol = "-1" - security_group_id = "${join("", aws_security_group.default.*.id)}" - source_security_group_id = "${join("", aws_security_group.default.*.id)}" + security_group_id = join("", aws_security_group.default.*.id) + source_security_group_id = join("", aws_security_group.default.*.id) type = "ingress" } resource "aws_security_group_rule" "ingress_cluster" { - count = "${var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0}" + count = var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0 description = "Allow worker kubelets and pods to receive communication from the cluster control plane" from_port = 0 to_port = 65535 protocol = "-1" - security_group_id = "${join("", aws_security_group.default.*.id)}" - source_security_group_id = "${var.cluster_security_group_id}" + security_group_id = join("", aws_security_group.default.*.id) + source_security_group_id = var.cluster_security_group_id type = "ingress" } resource "aws_security_group_rule" "ingress_security_groups" { - count = "${var.enabled == "true" && var.use_existing_security_group == "false" ? length(var.allowed_security_groups) : 0}" + count = var.enabled == "true" && var.use_existing_security_group == "false" ? length(var.allowed_security_groups) : 0 description = "Allow inbound traffic from existing Security Groups" from_port = 0 to_port = 65535 protocol = "-1" - source_security_group_id = "${element(var.allowed_security_groups, count.index)}" - security_group_id = "${join("", aws_security_group.default.*.id)}" + source_security_group_id = element(var.allowed_security_groups, count.index) + security_group_id = join("", aws_security_group.default.*.id) type = "ingress" } resource "aws_security_group_rule" "ingress_cidr_blocks" { - count = "${var.enabled == "true" && length(var.allowed_cidr_blocks) > 0 && var.use_existing_security_group == "false" ? 1 : 0}" + count = var.enabled == "true" && length(var.allowed_cidr_blocks) > 0 && var.use_existing_security_group == "false" ? 1 : 0 description = "Allow inbound traffic from CIDR blocks" from_port = 0 to_port = 0 protocol = "-1" - cidr_blocks = ["${var.allowed_cidr_blocks}"] - security_group_id = "${join("", aws_security_group.default.*.id)}" + cidr_blocks = var.allowed_cidr_blocks + security_group_id = join("", aws_security_group.default.*.id) type = "ingress" } data "aws_ami" "eks_worker" { - count = "${var.enabled == "true" && var.use_custom_image_id == "false" ? 1 : 0}" + count = var.enabled == "true" && var.use_custom_image_id == "false" ? 1 : 0 most_recent = true - name_regex = "${var.eks_worker_ami_name_regex}" + name_regex = var.eks_worker_ami_name_regex filter { name = "name" - values = ["${var.eks_worker_ami_name_filter}"] + values = [var.eks_worker_ami_name_filter] } owners = ["602401143452"] # Amazon } module "autoscale_group" { - source = "git::https://github.com/cloudposse/terraform-aws-ec2-autoscale-group.git?ref=tags/0.1.3" - - enabled = "${var.enabled}" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - delimiter = "${var.delimiter}" - attributes = "${var.attributes}" - - image_id = "${var.use_custom_image_id == "true" ? var.image_id : join("", data.aws_ami.eks_worker.*.id)}" - iam_instance_profile_name = "${var.use_existing_aws_iam_instance_profile == "false" ? join("", aws_iam_instance_profile.default.*.name) : var.aws_iam_instance_profile_name}" - security_group_ids = ["${compact(concat(list(var.use_existing_security_group == "false" ? join("", aws_security_group.default.*.id) : var.workers_security_group_id), var.additional_security_group_ids))}"] - user_data_base64 = "${base64encode(join("", data.template_file.userdata.*.rendered))}" - tags = "${module.label.tags}" - - instance_type = "${var.instance_type}" - subnet_ids = ["${var.subnet_ids}"] - min_size = "${var.min_size}" - max_size = "${var.max_size}" - associate_public_ip_address = "${var.associate_public_ip_address}" - block_device_mappings = ["${var.block_device_mappings}"] - credit_specification = ["${var.credit_specification}"] - disable_api_termination = "${var.disable_api_termination}" - ebs_optimized = "${var.ebs_optimized}" - elastic_gpu_specifications = ["${var.elastic_gpu_specifications}"] - instance_initiated_shutdown_behavior = "${var.instance_initiated_shutdown_behavior}" - instance_market_options = ["${var.instance_market_options }"] - key_name = "${var.key_name}" - placement = ["${var.placement}"] - enable_monitoring = "${var.enable_monitoring}" - load_balancers = ["${var.load_balancers}"] - health_check_grace_period = "${var.health_check_grace_period}" - health_check_type = "${var.health_check_type}" - min_elb_capacity = "${var.min_elb_capacity}" - wait_for_elb_capacity = "${var.wait_for_elb_capacity}" - target_group_arns = ["${var.target_group_arns}"] - default_cooldown = "${var.default_cooldown}" - force_delete = "${var.force_delete}" - termination_policies = "${var.termination_policies}" - suspended_processes = "${var.suspended_processes}" - placement_group = "${var.placement_group}" - enabled_metrics = ["${var.enabled_metrics}"] - metrics_granularity = "${var.metrics_granularity}" - wait_for_capacity_timeout = "${var.wait_for_capacity_timeout}" - protect_from_scale_in = "${var.protect_from_scale_in}" - service_linked_role_arn = "${var.service_linked_role_arn}" - autoscaling_policies_enabled = "${var.autoscaling_policies_enabled}" - scale_up_cooldown_seconds = "${var.scale_up_cooldown_seconds}" - scale_up_scaling_adjustment = "${var.scale_up_scaling_adjustment}" - scale_up_adjustment_type = "${var.scale_up_adjustment_type}" - scale_up_policy_type = "${var.scale_up_policy_type}" - scale_down_cooldown_seconds = "${var.scale_down_cooldown_seconds}" - scale_down_scaling_adjustment = "${var.scale_down_scaling_adjustment}" - scale_down_adjustment_type = "${var.scale_down_adjustment_type}" - scale_down_policy_type = "${var.scale_down_policy_type}" - cpu_utilization_high_evaluation_periods = "${var.cpu_utilization_high_evaluation_periods}" - cpu_utilization_high_period_seconds = "${var.cpu_utilization_high_period_seconds}" - cpu_utilization_high_threshold_percent = "${var.cpu_utilization_high_threshold_percent}" - cpu_utilization_high_statistic = "${var.cpu_utilization_high_statistic}" - cpu_utilization_low_evaluation_periods = "${var.cpu_utilization_low_evaluation_periods}" - cpu_utilization_low_period_seconds = "${var.cpu_utilization_low_period_seconds}" - cpu_utilization_low_statistic = "${var.cpu_utilization_low_statistic}" - cpu_utilization_low_threshold_percent = "${var.cpu_utilization_low_threshold_percent}" + source = "git::https://github.com/cloudposse/terraform-aws-ec2-autoscale-group.git?ref=tags/0.2.0" + + enabled = var.enabled + namespace = var.namespace + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + + image_id = var.use_custom_image_id == "true" ? var.image_id : join("", data.aws_ami.eks_worker.*.id) + iam_instance_profile_name = var.use_existing_aws_iam_instance_profile == "false" ? join("", aws_iam_instance_profile.default.*.name) : var.aws_iam_instance_profile_name + + security_group_ids = [compact( + concat( + [ + var.use_existing_security_group == "false" ? join("", aws_security_group.default.*.id) : var.workers_security_group_id, + ], + var.additional_security_group_ids + ) + )] + + user_data_base64 = base64encode(join("", data.template_file.userdata.*.rendered)) + tags = module.label.tags + + instance_type = var.instance_type + subnet_ids = [var.subnet_ids] + min_size = var.min_size + max_size = var.max_size + associate_public_ip_address = var.associate_public_ip_address + block_device_mappings = [var.block_device_mappings] + credit_specification = [var.credit_specification] + disable_api_termination = var.disable_api_termination + ebs_optimized = var.ebs_optimized + elastic_gpu_specifications = [var.elastic_gpu_specifications] + instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior + instance_market_options = [var.instance_market_options] + key_name = var.key_name + placement = [var.placement] + enable_monitoring = var.enable_monitoring + load_balancers = [var.load_balancers] + health_check_grace_period = var.health_check_grace_period + health_check_type = var.health_check_type + min_elb_capacity = var.min_elb_capacity + wait_for_elb_capacity = var.wait_for_elb_capacity + target_group_arns = [var.target_group_arns] + default_cooldown = var.default_cooldown + force_delete = var.force_delete + termination_policies = var.termination_policies + suspended_processes = var.suspended_processes + placement_group = var.placement_group + enabled_metrics = [var.enabled_metrics] + metrics_granularity = var.metrics_granularity + wait_for_capacity_timeout = var.wait_for_capacity_timeout + protect_from_scale_in = var.protect_from_scale_in + service_linked_role_arn = var.service_linked_role_arn + autoscaling_policies_enabled = var.autoscaling_policies_enabled + scale_up_cooldown_seconds = var.scale_up_cooldown_seconds + scale_up_scaling_adjustment = var.scale_up_scaling_adjustment + scale_up_adjustment_type = var.scale_up_adjustment_type + scale_up_policy_type = var.scale_up_policy_type + scale_down_cooldown_seconds = var.scale_down_cooldown_seconds + scale_down_scaling_adjustment = var.scale_down_scaling_adjustment + scale_down_adjustment_type = var.scale_down_adjustment_type + scale_down_policy_type = var.scale_down_policy_type + cpu_utilization_high_evaluation_periods = var.cpu_utilization_high_evaluation_periods + cpu_utilization_high_period_seconds = var.cpu_utilization_high_period_seconds + cpu_utilization_high_threshold_percent = var.cpu_utilization_high_threshold_percent + cpu_utilization_high_statistic = var.cpu_utilization_high_statistic + cpu_utilization_low_evaluation_periods = var.cpu_utilization_low_evaluation_periods + cpu_utilization_low_period_seconds = var.cpu_utilization_low_period_seconds + cpu_utilization_low_statistic = var.cpu_utilization_low_statistic + cpu_utilization_low_threshold_percent = var.cpu_utilization_low_threshold_percent } data "template_file" "userdata" { - count = "${var.enabled == "true" ? 1 : 0}" - template = "${file("${path.module}/userdata.tpl")}" - - vars { - cluster_endpoint = "${var.cluster_endpoint}" - certificate_authority_data = "${var.cluster_certificate_authority_data}" - cluster_name = "${var.cluster_name}" - bootstrap_extra_args = "${var.bootstrap_extra_args}" + count = var.enabled == "true" ? 1 : 0 + template = file("${path.module}/userdata.tpl") + + vars = { + cluster_endpoint = var.cluster_endpoint + certificate_authority_data = var.cluster_certificate_authority_data + cluster_name = var.cluster_name + bootstrap_extra_args = var.bootstrap_extra_args } } data "aws_iam_instance_profile" "default" { - count = "${var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "true" ? 1 : 0}" - name = "${var.aws_iam_instance_profile_name}" + count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "true" ? 1 : 0 + name = var.aws_iam_instance_profile_name } data "template_file" "config_map_aws_auth" { - count = "${var.enabled == "true" ? 1 : 0}" - template = "${file("${path.module}/config_map_aws_auth.tpl")}" + count = var.enabled == "true" ? 1 : 0 + template = file("${path.module}/config_map_aws_auth.tpl") - vars { - aws_iam_role_arn = "${var.use_existing_aws_iam_instance_profile == "true" ? join("", data.aws_iam_instance_profile.default.*.role_arn) : join("", aws_iam_role.default.*.arn)}" + vars = { + aws_iam_role_arn = var.use_existing_aws_iam_instance_profile == "true" ? join("", data.aws_iam_instance_profile.default.*.role_arn) : join("", aws_iam_role.default.*.arn) } } diff --git a/outputs.tf b/outputs.tf index 3d0b72d..794e987 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,84 +1,85 @@ output "launch_template_id" { description = "The ID of the launch template" - value = "${module.autoscale_group.launch_template_id}" + value = module.autoscale_group.launch_template_id } output "launch_template_arn" { description = "ARN of the launch template" - value = "${module.autoscale_group.launch_template_arn}" + value = module.autoscale_group.launch_template_arn } output "autoscaling_group_id" { description = "The AutoScaling Group ID" - value = "${module.autoscale_group.autoscaling_group_id}" + value = module.autoscale_group.autoscaling_group_id } output "autoscaling_group_name" { description = "The AutoScaling Group name" - value = "${module.autoscale_group.autoscaling_group_name}" + value = module.autoscale_group.autoscaling_group_name } output "autoscaling_group_arn" { description = "ARN of the AutoScaling Group" - value = "${module.autoscale_group.autoscaling_group_arn}" + value = module.autoscale_group.autoscaling_group_arn } output "autoscaling_group_min_size" { description = "The minimum size of the AutoScaling Group" - value = "${module.autoscale_group.autoscaling_group_min_size}" + value = module.autoscale_group.autoscaling_group_min_size } output "autoscaling_group_max_size" { description = "The maximum size of the AutoScaling Group" - value = "${module.autoscale_group.autoscaling_group_max_size}" + value = module.autoscale_group.autoscaling_group_max_size } output "autoscaling_group_desired_capacity" { description = "The number of Amazon EC2 instances that should be running in the group" - value = "${module.autoscale_group.autoscaling_group_desired_capacity}" + value = module.autoscale_group.autoscaling_group_desired_capacity } output "autoscaling_group_default_cooldown" { description = "Time between a scaling activity and the succeeding scaling activity" - value = "${module.autoscale_group.autoscaling_group_default_cooldown}" + value = module.autoscale_group.autoscaling_group_default_cooldown } output "autoscaling_group_health_check_grace_period" { description = "Time after instance comes into service before checking health" - value = "${module.autoscale_group.autoscaling_group_health_check_grace_period}" + value = module.autoscale_group.autoscaling_group_health_check_grace_period } output "autoscaling_group_health_check_type" { description = "`EC2` or `ELB`. Controls how health checking is done" - value = "${module.autoscale_group.autoscaling_group_health_check_type}" + value = module.autoscale_group.autoscaling_group_health_check_type } output "security_group_id" { description = "ID of the worker nodes Security Group" - value = "${join("", aws_security_group.default.*.id)}" + value = join("", aws_security_group.default.*.id) } output "security_group_arn" { description = "ARN of the worker nodes Security Group" - value = "${join("", aws_security_group.default.*.arn)}" + value = join("", aws_security_group.default.*.arn) } output "security_group_name" { description = "Name of the worker nodes Security Group" - value = "${join("", aws_security_group.default.*.name)}" + value = join("", aws_security_group.default.*.name) } output "worker_role_arn" { description = "ARN of the worker nodes IAM role" - value = "${join("", aws_iam_role.default.*.arn)}" + value = join("", aws_iam_role.default.*.arn) } output "worker_role_name" { description = "Name of the worker nodes IAM role" - value = "${join("", aws_iam_role.default.*.name)}" + value = join("", aws_iam_role.default.*.name) } output "config_map_aws_auth" { description = "Kubernetes ConfigMap configuration for worker nodes to join the EKS cluster. https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes" - value = "${join("", data.template_file.config_map_aws_auth.*.rendered)}" + value = join("", data.template_file.config_map_aws_auth.*.rendered) } + diff --git a/variables.tf b/variables.tf index 4fe2d05..b5377f8 100644 --- a/variables.tf +++ b/variables.tf @@ -1,123 +1,125 @@ variable "namespace" { - type = "string" + type = string description = "Namespace, which could be your organization name, e.g. 'eg' or 'cp'" + default = "" } variable "stage" { - type = "string" + type = string description = "Stage, e.g. 'prod', 'staging', 'dev', or 'test'" + default = "" } variable "environment" { - type = "string" + type = string default = "" description = "Environment, e.g. 'testing', 'UAT'" } variable "name" { - type = "string" + type = string default = "app" description = "Solution name, e.g. 'app' or 'cluster'" } variable "delimiter" { - type = "string" + type = string default = "-" description = "Delimiter to be used between `namespace`, `stage`, `name` and `attributes`" } variable "attributes" { - type = "list" + type = list(string) default = [] description = "Additional attributes (e.g. `1`)" } variable "tags" { - type = "map" + type = map(string) default = {} description = "Additional tags (e.g. `{ BusinessUnit = \"XYZ\" }`" } variable "enabled" { - type = "string" + type = string description = "Whether to create the resources. Set to `false` to prevent the module from creating any resources" default = "true" } variable "cluster_name" { - type = "string" + type = string description = "The name of the EKS cluster" } variable "cluster_endpoint" { - type = "string" + type = string description = "EKS cluster endpoint" } variable "cluster_certificate_authority_data" { - type = "string" + type = string description = "The base64 encoded certificate data required to communicate with the cluster" } variable "cluster_security_group_id" { - type = "string" + type = string description = "Security Group ID of the EKS cluster" } variable "vpc_id" { - type = "string" + type = string description = "VPC ID for the EKS cluster" } variable "allowed_security_groups" { - type = "list" + type = list(string) default = [] description = "List of Security Group IDs to be allowed to connect to the worker nodes" } variable "allowed_cidr_blocks" { - type = "list" + type = list(string) default = [] description = "List of CIDR blocks to be allowed to connect to the worker nodes" } variable "instance_initiated_shutdown_behavior" { - type = "string" + type = string description = "Shutdown behavior for the instances. Can be `stop` or `terminate`" default = "terminate" } variable "image_id" { - type = "string" + type = string description = "EC2 image ID to launch. If not provided, the module will lookup the most recent EKS AMI. See https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html for more details on EKS-optimized images" default = "" } variable "use_custom_image_id" { - type = "string" + type = string description = "If set to `true`, will use variable `image_id` to run EKS workers inside autoscaling group" default = "false" } variable "eks_worker_ami_name_filter" { - type = "string" + type = string description = "AMI name filter to lookup the most recent EKS AMI if `image_id` is not provided" default = "amazon-eks-node-*" } variable "eks_worker_ami_name_regex" { - type = "string" + type = string description = "A regex string to apply to the AMI list returned by AWS" default = "^amazon-eks-node-[1-9,\\.]+-v\\d{8}$" } variable "instance_type" { - type = "string" + type = string description = "Instance type to launch" } variable "key_name" { - type = "string" + type = string description = "SSH key name that should be used for the instance" default = "" } @@ -139,31 +141,31 @@ variable "ebs_optimized" { variable "block_device_mappings" { description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" - type = "list" + type = list(string) default = [] } variable "instance_market_options" { description = "The market (purchasing) option for the instances" - type = "list" + type = list(string) default = [] } variable "placement" { description = "The placement specifications of the instances" - type = "list" + type = list(string) default = [] } variable "credit_specification" { description = "Customize the credit specification of the instances" - type = "list" + type = list(string) default = [] } variable "elastic_gpu_specifications" { description = "Specifications of Elastic GPU to attach to the instances" - type = "list" + type = list(string) default = [] } @@ -182,7 +184,7 @@ variable "min_size" { variable "subnet_ids" { description = "A list of subnet IDs to launch resources in" - type = "list" + type = list(string) } variable "default_cooldown" { @@ -196,7 +198,7 @@ variable "health_check_grace_period" { } variable "health_check_type" { - type = "string" + type = string description = "Controls how health checking is done. Valid values are `EC2` or `ELB`" default = "EC2" } @@ -207,44 +209,44 @@ variable "force_delete" { } variable "load_balancers" { - type = "list" + type = list(string) description = "A list of elastic load balancer names to add to the autoscaling group names. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead" default = [] } variable "target_group_arns" { - type = "list" + type = list(string) description = "A list of aws_alb_target_group ARNs, for use with Application Load Balancing" default = [] } variable "termination_policies" { description = "A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default`" - type = "list" + type = list(string) default = ["Default"] } variable "suspended_processes" { - type = "list" + type = list(string) description = "A list of processes to suspend for the AutoScaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your autoscaling group from functioning properly." default = [] } variable "placement_group" { - type = "string" + type = string description = "The name of the placement group into which you'll launch your instances, if any" default = "" } variable "metrics_granularity" { - type = "string" + type = string description = "The granularity to associate with the metrics to collect. The only valid value is 1Minute" default = "1Minute" } variable "enabled_metrics" { description = "A list of metrics to collect. The allowed values are `GroupMinSize`, `GroupMaxSize`, `GroupDesiredCapacity`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupTerminatingInstances`, `GroupTotalInstances`" - type = "list" + type = list(string) default = [ "GroupMinSize", @@ -259,7 +261,7 @@ variable "enabled_metrics" { } variable "wait_for_capacity_timeout" { - type = "string" + type = string description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. Setting this to '0' causes Terraform to skip all Capacity Waiting behavior" default = "10m" } @@ -280,19 +282,19 @@ variable "protect_from_scale_in" { } variable "service_linked_role_arn" { - type = "string" + type = string description = "The ARN of the service-linked role that the ASG will use to call other AWS services" default = "" } variable "autoscaling_policies_enabled" { - type = "string" + type = string default = "true" description = "Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling" } variable "scale_up_cooldown_seconds" { - type = "string" + type = string default = "300" description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" } @@ -303,19 +305,19 @@ variable "scale_up_scaling_adjustment" { } variable "scale_up_adjustment_type" { - type = "string" + type = string default = "ChangeInCapacity" description = "Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity`" } variable "scale_up_policy_type" { - type = "string" + type = string default = "SimpleScaling" description = "The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling`" } variable "scale_down_cooldown_seconds" { - type = "string" + type = string default = "300" description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" } @@ -326,109 +328,109 @@ variable "scale_down_scaling_adjustment" { } variable "scale_down_adjustment_type" { - type = "string" + type = string default = "ChangeInCapacity" description = "Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity`" } variable "scale_down_policy_type" { - type = "string" + type = string default = "SimpleScaling" description = "The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling`" } variable "cpu_utilization_high_evaluation_periods" { - type = "string" + type = string default = "2" description = "The number of periods over which data is compared to the specified threshold" } variable "cpu_utilization_high_period_seconds" { - type = "string" + type = string default = "300" description = "The period in seconds over which the specified statistic is applied" } variable "cpu_utilization_high_threshold_percent" { - type = "string" + type = string default = "90" description = "The value against which the specified statistic is compared" } variable "cpu_utilization_high_statistic" { - type = "string" + type = string default = "Average" description = "The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum`" } variable "cpu_utilization_low_evaluation_periods" { - type = "string" + type = string default = "2" description = "The number of periods over which data is compared to the specified threshold" } variable "cpu_utilization_low_period_seconds" { - type = "string" + type = string default = "300" description = "The period in seconds over which the specified statistic is applied" } variable "cpu_utilization_low_threshold_percent" { - type = "string" + type = string default = "10" description = "The value against which the specified statistic is compared" } variable "cpu_utilization_low_statistic" { - type = "string" + type = string default = "Average" description = "The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum`" } variable "bootstrap_extra_args" { - type = "string" + type = string default = "" description = "Passed to the bootstrap.sh script to enable --kublet-extra-args or --use-max-pods." } variable "aws_iam_instance_profile_name" { - type = "string" + type = string default = "" description = "The name of the existing instance profile that will be used in autoscaling group for EKS workers. If empty will create a new instance profile." } variable "workers_security_group_id" { - type = "string" + type = string default = "" description = "The name of the existing security group that will be used in autoscaling group for EKS workers. If empty, a new security group will be created" } variable "use_existing_security_group" { - type = "string" + type = string description = "If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed`" default = "false" } variable "additional_security_group_ids" { - type = "list" + type = list(string) default = [] description = "Additional list of security groups that will be attached to the autoscaling group" } variable "use_existing_aws_iam_instance_profile" { - type = "string" + type = string description = "If set to `true`, will use variable `aws_iam_instance_profile_name` to run EKS workers using an existing AWS instance profile that was created outside of this module, workaround for error like `count cannot be computed`" default = "false" } variable "workers_role_policy_arns" { - type = "list" + type = list(string) default = [] description = "List of policy ARNs that will be attached to the workers default role on creation" } variable "workers_role_policy_arns_count" { - type = "string" + type = string default = "0" description = "Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed`" } diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..d945c37 --- /dev/null +++ b/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + } +} From df308367c1eb35a5c1e4337de4ff8ec3fbb9a590 Mon Sep 17 00:00:00 2001 From: aknysh Date: Wed, 25 Sep 2019 17:24:40 -0400 Subject: [PATCH 02/10] Convert to TF 0.12 --- examples/complete/main.tf | 2 +- examples/complete/variables.tf | 279 ++++++++++++++++++++++++--------- main.tf | 42 ++--- outputs.tf | 1 - variables.tf | 176 ++++++++++++++------- 5 files changed, 345 insertions(+), 155 deletions(-) diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 5d9ab70..6433670 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -41,7 +41,7 @@ module "eks_workers" { stage = var.stage name = var.name attributes = var.attributes - tags = var.tags + tags = local.tags image_id = var.image_id eks_worker_ami_name_filter = var.eks_worker_ami_name_filter instance_type = var.instance_type diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index 0930dc9..f59c2c2 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -1,13 +1,24 @@ +variable "region" { + type = string + default = "us-west-2" + description = "AWS Region" +} + +variable "availability_zones" { + type = list(string) + description = "List of availability zones" +} + variable "namespace" { type = string - default = "eg" description = "Namespace, which could be your organization name, e.g. 'eg' or 'cp'" + default = "" } variable "stage" { type = string - default = "testing" description = "Stage, e.g. 'prod', 'staging', 'dev', or 'test'" + default = "" } variable "environment" { @@ -18,7 +29,7 @@ variable "environment" { variable "name" { type = string - default = "test" + default = "app" description = "Solution name, e.g. 'app' or 'cluster'" } @@ -41,20 +52,9 @@ variable "tags" { } variable "enabled" { - type = string + type = bool description = "Whether to create the resources. Set to `false` to prevent the module from creating any resources" - default = "true" -} - -variable "region" { - type = string - default = "us-west-2" - description = "AWS Region" -} - -variable "availability_zones" { - type = list(string) - description = "List of availability zones" + default = true } variable "cluster_name" { @@ -77,6 +77,23 @@ variable "cluster_security_group_id" { description = "Security Group ID of the EKS cluster" } +variable "vpc_id" { + type = string + description = "VPC ID for the EKS cluster" +} + +variable "allowed_security_groups" { + type = list(string) + default = [] + description = "List of Security Group IDs to be allowed to connect to the worker nodes" +} + +variable "allowed_cidr_blocks" { + type = list(string) + default = [] + description = "List of CIDR blocks to be allowed to connect to the worker nodes" +} + variable "instance_initiated_shutdown_behavior" { type = string description = "Shutdown behavior for the instances. Can be `stop` or `terminate`" @@ -89,90 +106,82 @@ variable "image_id" { default = "" } +variable "use_custom_image_id" { + type = bool + description = "If set to `true`, will use variable `image_id` for the EKS workers inside autoscaling group" + default = false +} + variable "eks_worker_ami_name_filter" { type = string description = "AMI name filter to lookup the most recent EKS AMI if `image_id` is not provided" - default = "amazon-eks-node-v*" + default = "amazon-eks-node-*" +} + +variable "eks_worker_ami_name_regex" { + type = string + description = "A regex string to apply to the AMI list returned by AWS" + default = "^amazon-eks-node-[1-9,\\.]+-v\\d{8}$" } variable "instance_type" { type = string - default = "t2.medium" description = "Instance type to launch" } variable "key_name" { type = string - description = "The SSH key name that should be used for the instance" + description = "SSH key name that should be used for the instance" default = "" } variable "associate_public_ip_address" { + type = bool description = "Associate a public IP address with an instance in a VPC" default = false } variable "enable_monitoring" { + type = bool description = "Enable/disable detailed monitoring" default = true } variable "ebs_optimized" { + type = bool description = "If true, the launched EC2 instance will be EBS-optimized" default = false } -variable "block_device_mappings" { - description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" - type = list(string) - default = [] -} - -variable "instance_market_options" { - description = "The market (purchasing) option for the instances" - type = list(string) - default = [] -} - -variable "placement" { - description = "The placement specifications of the instances" - type = list(string) - default = [] -} - -variable "credit_specification" { - description = "Customize the credit specification of the instances" - type = list(string) - default = [] -} - -variable "elastic_gpu_specifications" { - description = "Specifications of Elastic GPU to attach to the instances" - type = list(string) - default = [] -} - variable "disable_api_termination" { + type = bool description = "If `true`, enables EC2 Instance Termination Protection" default = false } variable "max_size" { - default = 3 + type = number description = "The maximum size of the autoscale group" } variable "min_size" { - default = 1 + type = number description = "The minimum size of the autoscale group" } +variable "subnet_ids" { + description = "A list of subnet IDs to launch resources in" + type = list(string) +} + variable "default_cooldown" { + type = number description = "The amount of time, in seconds, after a scaling activity completes before another scaling activity can start" default = 300 } variable "health_check_grace_period" { + type = number description = "Time (in seconds) after instance comes into service before checking health" default = 300 } @@ -184,13 +193,14 @@ variable "health_check_type" { } variable "force_delete" { + type = bool description = "Allows deleting the autoscaling group without waiting for all instances in the pool to terminate. You can force an autoscaling group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling" default = false } variable "load_balancers" { type = list(string) - description = "A list of elastic load balancer names to add to the autoscaling group names. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead" + description = "A list of elastic load balancer names to add to the autoscaling group. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead" default = [] } @@ -214,7 +224,7 @@ variable "suspended_processes" { variable "placement_group" { type = string - description = "The name of the placement group into which to launch the instances, if any" + description = "The name of the placement group into which you'll launch your instances, if any" default = "" } @@ -242,21 +252,24 @@ variable "enabled_metrics" { variable "wait_for_capacity_timeout" { type = string - description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. (See also Waiting for Capacity below.) Setting this to '0' causes Terraform to skip all Capacity Waiting behavior" + description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. Setting this to '0' causes Terraform to skip all Capacity Waiting behavior" default = "10m" } variable "min_elb_capacity" { + type = number description = "Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes" default = 0 } variable "wait_for_elb_capacity" { + type = bool description = "Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior" default = false } variable "protect_from_scale_in" { + type = bool description = "Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events" default = false } @@ -268,18 +281,19 @@ variable "service_linked_role_arn" { } variable "autoscaling_policies_enabled" { - type = string - default = "true" + type = bool + default = true description = "Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling" } variable "scale_up_cooldown_seconds" { - type = string - default = "300" + type = number + default = 300 description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" } variable "scale_up_scaling_adjustment" { + type = number default = 1 description = "The number of instances by which to scale. `scale_up_adjustment_type` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity" } @@ -297,12 +311,13 @@ variable "scale_up_policy_type" { } variable "scale_down_cooldown_seconds" { - type = string - default = "300" + type = number + default = 300 description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" } variable "scale_down_scaling_adjustment" { + type = number default = -1 description = "The number of instances by which to scale. `scale_down_scaling_adjustment` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity" } @@ -320,20 +335,20 @@ variable "scale_down_policy_type" { } variable "cpu_utilization_high_evaluation_periods" { - type = string - default = "2" + type = number + default = 2 description = "The number of periods over which data is compared to the specified threshold" } variable "cpu_utilization_high_period_seconds" { - type = string - default = "300" + type = number + default = 300 description = "The period in seconds over which the specified statistic is applied" } variable "cpu_utilization_high_threshold_percent" { - type = string - default = "90" + type = number + default = 90 description = "The value against which the specified statistic is compared" } @@ -344,20 +359,20 @@ variable "cpu_utilization_high_statistic" { } variable "cpu_utilization_low_evaluation_periods" { - type = string - default = "2" + type = number + default = 2 description = "The number of periods over which data is compared to the specified threshold" } variable "cpu_utilization_low_period_seconds" { - type = string - default = "300" + type = number + default = 300 description = "The period in seconds over which the specified statistic is applied" } variable "cpu_utilization_low_threshold_percent" { - type = string - default = "10" + type = number + default = 10 description = "The value against which the specified statistic is compared" } @@ -366,3 +381,123 @@ variable "cpu_utilization_low_statistic" { default = "Average" description = "The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum`" } + +variable "bootstrap_extra_args" { + type = string + default = "" + description = "Passed to the bootstrap.sh script to enable --kublet-extra-args or --use-max-pods." +} + +variable "aws_iam_instance_profile_name" { + type = string + default = "" + description = "The name of the existing instance profile that will be used in autoscaling group for EKS workers. If empty will create a new instance profile." +} + +variable "workers_security_group_id" { + type = string + default = "" + description = "The name of the existing security group that will be used in autoscaling group for EKS workers. If empty, a new security group will be created" +} + +variable "use_existing_security_group" { + type = bool + description = "If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed`" + default = false +} + +variable "additional_security_group_ids" { + type = list(string) + default = [] + description = "Additional list of security groups that will be attached to the autoscaling group" +} + +variable "use_existing_aws_iam_instance_profile" { + type = bool + description = "If set to `true`, will use variable `aws_iam_instance_profile_name` to run EKS workers using an existing AWS instance profile that was created outside of this module, workaround for error like `count cannot be computed`" + default = false +} + +variable "workers_role_policy_arns" { + type = list(string) + default = [] + description = "List of policy ARNs that will be attached to the workers default role on creation" +} + +variable "workers_role_policy_arns_count" { + type = number + default = 0 + description = "Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed`" +} + +variable "block_device_mappings" { + description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" + + type = list(object({ + device_name = string + no_device = bool + virtual_name = string + ebs = object({ + delete_on_termination = bool + encrypted = bool + iops = number + kms_key_id = string + snapshot_id = string + volume_size = number + volume_type = string + }) + })) + + default = [] +} + +variable "instance_market_options" { + description = "The market (purchasing) option for the instances" + + type = object({ + market_type = string + spot_options = object({ + block_duration_minutes = bool + instance_interruption_behavior = string + max_price = number + spot_instance_type = string + valid_until = string + }) + }) + + default = null +} + +variable "placement" { + description = "The placement specifications of the instances" + + type = object({ + affinity = string + availability_zone = string + group_name = string + host_id = string + tenancy = string + }) + + default = null +} + +variable "credit_specification" { + description = "Customize the credit specification of the instances" + + type = object({ + cpu_credits = string + }) + + default = null +} + +variable "elastic_gpu_specifications" { + description = "Specifications of Elastic GPU to attach to the instances" + + type = object({ + type = string + }) + + default = null +} diff --git a/main.tf b/main.tf index 3e58ea2..8729521 100644 --- a/main.tf +++ b/main.tf @@ -19,7 +19,7 @@ module "label" { } data "aws_iam_policy_document" "assume_role" { - count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 statement { effect = "Allow" @@ -33,43 +33,43 @@ data "aws_iam_policy_document" "assume_role" { } resource "aws_iam_role" "default" { - count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 name = module.label.id assume_role_policy = join("", data.aws_iam_policy_document.assume_role.*.json) } resource "aws_iam_role_policy_attachment" "amazon_eks_worker_node_policy" { - count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "amazon_eks_cni_policy" { - count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "amazon_ec2_container_registry_read_only" { - count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "existing_policies_attach_to_eks_workers_role" { - count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? var.workers_role_policy_arns_count : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile ? var.workers_role_policy_arns_count : 0 policy_arn = element(var.workers_role_policy_arns, count.index) role = join("", aws_iam_role.default.*.name) } resource "aws_iam_instance_profile" "default" { - count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "false" ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 name = module.label.id role = join("", aws_iam_role.default.*.name) } resource "aws_security_group" "default" { - count = var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0 + count = var.enabled && var.use_existing_security_group ? 1 : 0 name = module.label.id description = "Security Group for EKS worker nodes" vpc_id = var.vpc_id @@ -77,7 +77,7 @@ resource "aws_security_group" "default" { } resource "aws_security_group_rule" "egress" { - count = var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0 + count = var.enabled && var.use_existing_security_group ? 1 : 0 description = "Allow all egress traffic" from_port = 0 to_port = 0 @@ -88,7 +88,7 @@ resource "aws_security_group_rule" "egress" { } resource "aws_security_group_rule" "ingress_self" { - count = var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0 + count = var.enabled && var.use_existing_security_group ? 1 : 0 description = "Allow nodes to communicate with each other" from_port = 0 to_port = 65535 @@ -99,7 +99,7 @@ resource "aws_security_group_rule" "ingress_self" { } resource "aws_security_group_rule" "ingress_cluster" { - count = var.enabled == "true" && var.use_existing_security_group == "false" ? 1 : 0 + count = var.enabled && var.use_existing_security_group ? 1 : 0 description = "Allow worker kubelets and pods to receive communication from the cluster control plane" from_port = 0 to_port = 65535 @@ -110,7 +110,7 @@ resource "aws_security_group_rule" "ingress_cluster" { } resource "aws_security_group_rule" "ingress_security_groups" { - count = var.enabled == "true" && var.use_existing_security_group == "false" ? length(var.allowed_security_groups) : 0 + count = var.enabled && var.use_existing_security_group ? length(var.allowed_security_groups) : 0 description = "Allow inbound traffic from existing Security Groups" from_port = 0 to_port = 65535 @@ -121,7 +121,7 @@ resource "aws_security_group_rule" "ingress_security_groups" { } resource "aws_security_group_rule" "ingress_cidr_blocks" { - count = var.enabled == "true" && length(var.allowed_cidr_blocks) > 0 && var.use_existing_security_group == "false" ? 1 : 0 + count = var.enabled && length(var.allowed_cidr_blocks) > 0 && var.use_existing_security_group ? 1 : 0 description = "Allow inbound traffic from CIDR blocks" from_port = 0 to_port = 0 @@ -132,7 +132,7 @@ resource "aws_security_group_rule" "ingress_cidr_blocks" { } data "aws_ami" "eks_worker" { - count = var.enabled == "true" && var.use_custom_image_id == "false" ? 1 : 0 + count = var.enabled && var.use_custom_image_id ? 1 : 0 most_recent = true name_regex = var.eks_worker_ami_name_regex @@ -155,13 +155,13 @@ module "autoscale_group" { delimiter = var.delimiter attributes = var.attributes - image_id = var.use_custom_image_id == "true" ? var.image_id : join("", data.aws_ami.eks_worker.*.id) - iam_instance_profile_name = var.use_existing_aws_iam_instance_profile == "false" ? join("", aws_iam_instance_profile.default.*.name) : var.aws_iam_instance_profile_name + image_id = var.use_custom_image_id ? var.image_id : join("", data.aws_ami.eks_worker.*.id) + iam_instance_profile_name = var.use_existing_aws_iam_instance_profile ? join("", aws_iam_instance_profile.default.*.name) : var.aws_iam_instance_profile_name security_group_ids = [compact( concat( [ - var.use_existing_security_group == "false" ? join("", aws_security_group.default.*.id) : var.workers_security_group_id, + var.use_existing_security_group ? join("", aws_security_group.default.*.id) : var.workers_security_group_id, ], var.additional_security_group_ids ) @@ -221,7 +221,7 @@ module "autoscale_group" { } data "template_file" "userdata" { - count = var.enabled == "true" ? 1 : 0 + count = var.enabled ? 1 : 0 template = file("${path.module}/userdata.tpl") vars = { @@ -233,15 +233,15 @@ data "template_file" "userdata" { } data "aws_iam_instance_profile" "default" { - count = var.enabled == "true" && var.use_existing_aws_iam_instance_profile == "true" ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 name = var.aws_iam_instance_profile_name } data "template_file" "config_map_aws_auth" { - count = var.enabled == "true" ? 1 : 0 + count = var.enabled ? 1 : 0 template = file("${path.module}/config_map_aws_auth.tpl") vars = { - aws_iam_role_arn = var.use_existing_aws_iam_instance_profile == "true" ? join("", data.aws_iam_instance_profile.default.*.role_arn) : join("", aws_iam_role.default.*.arn) + aws_iam_role_arn = var.use_existing_aws_iam_instance_profile ? join("", data.aws_iam_instance_profile.default.*.role_arn) : join("", aws_iam_role.default.*.arn) } } diff --git a/outputs.tf b/outputs.tf index 794e987..d921d68 100644 --- a/outputs.tf +++ b/outputs.tf @@ -82,4 +82,3 @@ output "config_map_aws_auth" { description = "Kubernetes ConfigMap configuration for worker nodes to join the EKS cluster. https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes" value = join("", data.template_file.config_map_aws_auth.*.rendered) } - diff --git a/variables.tf b/variables.tf index b5377f8..a1013d0 100644 --- a/variables.tf +++ b/variables.tf @@ -41,9 +41,9 @@ variable "tags" { } variable "enabled" { - type = string + type = bool description = "Whether to create the resources. Set to `false` to prevent the module from creating any resources" - default = "true" + default = true } variable "cluster_name" { @@ -96,9 +96,9 @@ variable "image_id" { } variable "use_custom_image_id" { - type = string - description = "If set to `true`, will use variable `image_id` to run EKS workers inside autoscaling group" - default = "false" + type = bool + description = "If set to `true`, will use variable `image_id` for the EKS workers inside autoscaling group" + default = false } variable "eks_worker_ami_name_filter" { @@ -125,60 +125,36 @@ variable "key_name" { } variable "associate_public_ip_address" { + type = bool description = "Associate a public IP address with an instance in a VPC" default = false } variable "enable_monitoring" { + type = bool description = "Enable/disable detailed monitoring" default = true } variable "ebs_optimized" { + type = bool description = "If true, the launched EC2 instance will be EBS-optimized" default = false } -variable "block_device_mappings" { - description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" - type = list(string) - default = [] -} - -variable "instance_market_options" { - description = "The market (purchasing) option for the instances" - type = list(string) - default = [] -} - -variable "placement" { - description = "The placement specifications of the instances" - type = list(string) - default = [] -} - -variable "credit_specification" { - description = "Customize the credit specification of the instances" - type = list(string) - default = [] -} - -variable "elastic_gpu_specifications" { - description = "Specifications of Elastic GPU to attach to the instances" - type = list(string) - default = [] -} - variable "disable_api_termination" { + type = bool description = "If `true`, enables EC2 Instance Termination Protection" default = false } variable "max_size" { + type = number description = "The maximum size of the autoscale group" } variable "min_size" { + type = number description = "The minimum size of the autoscale group" } @@ -188,11 +164,13 @@ variable "subnet_ids" { } variable "default_cooldown" { + type = number description = "The amount of time, in seconds, after a scaling activity completes before another scaling activity can start" default = 300 } variable "health_check_grace_period" { + type = number description = "Time (in seconds) after instance comes into service before checking health" default = 300 } @@ -204,13 +182,14 @@ variable "health_check_type" { } variable "force_delete" { + type = bool description = "Allows deleting the autoscaling group without waiting for all instances in the pool to terminate. You can force an autoscaling group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling" default = false } variable "load_balancers" { type = list(string) - description = "A list of elastic load balancer names to add to the autoscaling group names. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead" + description = "A list of elastic load balancer names to add to the autoscaling group. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead" default = [] } @@ -267,16 +246,19 @@ variable "wait_for_capacity_timeout" { } variable "min_elb_capacity" { + type = number description = "Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes" default = 0 } variable "wait_for_elb_capacity" { + type = bool description = "Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior" default = false } variable "protect_from_scale_in" { + type = bool description = "Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events" default = false } @@ -288,18 +270,19 @@ variable "service_linked_role_arn" { } variable "autoscaling_policies_enabled" { - type = string - default = "true" + type = bool + default = true description = "Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling" } variable "scale_up_cooldown_seconds" { - type = string - default = "300" + type = number + default = 300 description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" } variable "scale_up_scaling_adjustment" { + type = number default = 1 description = "The number of instances by which to scale. `scale_up_adjustment_type` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity" } @@ -317,12 +300,13 @@ variable "scale_up_policy_type" { } variable "scale_down_cooldown_seconds" { - type = string - default = "300" + type = number + default = 300 description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" } variable "scale_down_scaling_adjustment" { + type = number default = -1 description = "The number of instances by which to scale. `scale_down_scaling_adjustment` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity" } @@ -340,20 +324,20 @@ variable "scale_down_policy_type" { } variable "cpu_utilization_high_evaluation_periods" { - type = string - default = "2" + type = number + default = 2 description = "The number of periods over which data is compared to the specified threshold" } variable "cpu_utilization_high_period_seconds" { - type = string - default = "300" + type = number + default = 300 description = "The period in seconds over which the specified statistic is applied" } variable "cpu_utilization_high_threshold_percent" { - type = string - default = "90" + type = number + default = 90 description = "The value against which the specified statistic is compared" } @@ -364,20 +348,20 @@ variable "cpu_utilization_high_statistic" { } variable "cpu_utilization_low_evaluation_periods" { - type = string - default = "2" + type = number + default = 2 description = "The number of periods over which data is compared to the specified threshold" } variable "cpu_utilization_low_period_seconds" { - type = string - default = "300" + type = number + default = 300 description = "The period in seconds over which the specified statistic is applied" } variable "cpu_utilization_low_threshold_percent" { - type = string - default = "10" + type = number + default = 10 description = "The value against which the specified statistic is compared" } @@ -406,9 +390,9 @@ variable "workers_security_group_id" { } variable "use_existing_security_group" { - type = string + type = bool description = "If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed`" - default = "false" + default = false } variable "additional_security_group_ids" { @@ -418,9 +402,9 @@ variable "additional_security_group_ids" { } variable "use_existing_aws_iam_instance_profile" { - type = string + type = bool description = "If set to `true`, will use variable `aws_iam_instance_profile_name` to run EKS workers using an existing AWS instance profile that was created outside of this module, workaround for error like `count cannot be computed`" - default = "false" + default = false } variable "workers_role_policy_arns" { @@ -430,7 +414,79 @@ variable "workers_role_policy_arns" { } variable "workers_role_policy_arns_count" { - type = string - default = "0" + type = number + default = 0 description = "Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed`" } + +variable "block_device_mappings" { + description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" + + type = list(object({ + device_name = string + no_device = bool + virtual_name = string + ebs = object({ + delete_on_termination = bool + encrypted = bool + iops = number + kms_key_id = string + snapshot_id = string + volume_size = number + volume_type = string + }) + })) + + default = [] +} + +variable "instance_market_options" { + description = "The market (purchasing) option for the instances" + + type = object({ + market_type = string + spot_options = object({ + block_duration_minutes = bool + instance_interruption_behavior = string + max_price = number + spot_instance_type = string + valid_until = string + }) + }) + + default = null +} + +variable "placement" { + description = "The placement specifications of the instances" + + type = object({ + affinity = string + availability_zone = string + group_name = string + host_id = string + tenancy = string + }) + + default = null +} + +variable "credit_specification" { + description = "Customize the credit specification of the instances" + + type = object({ + cpu_credits = string + }) + + default = null +} + +variable "elastic_gpu_specifications" { + description = "Specifications of Elastic GPU to attach to the instances" + + type = object({ + type = string + }) + + default = null +} From 1e711214751f1199fdbb638e7553c7259cc72c90 Mon Sep 17 00:00:00 2001 From: aknysh Date: Wed, 25 Sep 2019 21:20:17 -0400 Subject: [PATCH 03/10] Add tests. Add Codefresh test pipeline --- README.md | 229 ++++++----- README.yaml | 129 +++--- codefresh/test.yml | 74 ++++ docs/terraform.md | 95 +++-- examples/complete/fixtures.us-east-2.tfvars | 31 ++ examples/complete/main.tf | 17 +- examples/complete/outputs.tf | 26 +- examples/complete/variables.tf | 412 -------------------- main.tf | 58 +-- test/.gitignore | 1 + test/Makefile | 43 ++ test/Makefile.alpine | 5 + test/src/.gitignore | 2 + test/src/Gopkg.lock | 92 +++++ test/src/Gopkg.toml | 7 + test/src/Makefile | 50 +++ test/src/examples_complete_test.go | 52 +++ variables.tf | 6 - 18 files changed, 634 insertions(+), 695 deletions(-) create mode 100644 codefresh/test.yml create mode 100644 examples/complete/fixtures.us-east-2.tfvars create mode 100644 test/.gitignore create mode 100644 test/Makefile create mode 100644 test/Makefile.alpine create mode 100644 test/src/.gitignore create mode 100644 test/src/Gopkg.lock create mode 100644 test/src/Gopkg.toml create mode 100644 test/src/Makefile create mode 100644 test/src/examples_complete_test.go diff --git a/README.md b/README.md index e59eea2..c35bb63 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Cloud Posse][logo]](https://cpco.io/homepage) -# terraform-aws-eks-workers [![Build Status](https://travis-ci.org/cloudposse/terraform-aws-eks-workers.svg?branch=master)](https://travis-ci.org/cloudposse/terraform-aws-eks-workers) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-eks-workers.svg)](https://github.com/cloudposse/terraform-aws-eks-workers/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) +# terraform-aws-eks-workers [![Codefresh Build Status](https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-eks-workers?type=cf-1)](https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d8c0fe0c9daf686b5858180) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-eks-workers.svg)](https://github.com/cloudposse/terraform-aws-eks-workers/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) Terraform module to provision AWS resources to run EC2 worker nodes for [Elastic Container Service for Kubernetes](https://aws.amazon.com/eks/). @@ -54,74 +54,70 @@ If you don't want to use the provided functionality, or want to provide your own ## Usage +**IMPORTANT:** The `master` branch is used in `source` just as an example. In your code, do not pin to `master` because there may be breaking changes between releases. +Instead pin to the release tag (e.g. `?ref=tags/x.y.z`) of one of our [latest releases](https://github.com/cloudposse/terraform-aws-eks-workers/releases). + + + For a complete example, see [examples/complete](examples/complete) ```hcl -provider "aws" { - region = "${var.region}" -} - -locals { - # The usage of the specific kubernetes.io/cluster/* resource tags below are required - # for EKS and Kubernetes to discover and manage networking resources - # https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#base-vpc-networking - tags = "${merge(var.tags, map("kubernetes.io/cluster/${var.cluster_name}", "shared"))}" -} - -data "aws_availability_zones" "available" {} - -module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=master" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${local.tags}" - cidr_block = "10.0.0.0/16" -} - -module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=master" - availability_zones = ["${data.aws_availability_zones.available.names}"] - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${local.tags}" - region = "${var.region}" - vpc_id = "${module.vpc.vpc_id}" - igw_id = "${module.vpc.igw_id}" - cidr_block = "${module.vpc.vpc_cidr_block}" - nat_gateway_enabled = "true" -} - -module "eks_workers" { - source = "git::https://github.com/cloudposse/terraform-aws-eks-workers.git?ref=master" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${var.tags}" - image_id = "${var.image_id}" - eks_worker_ami_name_filter = "${var.eks_worker_ami_name_filter}" - instance_type = "${var.instance_type}" - vpc_id = "${module.vpc.vpc_id}" - subnet_ids = ["${module.subnets.public_subnet_ids}"] - health_check_type = "${var.health_check_type}" - min_size = "${var.min_size}" - max_size = "${var.max_size}" - wait_for_capacity_timeout = "${var.wait_for_capacity_timeout}" - associate_public_ip_address = "${var.associate_public_ip_address}" - cluster_name = "${var.cluster_name}" - cluster_endpoint = "${var.cluster_endpoint}" - cluster_certificate_authority_data = "${var.cluster_certificate_authority_data}" - cluster_security_group_id = "${var.cluster_security_group_id}" - - # Auto-scaling policies and CloudWatch metric alarms - autoscaling_policies_enabled = "${var.autoscaling_policies_enabled}" - cpu_utilization_high_threshold_percent = "${var.cpu_utilization_high_threshold_percent}" - cpu_utilization_low_threshold_percent = "${var.cpu_utilization_low_threshold_percent}" -} + provider "aws" { + region = var.region + } + + locals { + # The usage of the specific kubernetes.io/cluster/* resource tags below are required + # for EKS and Kubernetes to discover and manage networking resources + # https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#base-vpc-networking + tags = merge(var.tags, map("kubernetes.io/cluster/${var.cluster_name}", "shared")) + } + + module "vpc" { + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.0" + namespace = var.namespace + stage = var.stage + name = var.name + cidr_block = "172.16.0.0/16" + tags = local.tags + } + + module "subnets" { + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.0" + availability_zones = var.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = false + nat_instance_enabled = false + tags = local.tags + } + + module "eks_workers" { + source = "git::https://github.com/cloudposse/terraform-aws-eks-workers.git?ref=master" + namespace = var.namespace + stage = var.stage + name = var.name + instance_type = var.instance_type + vpc_id = module.vpc.vpc_id + subnet_ids = module.subnets.public_subnet_ids + health_check_type = var.health_check_type + min_size = var.min_size + max_size = var.max_size + wait_for_capacity_timeout = var.wait_for_capacity_timeout + cluster_name = var.cluster_name + cluster_endpoint = var.cluster_endpoint + cluster_certificate_authority_data = var.cluster_certificate_authority_data + cluster_security_group_id = var.cluster_security_group_id + + # Auto-scaling policies and CloudWatch metric alarms + autoscaling_policies_enabled = var.autoscaling_policies_enabled + cpu_utilization_high_threshold_percent = var.cpu_utilization_high_threshold_percent + cpu_utilization_low_threshold_percent = var.cpu_utilization_low_threshold_percent + } ``` @@ -143,80 +139,79 @@ Available targets: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| additional_security_group_ids | Additional list of security groups that will be attached to the autoscaling group | list | `` | no | -| allowed_cidr_blocks | List of CIDR blocks to be allowed to connect to the worker nodes | list | `` | no | -| allowed_security_groups | List of Security Group IDs to be allowed to connect to the worker nodes | list | `` | no | -| associate_public_ip_address | Associate a public IP address with an instance in a VPC | string | `false` | no | -| attributes | Additional attributes (e.g. `1`) | list | `` | no | -| autoscaling_policies_enabled | Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling | string | `true` | no | +| additional_security_group_ids | Additional list of security groups that will be attached to the autoscaling group | list(string) | `` | no | +| allowed_cidr_blocks | List of CIDR blocks to be allowed to connect to the worker nodes | list(string) | `` | no | +| allowed_security_groups | List of Security Group IDs to be allowed to connect to the worker nodes | list(string) | `` | no | +| associate_public_ip_address | Associate a public IP address with an instance in a VPC | bool | `false` | no | +| attributes | Additional attributes (e.g. `1`) | list(string) | `` | no | +| autoscaling_policies_enabled | Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling | bool | `true` | no | | aws_iam_instance_profile_name | The name of the existing instance profile that will be used in autoscaling group for EKS workers. If empty will create a new instance profile. | string | `` | no | -| block_device_mappings | Specify volumes to attach to the instance besides the volumes specified by the AMI | list | `` | no | +| block_device_mappings | Specify volumes to attach to the instance besides the volumes specified by the AMI | object | `` | no | | bootstrap_extra_args | Passed to the bootstrap.sh script to enable --kublet-extra-args or --use-max-pods. | string | `` | no | | cluster_certificate_authority_data | The base64 encoded certificate data required to communicate with the cluster | string | - | yes | | cluster_endpoint | EKS cluster endpoint | string | - | yes | | cluster_name | The name of the EKS cluster | string | - | yes | | cluster_security_group_id | Security Group ID of the EKS cluster | string | - | yes | -| cpu_utilization_high_evaluation_periods | The number of periods over which data is compared to the specified threshold | string | `2` | no | -| cpu_utilization_high_period_seconds | The period in seconds over which the specified statistic is applied | string | `300` | no | +| cpu_utilization_high_evaluation_periods | The number of periods over which data is compared to the specified threshold | number | `2` | no | +| cpu_utilization_high_period_seconds | The period in seconds over which the specified statistic is applied | number | `300` | no | | cpu_utilization_high_statistic | The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum` | string | `Average` | no | -| cpu_utilization_high_threshold_percent | The value against which the specified statistic is compared | string | `90` | no | -| cpu_utilization_low_evaluation_periods | The number of periods over which data is compared to the specified threshold | string | `2` | no | -| cpu_utilization_low_period_seconds | The period in seconds over which the specified statistic is applied | string | `300` | no | +| cpu_utilization_high_threshold_percent | The value against which the specified statistic is compared | number | `90` | no | +| cpu_utilization_low_evaluation_periods | The number of periods over which data is compared to the specified threshold | number | `2` | no | +| cpu_utilization_low_period_seconds | The period in seconds over which the specified statistic is applied | number | `300` | no | | cpu_utilization_low_statistic | The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum` | string | `Average` | no | -| cpu_utilization_low_threshold_percent | The value against which the specified statistic is compared | string | `10` | no | -| credit_specification | Customize the credit specification of the instances | list | `` | no | -| default_cooldown | The amount of time, in seconds, after a scaling activity completes before another scaling activity can start | string | `300` | no | +| cpu_utilization_low_threshold_percent | The value against which the specified statistic is compared | number | `10` | no | +| credit_specification | Customize the credit specification of the instances | object | `null` | no | +| default_cooldown | The amount of time, in seconds, after a scaling activity completes before another scaling activity can start | number | `300` | no | | delimiter | Delimiter to be used between `namespace`, `stage`, `name` and `attributes` | string | `-` | no | -| disable_api_termination | If `true`, enables EC2 Instance Termination Protection | string | `false` | no | -| ebs_optimized | If true, the launched EC2 instance will be EBS-optimized | string | `false` | no | +| disable_api_termination | If `true`, enables EC2 Instance Termination Protection | bool | `false` | no | +| ebs_optimized | If true, the launched EC2 instance will be EBS-optimized | bool | `false` | no | | eks_worker_ami_name_filter | AMI name filter to lookup the most recent EKS AMI if `image_id` is not provided | string | `amazon-eks-node-*` | no | | eks_worker_ami_name_regex | A regex string to apply to the AMI list returned by AWS | string | `^amazon-eks-node-[1-9,\.]+-v\d{8}$` | no | -| elastic_gpu_specifications | Specifications of Elastic GPU to attach to the instances | list | `` | no | -| enable_monitoring | Enable/disable detailed monitoring | string | `true` | no | -| enabled | Whether to create the resources. Set to `false` to prevent the module from creating any resources | string | `true` | no | -| enabled_metrics | A list of metrics to collect. The allowed values are `GroupMinSize`, `GroupMaxSize`, `GroupDesiredCapacity`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupTerminatingInstances`, `GroupTotalInstances` | list | `` | no | -| environment | Environment, e.g. 'testing', 'UAT' | string | `` | no | -| force_delete | Allows deleting the autoscaling group without waiting for all instances in the pool to terminate. You can force an autoscaling group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling | string | `false` | no | -| health_check_grace_period | Time (in seconds) after instance comes into service before checking health | string | `300` | no | +| elastic_gpu_specifications | Specifications of Elastic GPU to attach to the instances | object | `null` | no | +| enable_monitoring | Enable/disable detailed monitoring | bool | `true` | no | +| enabled | Whether to create the resources. Set to `false` to prevent the module from creating any resources | bool | `true` | no | +| enabled_metrics | A list of metrics to collect. The allowed values are `GroupMinSize`, `GroupMaxSize`, `GroupDesiredCapacity`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupTerminatingInstances`, `GroupTotalInstances` | list(string) | `` | no | +| force_delete | Allows deleting the autoscaling group without waiting for all instances in the pool to terminate. You can force an autoscaling group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling | bool | `false` | no | +| health_check_grace_period | Time (in seconds) after instance comes into service before checking health | number | `300` | no | | health_check_type | Controls how health checking is done. Valid values are `EC2` or `ELB` | string | `EC2` | no | | image_id | EC2 image ID to launch. If not provided, the module will lookup the most recent EKS AMI. See https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html for more details on EKS-optimized images | string | `` | no | | instance_initiated_shutdown_behavior | Shutdown behavior for the instances. Can be `stop` or `terminate` | string | `terminate` | no | -| instance_market_options | The market (purchasing) option for the instances | list | `` | no | +| instance_market_options | The market (purchasing) option for the instances | object | `null` | no | | instance_type | Instance type to launch | string | - | yes | | key_name | SSH key name that should be used for the instance | string | `` | no | -| load_balancers | A list of elastic load balancer names to add to the autoscaling group names. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead | list | `` | no | -| max_size | The maximum size of the autoscale group | string | - | yes | +| load_balancers | A list of elastic load balancer names to add to the autoscaling group. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead | list(string) | `` | no | +| max_size | The maximum size of the autoscale group | number | - | yes | | metrics_granularity | The granularity to associate with the metrics to collect. The only valid value is 1Minute | string | `1Minute` | no | -| min_elb_capacity | Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes | string | `0` | no | -| min_size | The minimum size of the autoscale group | string | - | yes | +| min_elb_capacity | Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes | number | `0` | no | +| min_size | The minimum size of the autoscale group | number | - | yes | | name | Solution name, e.g. 'app' or 'cluster' | string | `app` | no | -| namespace | Namespace, which could be your organization name, e.g. 'eg' or 'cp' | string | - | yes | -| placement | The placement specifications of the instances | list | `` | no | +| namespace | Namespace, which could be your organization name, e.g. 'eg' or 'cp' | string | `` | no | +| placement | The placement specifications of the instances | object | `null` | no | | placement_group | The name of the placement group into which you'll launch your instances, if any | string | `` | no | -| protect_from_scale_in | Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events | string | `false` | no | +| protect_from_scale_in | Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events | bool | `false` | no | | scale_down_adjustment_type | Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity` | string | `ChangeInCapacity` | no | -| scale_down_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | string | `300` | no | +| scale_down_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | number | `300` | no | | scale_down_policy_type | The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling` | string | `SimpleScaling` | no | -| scale_down_scaling_adjustment | The number of instances by which to scale. `scale_down_scaling_adjustment` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | string | `-1` | no | +| scale_down_scaling_adjustment | The number of instances by which to scale. `scale_down_scaling_adjustment` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | number | `-1` | no | | scale_up_adjustment_type | Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity` | string | `ChangeInCapacity` | no | -| scale_up_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | string | `300` | no | +| scale_up_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | number | `300` | no | | scale_up_policy_type | The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling` | string | `SimpleScaling` | no | -| scale_up_scaling_adjustment | The number of instances by which to scale. `scale_up_adjustment_type` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | string | `1` | no | +| scale_up_scaling_adjustment | The number of instances by which to scale. `scale_up_adjustment_type` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | number | `1` | no | | service_linked_role_arn | The ARN of the service-linked role that the ASG will use to call other AWS services | string | `` | no | -| stage | Stage, e.g. 'prod', 'staging', 'dev', or 'test' | string | - | yes | -| subnet_ids | A list of subnet IDs to launch resources in | list | - | yes | -| suspended_processes | A list of processes to suspend for the AutoScaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your autoscaling group from functioning properly. | list | `` | no | -| tags | Additional tags (e.g. `{ BusinessUnit = "XYZ" }` | map | `` | no | -| target_group_arns | A list of aws_alb_target_group ARNs, for use with Application Load Balancing | list | `` | no | -| termination_policies | A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default` | list | `` | no | -| use_custom_image_id | If set to `true`, will use variable `image_id` to run EKS workers inside autoscaling group | string | `false` | no | -| use_existing_aws_iam_instance_profile | If set to `true`, will use variable `aws_iam_instance_profile_name` to run EKS workers using an existing AWS instance profile that was created outside of this module, workaround for error like `count cannot be computed` | string | `false` | no | -| use_existing_security_group | If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed` | string | `false` | no | +| stage | Stage, e.g. 'prod', 'staging', 'dev', or 'test' | string | `` | no | +| subnet_ids | A list of subnet IDs to launch resources in | list(string) | - | yes | +| suspended_processes | A list of processes to suspend for the AutoScaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your autoscaling group from functioning properly. | list(string) | `` | no | +| tags | Additional tags (e.g. `{ BusinessUnit = "XYZ" }` | map(string) | `` | no | +| target_group_arns | A list of aws_alb_target_group ARNs, for use with Application Load Balancing | list(string) | `` | no | +| termination_policies | A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default` | list(string) | `` | no | +| use_custom_image_id | If set to `true`, will use variable `image_id` for the EKS workers inside autoscaling group | bool | `false` | no | +| use_existing_aws_iam_instance_profile | If set to `true`, will use variable `aws_iam_instance_profile_name` to run EKS workers using an existing AWS instance profile that was created outside of this module, workaround for error like `count cannot be computed` | bool | `false` | no | +| use_existing_security_group | If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed` | bool | `false` | no | | vpc_id | VPC ID for the EKS cluster | string | - | yes | | wait_for_capacity_timeout | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. Setting this to '0' causes Terraform to skip all Capacity Waiting behavior | string | `10m` | no | -| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | string | `false` | no | -| workers_role_policy_arns | List of policy ARNs that will be attached to the workers default role on creation | list | `` | no | -| workers_role_policy_arns_count | Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed` | string | `0` | no | +| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | bool | `false` | no | +| workers_role_policy_arns | List of policy ARNs that will be attached to the workers default role on creation | list(string) | `` | no | +| workers_role_policy_arns_count | Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed` | number | `0` | no | | workers_security_group_id | The name of the existing security group that will be used in autoscaling group for EKS workers. If empty, a new security group will be created | string | `` | no | ## Outputs @@ -388,11 +383,11 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply |---|---|---| [osterman_homepage]: https://github.com/osterman - [osterman_avatar]: https://github.com/osterman.png?size=150 + [osterman_avatar]: https://img.cloudposse.com/150x150/https://github.com/osterman.png [aknysh_homepage]: https://github.com/aknysh - [aknysh_avatar]: https://github.com/aknysh.png?size=150 + [aknysh_avatar]: https://img.cloudposse.com/150x150/https://github.com/aknysh.png [goruha_homepage]: https://github.com/goruha - [goruha_avatar]: https://github.com/goruha.png?size=150 + [goruha_avatar]: https://img.cloudposse.com/150x150/https://github.com/goruha.png diff --git a/README.yaml b/README.yaml index aa99b77..b434d65 100644 --- a/README.yaml +++ b/README.yaml @@ -18,9 +18,9 @@ github_repo: cloudposse/terraform-aws-eks-workers # Badges to display badges: - - name: "Build Status" - image: "https://travis-ci.org/cloudposse/terraform-aws-eks-workers.svg?branch=master" - url: "https://travis-ci.org/cloudposse/terraform-aws-eks-workers" + - name: "Codefresh Build Status" + image: "https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-eks-workers?type=cf-1" + url: "https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d8c0fe0c9daf686b5858180" - name: "Latest Release" image: "https://img.shields.io/github/release/cloudposse/terraform-aws-eks-workers.svg" url: "https://github.com/cloudposse/terraform-aws-eks-workers/releases/latest" @@ -38,7 +38,7 @@ related: - name: "terraform-aws-ecs-alb-service-task" description: "Terraform module which implements an ECS service which exposes a web service via ALB" url: "https://github.com/cloudposse/terraform-aws-ecs-alb-service-task" - - name: "erraform-aws-ecs-web-app" + - name: "terraform-aws-ecs-web-app" description: "Terraform module that implements a web app on ECS and supports autoscaling, CI/CD, monitoring, ALB integration, and much more" url: "https://github.com/cloudposse/terraform-aws-ecs-web-app" - name: "terraform-aws-ecs-codepipeline" @@ -78,71 +78,62 @@ usage: |- For a complete example, see [examples/complete](examples/complete) ```hcl - provider "aws" { - region = "${var.region}" - } - - locals { - # The usage of the specific kubernetes.io/cluster/* resource tags below are required - # for EKS and Kubernetes to discover and manage networking resources - # https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#base-vpc-networking - tags = "${merge(var.tags, map("kubernetes.io/cluster/${var.cluster_name}", "shared"))}" - } - - data "aws_availability_zones" "available" {} - - module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=master" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${local.tags}" - cidr_block = "10.0.0.0/16" - } - - module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=master" - availability_zones = ["${data.aws_availability_zones.available.names}"] - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${local.tags}" - region = "${var.region}" - vpc_id = "${module.vpc.vpc_id}" - igw_id = "${module.vpc.igw_id}" - cidr_block = "${module.vpc.vpc_cidr_block}" - nat_gateway_enabled = "true" - } - - module "eks_workers" { - source = "git::https://github.com/cloudposse/terraform-aws-eks-workers.git?ref=master" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = "${var.attributes}" - tags = "${var.tags}" - image_id = "${var.image_id}" - eks_worker_ami_name_filter = "${var.eks_worker_ami_name_filter}" - instance_type = "${var.instance_type}" - vpc_id = "${module.vpc.vpc_id}" - subnet_ids = ["${module.subnets.public_subnet_ids}"] - health_check_type = "${var.health_check_type}" - min_size = "${var.min_size}" - max_size = "${var.max_size}" - wait_for_capacity_timeout = "${var.wait_for_capacity_timeout}" - associate_public_ip_address = "${var.associate_public_ip_address}" - cluster_name = "${var.cluster_name}" - cluster_endpoint = "${var.cluster_endpoint}" - cluster_certificate_authority_data = "${var.cluster_certificate_authority_data}" - cluster_security_group_id = "${var.cluster_security_group_id}" - - # Auto-scaling policies and CloudWatch metric alarms - autoscaling_policies_enabled = "${var.autoscaling_policies_enabled}" - cpu_utilization_high_threshold_percent = "${var.cpu_utilization_high_threshold_percent}" - cpu_utilization_low_threshold_percent = "${var.cpu_utilization_low_threshold_percent}" - } + provider "aws" { + region = var.region + } + + locals { + # The usage of the specific kubernetes.io/cluster/* resource tags below are required + # for EKS and Kubernetes to discover and manage networking resources + # https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#base-vpc-networking + tags = merge(var.tags, map("kubernetes.io/cluster/${var.cluster_name}", "shared")) + } + + module "vpc" { + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.0" + namespace = var.namespace + stage = var.stage + name = var.name + cidr_block = "172.16.0.0/16" + tags = local.tags + } + + module "subnets" { + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.0" + availability_zones = var.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = false + nat_instance_enabled = false + tags = local.tags + } + + module "eks_workers" { + source = "git::https://github.com/cloudposse/terraform-aws-eks-workers.git?ref=master" + namespace = var.namespace + stage = var.stage + name = var.name + instance_type = var.instance_type + vpc_id = module.vpc.vpc_id + subnet_ids = module.subnets.public_subnet_ids + health_check_type = var.health_check_type + min_size = var.min_size + max_size = var.max_size + wait_for_capacity_timeout = var.wait_for_capacity_timeout + cluster_name = var.cluster_name + cluster_endpoint = var.cluster_endpoint + cluster_certificate_authority_data = var.cluster_certificate_authority_data + cluster_security_group_id = var.cluster_security_group_id + + # Auto-scaling policies and CloudWatch metric alarms + autoscaling_policies_enabled = var.autoscaling_policies_enabled + cpu_utilization_high_threshold_percent = var.cpu_utilization_high_threshold_percent + cpu_utilization_low_threshold_percent = var.cpu_utilization_low_threshold_percent + } ``` include: diff --git a/codefresh/test.yml b/codefresh/test.yml new file mode 100644 index 0000000..ddd07f9 --- /dev/null +++ b/codefresh/test.yml @@ -0,0 +1,74 @@ +version: '1.0' + +stages: + - Prepare + - Test + +steps: + wait: + title: Wait + stage: Prepare + image: codefresh/cli:latest + commands: + - codefresh get builds --pipeline=${{CF_REPO_NAME}} --status running --limit 1000 -o json | jq --arg id ${{CF_BUILD_ID}} -ser 'flatten|.[-1].id==$id' + retry: + maxAttempts: 10 + delay: 20 + exponentialFactor: 1.1 + + main_clone: + title: "Clone repository" + type: git-clone + stage: Prepare + description: "Initialize" + repo: ${{CF_REPO_OWNER}}/${{CF_REPO_NAME}} + git: CF-default + revision: ${{CF_REVISION}} + + clean_init: + title: Prepare build-harness and test-harness + image: ${{TEST_IMAGE}} + stage: Prepare + commands: + - cf_export PATH="/usr/local/terraform/0.12/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + - make init + - git -C build-harness checkout master + - make -C test/ clean init TEST_HARNESS_BRANCH=master + - make -C test/src clean init + - find . -type d -name '.terraform' | xargs rm -rf + - find . -type f -name 'terraform.tfstate*' -exec rm -f {} \; + + test: + type: "parallel" + title: "Run tests" + description: "Run all tests in parallel" + stage: Test + steps: + test_readme_lint: + title: "Test README.md updated" + stage: "Test" + image: ${{TEST_IMAGE}} + description: Test "readme/lint" + commands: + - make readme/lint + + test_module: + title: Test module with bats + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/ module + + test_examples_complete: + title: Test "examples/complete" with bats + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/ examples/complete + + test_examples_complete_terratest: + title: Test "examples/complete" with terratest + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/src diff --git a/docs/terraform.md b/docs/terraform.md index 7a044fc..01e8d64 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -2,80 +2,79 @@ | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| additional_security_group_ids | Additional list of security groups that will be attached to the autoscaling group | list | `` | no | -| allowed_cidr_blocks | List of CIDR blocks to be allowed to connect to the worker nodes | list | `` | no | -| allowed_security_groups | List of Security Group IDs to be allowed to connect to the worker nodes | list | `` | no | -| associate_public_ip_address | Associate a public IP address with an instance in a VPC | string | `false` | no | -| attributes | Additional attributes (e.g. `1`) | list | `` | no | -| autoscaling_policies_enabled | Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling | string | `true` | no | +| additional_security_group_ids | Additional list of security groups that will be attached to the autoscaling group | list(string) | `` | no | +| allowed_cidr_blocks | List of CIDR blocks to be allowed to connect to the worker nodes | list(string) | `` | no | +| allowed_security_groups | List of Security Group IDs to be allowed to connect to the worker nodes | list(string) | `` | no | +| associate_public_ip_address | Associate a public IP address with an instance in a VPC | bool | `false` | no | +| attributes | Additional attributes (e.g. `1`) | list(string) | `` | no | +| autoscaling_policies_enabled | Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling | bool | `true` | no | | aws_iam_instance_profile_name | The name of the existing instance profile that will be used in autoscaling group for EKS workers. If empty will create a new instance profile. | string | `` | no | -| block_device_mappings | Specify volumes to attach to the instance besides the volumes specified by the AMI | list | `` | no | +| block_device_mappings | Specify volumes to attach to the instance besides the volumes specified by the AMI | object | `` | no | | bootstrap_extra_args | Passed to the bootstrap.sh script to enable --kublet-extra-args or --use-max-pods. | string | `` | no | | cluster_certificate_authority_data | The base64 encoded certificate data required to communicate with the cluster | string | - | yes | | cluster_endpoint | EKS cluster endpoint | string | - | yes | | cluster_name | The name of the EKS cluster | string | - | yes | | cluster_security_group_id | Security Group ID of the EKS cluster | string | - | yes | -| cpu_utilization_high_evaluation_periods | The number of periods over which data is compared to the specified threshold | string | `2` | no | -| cpu_utilization_high_period_seconds | The period in seconds over which the specified statistic is applied | string | `300` | no | +| cpu_utilization_high_evaluation_periods | The number of periods over which data is compared to the specified threshold | number | `2` | no | +| cpu_utilization_high_period_seconds | The period in seconds over which the specified statistic is applied | number | `300` | no | | cpu_utilization_high_statistic | The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum` | string | `Average` | no | -| cpu_utilization_high_threshold_percent | The value against which the specified statistic is compared | string | `90` | no | -| cpu_utilization_low_evaluation_periods | The number of periods over which data is compared to the specified threshold | string | `2` | no | -| cpu_utilization_low_period_seconds | The period in seconds over which the specified statistic is applied | string | `300` | no | +| cpu_utilization_high_threshold_percent | The value against which the specified statistic is compared | number | `90` | no | +| cpu_utilization_low_evaluation_periods | The number of periods over which data is compared to the specified threshold | number | `2` | no | +| cpu_utilization_low_period_seconds | The period in seconds over which the specified statistic is applied | number | `300` | no | | cpu_utilization_low_statistic | The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum` | string | `Average` | no | -| cpu_utilization_low_threshold_percent | The value against which the specified statistic is compared | string | `10` | no | -| credit_specification | Customize the credit specification of the instances | list | `` | no | -| default_cooldown | The amount of time, in seconds, after a scaling activity completes before another scaling activity can start | string | `300` | no | +| cpu_utilization_low_threshold_percent | The value against which the specified statistic is compared | number | `10` | no | +| credit_specification | Customize the credit specification of the instances | object | `null` | no | +| default_cooldown | The amount of time, in seconds, after a scaling activity completes before another scaling activity can start | number | `300` | no | | delimiter | Delimiter to be used between `namespace`, `stage`, `name` and `attributes` | string | `-` | no | -| disable_api_termination | If `true`, enables EC2 Instance Termination Protection | string | `false` | no | -| ebs_optimized | If true, the launched EC2 instance will be EBS-optimized | string | `false` | no | +| disable_api_termination | If `true`, enables EC2 Instance Termination Protection | bool | `false` | no | +| ebs_optimized | If true, the launched EC2 instance will be EBS-optimized | bool | `false` | no | | eks_worker_ami_name_filter | AMI name filter to lookup the most recent EKS AMI if `image_id` is not provided | string | `amazon-eks-node-*` | no | | eks_worker_ami_name_regex | A regex string to apply to the AMI list returned by AWS | string | `^amazon-eks-node-[1-9,\.]+-v\d{8}$` | no | -| elastic_gpu_specifications | Specifications of Elastic GPU to attach to the instances | list | `` | no | -| enable_monitoring | Enable/disable detailed monitoring | string | `true` | no | -| enabled | Whether to create the resources. Set to `false` to prevent the module from creating any resources | string | `true` | no | -| enabled_metrics | A list of metrics to collect. The allowed values are `GroupMinSize`, `GroupMaxSize`, `GroupDesiredCapacity`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupTerminatingInstances`, `GroupTotalInstances` | list | `` | no | -| environment | Environment, e.g. 'testing', 'UAT' | string | `` | no | -| force_delete | Allows deleting the autoscaling group without waiting for all instances in the pool to terminate. You can force an autoscaling group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling | string | `false` | no | -| health_check_grace_period | Time (in seconds) after instance comes into service before checking health | string | `300` | no | +| elastic_gpu_specifications | Specifications of Elastic GPU to attach to the instances | object | `null` | no | +| enable_monitoring | Enable/disable detailed monitoring | bool | `true` | no | +| enabled | Whether to create the resources. Set to `false` to prevent the module from creating any resources | bool | `true` | no | +| enabled_metrics | A list of metrics to collect. The allowed values are `GroupMinSize`, `GroupMaxSize`, `GroupDesiredCapacity`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupTerminatingInstances`, `GroupTotalInstances` | list(string) | `` | no | +| force_delete | Allows deleting the autoscaling group without waiting for all instances in the pool to terminate. You can force an autoscaling group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling | bool | `false` | no | +| health_check_grace_period | Time (in seconds) after instance comes into service before checking health | number | `300` | no | | health_check_type | Controls how health checking is done. Valid values are `EC2` or `ELB` | string | `EC2` | no | | image_id | EC2 image ID to launch. If not provided, the module will lookup the most recent EKS AMI. See https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html for more details on EKS-optimized images | string | `` | no | | instance_initiated_shutdown_behavior | Shutdown behavior for the instances. Can be `stop` or `terminate` | string | `terminate` | no | -| instance_market_options | The market (purchasing) option for the instances | list | `` | no | +| instance_market_options | The market (purchasing) option for the instances | object | `null` | no | | instance_type | Instance type to launch | string | - | yes | | key_name | SSH key name that should be used for the instance | string | `` | no | -| load_balancers | A list of elastic load balancer names to add to the autoscaling group names. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead | list | `` | no | -| max_size | The maximum size of the autoscale group | string | - | yes | +| load_balancers | A list of elastic load balancer names to add to the autoscaling group. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead | list(string) | `` | no | +| max_size | The maximum size of the autoscale group | number | - | yes | | metrics_granularity | The granularity to associate with the metrics to collect. The only valid value is 1Minute | string | `1Minute` | no | -| min_elb_capacity | Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes | string | `0` | no | -| min_size | The minimum size of the autoscale group | string | - | yes | +| min_elb_capacity | Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes | number | `0` | no | +| min_size | The minimum size of the autoscale group | number | - | yes | | name | Solution name, e.g. 'app' or 'cluster' | string | `app` | no | -| namespace | Namespace, which could be your organization name, e.g. 'eg' or 'cp' | string | - | yes | -| placement | The placement specifications of the instances | list | `` | no | +| namespace | Namespace, which could be your organization name, e.g. 'eg' or 'cp' | string | `` | no | +| placement | The placement specifications of the instances | object | `null` | no | | placement_group | The name of the placement group into which you'll launch your instances, if any | string | `` | no | -| protect_from_scale_in | Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events | string | `false` | no | +| protect_from_scale_in | Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events | bool | `false` | no | | scale_down_adjustment_type | Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity` | string | `ChangeInCapacity` | no | -| scale_down_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | string | `300` | no | +| scale_down_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | number | `300` | no | | scale_down_policy_type | The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling` | string | `SimpleScaling` | no | -| scale_down_scaling_adjustment | The number of instances by which to scale. `scale_down_scaling_adjustment` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | string | `-1` | no | +| scale_down_scaling_adjustment | The number of instances by which to scale. `scale_down_scaling_adjustment` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | number | `-1` | no | | scale_up_adjustment_type | Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity` | string | `ChangeInCapacity` | no | -| scale_up_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | string | `300` | no | +| scale_up_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | number | `300` | no | | scale_up_policy_type | The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling` | string | `SimpleScaling` | no | -| scale_up_scaling_adjustment | The number of instances by which to scale. `scale_up_adjustment_type` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | string | `1` | no | +| scale_up_scaling_adjustment | The number of instances by which to scale. `scale_up_adjustment_type` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | number | `1` | no | | service_linked_role_arn | The ARN of the service-linked role that the ASG will use to call other AWS services | string | `` | no | -| stage | Stage, e.g. 'prod', 'staging', 'dev', or 'test' | string | - | yes | -| subnet_ids | A list of subnet IDs to launch resources in | list | - | yes | -| suspended_processes | A list of processes to suspend for the AutoScaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your autoscaling group from functioning properly. | list | `` | no | -| tags | Additional tags (e.g. `{ BusinessUnit = "XYZ" }` | map | `` | no | -| target_group_arns | A list of aws_alb_target_group ARNs, for use with Application Load Balancing | list | `` | no | -| termination_policies | A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default` | list | `` | no | -| use_custom_image_id | If set to `true`, will use variable `image_id` to run EKS workers inside autoscaling group | string | `false` | no | -| use_existing_aws_iam_instance_profile | If set to `true`, will use variable `aws_iam_instance_profile_name` to run EKS workers using an existing AWS instance profile that was created outside of this module, workaround for error like `count cannot be computed` | string | `false` | no | -| use_existing_security_group | If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed` | string | `false` | no | +| stage | Stage, e.g. 'prod', 'staging', 'dev', or 'test' | string | `` | no | +| subnet_ids | A list of subnet IDs to launch resources in | list(string) | - | yes | +| suspended_processes | A list of processes to suspend for the AutoScaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your autoscaling group from functioning properly. | list(string) | `` | no | +| tags | Additional tags (e.g. `{ BusinessUnit = "XYZ" }` | map(string) | `` | no | +| target_group_arns | A list of aws_alb_target_group ARNs, for use with Application Load Balancing | list(string) | `` | no | +| termination_policies | A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default` | list(string) | `` | no | +| use_custom_image_id | If set to `true`, will use variable `image_id` for the EKS workers inside autoscaling group | bool | `false` | no | +| use_existing_aws_iam_instance_profile | If set to `true`, will use variable `aws_iam_instance_profile_name` to run EKS workers using an existing AWS instance profile that was created outside of this module, workaround for error like `count cannot be computed` | bool | `false` | no | +| use_existing_security_group | If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed` | bool | `false` | no | | vpc_id | VPC ID for the EKS cluster | string | - | yes | | wait_for_capacity_timeout | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. Setting this to '0' causes Terraform to skip all Capacity Waiting behavior | string | `10m` | no | -| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | string | `false` | no | -| workers_role_policy_arns | List of policy ARNs that will be attached to the workers default role on creation | list | `` | no | -| workers_role_policy_arns_count | Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed` | string | `0` | no | +| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | bool | `false` | no | +| workers_role_policy_arns | List of policy ARNs that will be attached to the workers default role on creation | list(string) | `` | no | +| workers_role_policy_arns_count | Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed` | number | `0` | no | | workers_security_group_id | The name of the existing security group that will be used in autoscaling group for EKS workers. If empty, a new security group will be created | string | `` | no | ## Outputs diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.us-east-2.tfvars new file mode 100644 index 0000000..e89c98c --- /dev/null +++ b/examples/complete/fixtures.us-east-2.tfvars @@ -0,0 +1,31 @@ +region = "us-east-2" + +availability_zones = ["us-east-2a", "us-east-2b"] + +namespace = "eg" + +stage = "test" + +name = "eks-workers" + +instance_type = "t2.small" + +health_check_type = "EC2" + +wait_for_capacity_timeout = "10m" + +max_size = 3 + +min_size = 2 + +autoscaling_policies_enabled = true + +cpu_utilization_high_threshold_percent = 80 + +cpu_utilization_low_threshold_percent = 20 + +cluster_name = "eg-test-eks-workers-cluster" + +cluster_endpoint = "" + +cluster_certificate_authority_data = "" diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 6433670..f789c4d 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -6,12 +6,7 @@ locals { # The usage of the specific kubernetes.io/cluster/* resource tags below are required # for EKS and Kubernetes to discover and manage networking resources # https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#base-vpc-networking - tags = merge( - var.tags, - { - "kubernetes.io/cluster/${var.cluster_name}" = "shared" - } - ) + tags = merge(var.tags, map("kubernetes.io/cluster/${var.cluster_name}", "shared")) } module "vpc" { @@ -20,6 +15,7 @@ module "vpc" { stage = var.stage name = var.name cidr_block = "172.16.0.0/16" + tags = local.tags } module "subnets" { @@ -33,6 +29,7 @@ module "subnets" { cidr_block = module.vpc.vpc_cidr_block nat_gateway_enabled = false nat_instance_enabled = false + tags = local.tags } module "eks_workers" { @@ -40,18 +37,13 @@ module "eks_workers" { namespace = var.namespace stage = var.stage name = var.name - attributes = var.attributes - tags = local.tags - image_id = var.image_id - eks_worker_ami_name_filter = var.eks_worker_ami_name_filter instance_type = var.instance_type vpc_id = module.vpc.vpc_id - subnet_ids = [module.subnets.public_subnet_ids] + subnet_ids = module.subnets.public_subnet_ids health_check_type = var.health_check_type min_size = var.min_size max_size = var.max_size wait_for_capacity_timeout = var.wait_for_capacity_timeout - associate_public_ip_address = var.associate_public_ip_address cluster_name = var.cluster_name cluster_endpoint = var.cluster_endpoint cluster_certificate_authority_data = var.cluster_certificate_authority_data @@ -62,4 +54,3 @@ module "eks_workers" { cpu_utilization_high_threshold_percent = var.cpu_utilization_high_threshold_percent cpu_utilization_low_threshold_percent = var.cpu_utilization_low_threshold_percent } - diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index b532455..43f6e9b 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -1,3 +1,18 @@ +output "public_subnet_cidrs" { + value = module.subnets.public_subnet_cidrs + description = "Public subnet CIDRs" +} + +output "private_subnet_cidrs" { + value = module.subnets.private_subnet_cidrs + description = "Private subnet CIDRs" +} + +output "vpc_cidr" { + value = module.vpc.vpc_cidr_block + description = "VPC ID" +} + output "launch_template_id" { description = "ID of the launch template" value = module.eks_workers.launch_template_id @@ -68,8 +83,17 @@ output "security_group_name" { value = module.eks_workers.security_group_name } +output "worker_role_arn" { + description = "ARN of the worker nodes IAM role" + value = module.eks_workers.worker_role_arn +} + +output "worker_role_name" { + description = "Name of the worker nodes IAM role" + value = module.eks_workers.worker_role_name +} + output "config_map_aws_auth" { description = "Kubernetes ConfigMap configuration for worker nodes to join the EKS cluster. https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes" value = module.eks_workers.config_map_aws_auth } - diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index f59c2c2..a4750e0 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -1,6 +1,5 @@ variable "region" { type = string - default = "us-west-2" description = "AWS Region" } @@ -12,51 +11,24 @@ variable "availability_zones" { variable "namespace" { type = string description = "Namespace, which could be your organization name, e.g. 'eg' or 'cp'" - default = "" } variable "stage" { type = string description = "Stage, e.g. 'prod', 'staging', 'dev', or 'test'" - default = "" -} - -variable "environment" { - type = string - default = "" - description = "Environment, e.g. 'testing', 'UAT'" } variable "name" { type = string - default = "app" description = "Solution name, e.g. 'app' or 'cluster'" } -variable "delimiter" { - type = string - default = "-" - description = "Delimiter to be used between `namespace`, `stage`, `name` and `attributes`" -} - -variable "attributes" { - type = list(string) - default = [] - description = "Additional attributes (e.g. `1`)" -} - variable "tags" { type = map(string) default = {} description = "Additional tags (e.g. `{ BusinessUnit = \"XYZ\" }`" } -variable "enabled" { - type = bool - description = "Whether to create the resources. Set to `false` to prevent the module from creating any resources" - default = true -} - variable "cluster_name" { type = string description = "The name of the EKS cluster" @@ -75,90 +47,14 @@ variable "cluster_certificate_authority_data" { variable "cluster_security_group_id" { type = string description = "Security Group ID of the EKS cluster" -} - -variable "vpc_id" { - type = string - description = "VPC ID for the EKS cluster" -} - -variable "allowed_security_groups" { - type = list(string) - default = [] - description = "List of Security Group IDs to be allowed to connect to the worker nodes" -} - -variable "allowed_cidr_blocks" { - type = list(string) - default = [] - description = "List of CIDR blocks to be allowed to connect to the worker nodes" -} - -variable "instance_initiated_shutdown_behavior" { - type = string - description = "Shutdown behavior for the instances. Can be `stop` or `terminate`" - default = "terminate" -} - -variable "image_id" { - type = string - description = "EC2 image ID to launch. If not provided, the module will lookup the most recent EKS AMI. See https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html for more details on EKS-optimized images" default = "" } -variable "use_custom_image_id" { - type = bool - description = "If set to `true`, will use variable `image_id` for the EKS workers inside autoscaling group" - default = false -} - -variable "eks_worker_ami_name_filter" { - type = string - description = "AMI name filter to lookup the most recent EKS AMI if `image_id` is not provided" - default = "amazon-eks-node-*" -} - -variable "eks_worker_ami_name_regex" { - type = string - description = "A regex string to apply to the AMI list returned by AWS" - default = "^amazon-eks-node-[1-9,\\.]+-v\\d{8}$" -} - variable "instance_type" { type = string description = "Instance type to launch" } -variable "key_name" { - type = string - description = "SSH key name that should be used for the instance" - default = "" -} - -variable "associate_public_ip_address" { - type = bool - description = "Associate a public IP address with an instance in a VPC" - default = false -} - -variable "enable_monitoring" { - type = bool - description = "Enable/disable detailed monitoring" - default = true -} - -variable "ebs_optimized" { - type = bool - description = "If true, the launched EC2 instance will be EBS-optimized" - default = false -} - -variable "disable_api_termination" { - type = bool - description = "If `true`, enables EC2 Instance Termination Protection" - default = false -} - variable "max_size" { type = number description = "The maximum size of the autoscale group" @@ -169,335 +65,27 @@ variable "min_size" { description = "The minimum size of the autoscale group" } -variable "subnet_ids" { - description = "A list of subnet IDs to launch resources in" - type = list(string) -} - -variable "default_cooldown" { - type = number - description = "The amount of time, in seconds, after a scaling activity completes before another scaling activity can start" - default = 300 -} - -variable "health_check_grace_period" { - type = number - description = "Time (in seconds) after instance comes into service before checking health" - default = 300 -} - variable "health_check_type" { type = string description = "Controls how health checking is done. Valid values are `EC2` or `ELB`" - default = "EC2" -} - -variable "force_delete" { - type = bool - description = "Allows deleting the autoscaling group without waiting for all instances in the pool to terminate. You can force an autoscaling group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling" - default = false -} - -variable "load_balancers" { - type = list(string) - description = "A list of elastic load balancer names to add to the autoscaling group. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead" - default = [] -} - -variable "target_group_arns" { - type = list(string) - description = "A list of aws_alb_target_group ARNs, for use with Application Load Balancing" - default = [] -} - -variable "termination_policies" { - description = "A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default`" - type = list(string) - default = ["Default"] -} - -variable "suspended_processes" { - type = list(string) - description = "A list of processes to suspend for the AutoScaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your autoscaling group from functioning properly." - default = [] -} - -variable "placement_group" { - type = string - description = "The name of the placement group into which you'll launch your instances, if any" - default = "" -} - -variable "metrics_granularity" { - type = string - description = "The granularity to associate with the metrics to collect. The only valid value is 1Minute" - default = "1Minute" -} - -variable "enabled_metrics" { - description = "A list of metrics to collect. The allowed values are `GroupMinSize`, `GroupMaxSize`, `GroupDesiredCapacity`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupTerminatingInstances`, `GroupTotalInstances`" - type = list(string) - - default = [ - "GroupMinSize", - "GroupMaxSize", - "GroupDesiredCapacity", - "GroupInServiceInstances", - "GroupPendingInstances", - "GroupStandbyInstances", - "GroupTerminatingInstances", - "GroupTotalInstances", - ] } variable "wait_for_capacity_timeout" { type = string description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. Setting this to '0' causes Terraform to skip all Capacity Waiting behavior" - default = "10m" -} - -variable "min_elb_capacity" { - type = number - description = "Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes" - default = 0 -} - -variable "wait_for_elb_capacity" { - type = bool - description = "Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior" - default = false -} - -variable "protect_from_scale_in" { - type = bool - description = "Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events" - default = false -} - -variable "service_linked_role_arn" { - type = string - description = "The ARN of the service-linked role that the ASG will use to call other AWS services" - default = "" } variable "autoscaling_policies_enabled" { type = bool - default = true description = "Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling" } -variable "scale_up_cooldown_seconds" { - type = number - default = 300 - description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" -} - -variable "scale_up_scaling_adjustment" { - type = number - default = 1 - description = "The number of instances by which to scale. `scale_up_adjustment_type` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity" -} - -variable "scale_up_adjustment_type" { - type = string - default = "ChangeInCapacity" - description = "Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity`" -} - -variable "scale_up_policy_type" { - type = string - default = "SimpleScaling" - description = "The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling`" -} - -variable "scale_down_cooldown_seconds" { - type = number - default = 300 - description = "The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start" -} - -variable "scale_down_scaling_adjustment" { - type = number - default = -1 - description = "The number of instances by which to scale. `scale_down_scaling_adjustment` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity" -} - -variable "scale_down_adjustment_type" { - type = string - default = "ChangeInCapacity" - description = "Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity`" -} - -variable "scale_down_policy_type" { - type = string - default = "SimpleScaling" - description = "The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling`" -} - -variable "cpu_utilization_high_evaluation_periods" { - type = number - default = 2 - description = "The number of periods over which data is compared to the specified threshold" -} - -variable "cpu_utilization_high_period_seconds" { - type = number - default = 300 - description = "The period in seconds over which the specified statistic is applied" -} - variable "cpu_utilization_high_threshold_percent" { type = number - default = 90 description = "The value against which the specified statistic is compared" } -variable "cpu_utilization_high_statistic" { - type = string - default = "Average" - description = "The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum`" -} - -variable "cpu_utilization_low_evaluation_periods" { - type = number - default = 2 - description = "The number of periods over which data is compared to the specified threshold" -} - -variable "cpu_utilization_low_period_seconds" { - type = number - default = 300 - description = "The period in seconds over which the specified statistic is applied" -} - variable "cpu_utilization_low_threshold_percent" { type = number - default = 10 description = "The value against which the specified statistic is compared" } - -variable "cpu_utilization_low_statistic" { - type = string - default = "Average" - description = "The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum`" -} - -variable "bootstrap_extra_args" { - type = string - default = "" - description = "Passed to the bootstrap.sh script to enable --kublet-extra-args or --use-max-pods." -} - -variable "aws_iam_instance_profile_name" { - type = string - default = "" - description = "The name of the existing instance profile that will be used in autoscaling group for EKS workers. If empty will create a new instance profile." -} - -variable "workers_security_group_id" { - type = string - default = "" - description = "The name of the existing security group that will be used in autoscaling group for EKS workers. If empty, a new security group will be created" -} - -variable "use_existing_security_group" { - type = bool - description = "If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed`" - default = false -} - -variable "additional_security_group_ids" { - type = list(string) - default = [] - description = "Additional list of security groups that will be attached to the autoscaling group" -} - -variable "use_existing_aws_iam_instance_profile" { - type = bool - description = "If set to `true`, will use variable `aws_iam_instance_profile_name` to run EKS workers using an existing AWS instance profile that was created outside of this module, workaround for error like `count cannot be computed`" - default = false -} - -variable "workers_role_policy_arns" { - type = list(string) - default = [] - description = "List of policy ARNs that will be attached to the workers default role on creation" -} - -variable "workers_role_policy_arns_count" { - type = number - default = 0 - description = "Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed`" -} - -variable "block_device_mappings" { - description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" - - type = list(object({ - device_name = string - no_device = bool - virtual_name = string - ebs = object({ - delete_on_termination = bool - encrypted = bool - iops = number - kms_key_id = string - snapshot_id = string - volume_size = number - volume_type = string - }) - })) - - default = [] -} - -variable "instance_market_options" { - description = "The market (purchasing) option for the instances" - - type = object({ - market_type = string - spot_options = object({ - block_duration_minutes = bool - instance_interruption_behavior = string - max_price = number - spot_instance_type = string - valid_until = string - }) - }) - - default = null -} - -variable "placement" { - description = "The placement specifications of the instances" - - type = object({ - affinity = string - availability_zone = string - group_name = string - host_id = string - tenancy = string - }) - - default = null -} - -variable "credit_specification" { - description = "Customize the credit specification of the instances" - - type = object({ - cpu_credits = string - }) - - default = null -} - -variable "elastic_gpu_specifications" { - description = "Specifications of Elastic GPU to attach to the instances" - - type = object({ - type = string - }) - - default = null -} diff --git a/main.tf b/main.tf index 8729521..547862a 100644 --- a/main.tf +++ b/main.tf @@ -13,13 +13,13 @@ module "label" { stage = var.stage name = var.name delimiter = var.delimiter - attributes = [compact(concat(var.attributes, ["workers"]))] + attributes = compact(concat(var.attributes, ["workers"])) tags = local.tags enabled = var.enabled } data "aws_iam_policy_document" "assume_role" { - count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile == false ? 1 : 0 statement { effect = "Allow" @@ -33,43 +33,43 @@ data "aws_iam_policy_document" "assume_role" { } resource "aws_iam_role" "default" { - count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile == false ? 1 : 0 name = module.label.id assume_role_policy = join("", data.aws_iam_policy_document.assume_role.*.json) } resource "aws_iam_role_policy_attachment" "amazon_eks_worker_node_policy" { - count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile == false ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "amazon_eks_cni_policy" { - count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile == false ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "amazon_ec2_container_registry_read_only" { - count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile == false ? 1 : 0 policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" role = join("", aws_iam_role.default.*.name) } resource "aws_iam_role_policy_attachment" "existing_policies_attach_to_eks_workers_role" { - count = var.enabled && var.use_existing_aws_iam_instance_profile ? var.workers_role_policy_arns_count : 0 - policy_arn = element(var.workers_role_policy_arns, count.index) + count = var.enabled && var.use_existing_aws_iam_instance_profile == false ? var.workers_role_policy_arns_count : 0 + policy_arn = var.workers_role_policy_arns[count.index] role = join("", aws_iam_role.default.*.name) } resource "aws_iam_instance_profile" "default" { - count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 + count = var.enabled && var.use_existing_aws_iam_instance_profile == false ? 1 : 0 name = module.label.id role = join("", aws_iam_role.default.*.name) } resource "aws_security_group" "default" { - count = var.enabled && var.use_existing_security_group ? 1 : 0 + count = var.enabled && var.use_existing_security_group == false ? 1 : 0 name = module.label.id description = "Security Group for EKS worker nodes" vpc_id = var.vpc_id @@ -77,7 +77,7 @@ resource "aws_security_group" "default" { } resource "aws_security_group_rule" "egress" { - count = var.enabled && var.use_existing_security_group ? 1 : 0 + count = var.enabled && var.use_existing_security_group == false ? 1 : 0 description = "Allow all egress traffic" from_port = 0 to_port = 0 @@ -88,7 +88,7 @@ resource "aws_security_group_rule" "egress" { } resource "aws_security_group_rule" "ingress_self" { - count = var.enabled && var.use_existing_security_group ? 1 : 0 + count = var.enabled && var.use_existing_security_group == false ? 1 : 0 description = "Allow nodes to communicate with each other" from_port = 0 to_port = 65535 @@ -99,7 +99,7 @@ resource "aws_security_group_rule" "ingress_self" { } resource "aws_security_group_rule" "ingress_cluster" { - count = var.enabled && var.use_existing_security_group ? 1 : 0 + count = var.enabled && var.cluster_security_group_id != "" && var.use_existing_security_group == false ? 1 : 0 description = "Allow worker kubelets and pods to receive communication from the cluster control plane" from_port = 0 to_port = 65535 @@ -110,18 +110,18 @@ resource "aws_security_group_rule" "ingress_cluster" { } resource "aws_security_group_rule" "ingress_security_groups" { - count = var.enabled && var.use_existing_security_group ? length(var.allowed_security_groups) : 0 + count = var.enabled && var.use_existing_security_group == false ? length(var.allowed_security_groups) : 0 description = "Allow inbound traffic from existing Security Groups" from_port = 0 to_port = 65535 protocol = "-1" - source_security_group_id = element(var.allowed_security_groups, count.index) + source_security_group_id = var.allowed_security_groups[count.index] security_group_id = join("", aws_security_group.default.*.id) type = "ingress" } resource "aws_security_group_rule" "ingress_cidr_blocks" { - count = var.enabled && length(var.allowed_cidr_blocks) > 0 && var.use_existing_security_group ? 1 : 0 + count = var.enabled && length(var.allowed_cidr_blocks) > 0 && var.use_existing_security_group == false ? 1 : 0 description = "Allow inbound traffic from CIDR blocks" from_port = 0 to_port = 0 @@ -156,47 +156,47 @@ module "autoscale_group" { attributes = var.attributes image_id = var.use_custom_image_id ? var.image_id : join("", data.aws_ami.eks_worker.*.id) - iam_instance_profile_name = var.use_existing_aws_iam_instance_profile ? join("", aws_iam_instance_profile.default.*.name) : var.aws_iam_instance_profile_name + iam_instance_profile_name = var.use_existing_aws_iam_instance_profile == false ? join("", aws_iam_instance_profile.default.*.name) : var.aws_iam_instance_profile_name - security_group_ids = [compact( + security_group_ids = compact( concat( [ - var.use_existing_security_group ? join("", aws_security_group.default.*.id) : var.workers_security_group_id, + var.use_existing_security_group == false ? join("", aws_security_group.default.*.id) : var.workers_security_group_id ], var.additional_security_group_ids ) - )] + ) user_data_base64 = base64encode(join("", data.template_file.userdata.*.rendered)) tags = module.label.tags instance_type = var.instance_type - subnet_ids = [var.subnet_ids] + subnet_ids = var.subnet_ids min_size = var.min_size max_size = var.max_size associate_public_ip_address = var.associate_public_ip_address - block_device_mappings = [var.block_device_mappings] - credit_specification = [var.credit_specification] + block_device_mappings = var.block_device_mappings + credit_specification = var.credit_specification disable_api_termination = var.disable_api_termination ebs_optimized = var.ebs_optimized - elastic_gpu_specifications = [var.elastic_gpu_specifications] + elastic_gpu_specifications = var.elastic_gpu_specifications instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior - instance_market_options = [var.instance_market_options] + instance_market_options = var.instance_market_options key_name = var.key_name - placement = [var.placement] + placement = var.placement enable_monitoring = var.enable_monitoring - load_balancers = [var.load_balancers] + load_balancers = var.load_balancers health_check_grace_period = var.health_check_grace_period health_check_type = var.health_check_type min_elb_capacity = var.min_elb_capacity wait_for_elb_capacity = var.wait_for_elb_capacity - target_group_arns = [var.target_group_arns] + target_group_arns = var.target_group_arns default_cooldown = var.default_cooldown force_delete = var.force_delete termination_policies = var.termination_policies suspended_processes = var.suspended_processes placement_group = var.placement_group - enabled_metrics = [var.enabled_metrics] + enabled_metrics = var.enabled_metrics metrics_granularity = var.metrics_granularity wait_for_capacity_timeout = var.wait_for_capacity_timeout protect_from_scale_in = var.protect_from_scale_in diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..442804a --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +.test-harness diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..17b2fe7 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,43 @@ +TEST_HARNESS ?= https://github.com/cloudposse/test-harness.git +TEST_HARNESS_BRANCH ?= master +TEST_HARNESS_PATH = $(realpath .test-harness) +BATS_ARGS ?= --tap +BATS_LOG ?= test.log + +# Define a macro to run the tests +define RUN_TESTS +@echo "Running tests in $(1)" +@cd $(1) && bats $(BATS_ARGS) $(addsuffix .bats,$(addprefix $(TEST_HARNESS_PATH)/test/terraform/,$(TESTS))) +endef + +default: all + +-include Makefile.* + +## Provision the test-harnesss +.test-harness: + [ -d $@ ] || git clone --depth=1 -b $(TEST_HARNESS_BRANCH) $(TEST_HARNESS) $@ + +## Initialize the tests +init: .test-harness + +## Install all dependencies (OS specific) +deps:: + @exit 0 + +## Clean up the test harness +clean: + [ "$(TEST_HARNESS_PATH)" == "/" ] || rm -rf $(TEST_HARNESS_PATH) + +## Run all tests +all: module examples/complete + +## Run basic sanity checks against the module itself +module: export TESTS ?= installed lint get-modules module-pinning get-plugins provider-pinning validate terraform-docs input-descriptions output-descriptions +module: deps + $(call RUN_TESTS, ../) + +## Run tests against example +examples/complete: export TESTS ?= installed lint get-modules get-plugins validate +examples/complete: deps + $(call RUN_TESTS, ../$@) diff --git a/test/Makefile.alpine b/test/Makefile.alpine new file mode 100644 index 0000000..7925b18 --- /dev/null +++ b/test/Makefile.alpine @@ -0,0 +1,5 @@ +ifneq (,$(wildcard /sbin/apk)) +## Install all dependencies for alpine +deps:: init + @apk add --update terraform-docs@cloudposse json2hcl@cloudposse +endif diff --git a/test/src/.gitignore b/test/src/.gitignore new file mode 100644 index 0000000..31b0219 --- /dev/null +++ b/test/src/.gitignore @@ -0,0 +1,2 @@ +.gopath +vendor/ diff --git a/test/src/Gopkg.lock b/test/src/Gopkg.lock new file mode 100644 index 0000000..87bb6bd --- /dev/null +++ b/test/src/Gopkg.lock @@ -0,0 +1,92 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" + name = "github.com/davecgh/go-spew" + packages = ["spew"] + pruneopts = "UT" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" + +[[projects]] + digest = "1:75d6042fc66aebc974cc49b0c6c7cc3b9adb5f8130fbfa0dbec0820d990afa25" + name = "github.com/gruntwork-io/terratest" + packages = [ + "modules/collections", + "modules/customerrors", + "modules/files", + "modules/logger", + "modules/retry", + "modules/shell", + "modules/ssh", + "modules/terraform", + ] + pruneopts = "UT" + revision = "892abb2c35878d0808101bbfe6559e931dc2d354" + version = "v0.16.0" + +[[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + pruneopts = "UT" + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + digest = "1:5da8ce674952566deae4dbc23d07c85caafc6cfa815b0b3e03e41979cedb8750" + name = "github.com/stretchr/testify" + packages = [ + "assert", + "require", + ] + pruneopts = "UT" + revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053" + version = "v1.3.0" + +[[projects]] + branch = "master" + digest = "1:831470c2758c8b733941144f2803a0ccad0632c5a767415b777ebd296b5f463e" + name = "golang.org/x/crypto" + packages = [ + "curve25519", + "ed25519", + "ed25519/internal/edwards25519", + "internal/chacha20", + "internal/subtle", + "poly1305", + "ssh", + "ssh/agent", + ] + pruneopts = "UT" + revision = "22d7a77e9e5f409e934ed268692e56707cd169e5" + +[[projects]] + branch = "master" + digest = "1:76ee51c3f468493aff39dbacc401e8831fbb765104cbf613b89bef01cf4bad70" + name = "golang.org/x/net" + packages = ["context"] + pruneopts = "UT" + revision = "f3200d17e092c607f615320ecaad13d87ad9a2b3" + +[[projects]] + branch = "master" + digest = "1:181f3fd33e620b958b5ab77da177cf775cdcccd7db82963607875fbd09ae995e" + name = "golang.org/x/sys" + packages = [ + "cpu", + "unix", + ] + pruneopts = "UT" + revision = "9cd6430ef91e39e1a0ec0470cf1321a33ef1b887" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "github.com/gruntwork-io/terratest/modules/terraform", + "github.com/stretchr/testify/assert", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/test/src/Gopkg.toml b/test/src/Gopkg.toml new file mode 100644 index 0000000..995bac5 --- /dev/null +++ b/test/src/Gopkg.toml @@ -0,0 +1,7 @@ +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.2.2" + +[prune] + go-tests = true + unused-packages = true diff --git a/test/src/Makefile b/test/src/Makefile new file mode 100644 index 0000000..f1920ff --- /dev/null +++ b/test/src/Makefile @@ -0,0 +1,50 @@ +PACKAGE = terraform-aws-eks-workers +GOEXE ?= /usr/bin/go +GOPATH = $(CURDIR)/.gopath +GOBIN = $(GOPATH)/bin +BASE = $(GOPATH)/src/$(PACKAGE) +PATH := $(PATH):$(GOBIN) + +export TF_DATA_DIR ?= $(CURDIR)/.terraform +export TF_CLI_ARGS_init ?= -get-plugins=true +export GOPATH + +.PHONY: all +## Default target +all: test + +ifneq (,$(wildcard /sbin/apk)) +## Install go, if not installed +$(GOEXE): + apk add --update go +endif + +ifeq ($(shell uname -s),Linux) +## Install all `dep`, if not installed +$(GOBIN)/dep: + @mkdir -p $(GOBIN) + @curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh +endif + +## Prepare the GOPATH +$(BASE): $(GOEXE) + @mkdir -p $(dir $@) + @ln -sf $(CURDIR) $@ + +## Download vendor dependencies to vendor/ +$(BASE)/vendor: $(BASE) $(GOBIN)/dep + cd $(BASE) && dep ensure + +.PHONY : init +## Initialize tests +init: $(BASE)/vendor + +.PHONY : test +## Run tests +test: init + cd $(BASE) && go test -v -timeout 30m -run TestExamplesComplete + +.PHONY : clean +## Clean up files +clean: + rm -rf .gopath/ vendor/ $(TF_DATA_DIR) diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go new file mode 100644 index 0000000..04217c9 --- /dev/null +++ b/test/src/examples_complete_test.go @@ -0,0 +1,52 @@ +package test + +import ( + "testing" + + "github.com/gruntwork-io/terratest/modules/terraform" + "github.com/stretchr/testify/assert" +) + +// Test the Terraform module in examples/complete using Terratest. +func TestExamplesComplete(t *testing.T) { + t.Parallel() + + terraformOptions := &terraform.Options{ + // The path to where our Terraform code is located + TerraformDir: "../../examples/complete", + Upgrade: true, + // Variables to pass to our Terraform code using -var-file options + VarFiles: []string{"fixtures.us-east-2.tfvars"}, + } + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer terraform.Destroy(t, terraformOptions) + + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.InitAndApply(t, terraformOptions) + + // Run `terraform output` to get the value of an output variable + vpcCidr := terraform.Output(t, terraformOptions, "vpc_cidr") + // Verify we're getting back the outputs we expect + assert.Equal(t, "172.16.0.0/16", vpcCidr) + + // Run `terraform output` to get the value of an output variable + privateSubnetCidrs := terraform.OutputList(t, terraformOptions, "private_subnet_cidrs") + // Verify we're getting back the outputs we expect + assert.Equal(t, []string{"172.16.0.0/19", "172.16.32.0/19"}, privateSubnetCidrs) + + // Run `terraform output` to get the value of an output variable + publicSubnetCidrs := terraform.OutputList(t, terraformOptions, "public_subnet_cidrs") + // Verify we're getting back the outputs we expect + assert.Equal(t, []string{"172.16.96.0/19", "172.16.128.0/19"}, publicSubnetCidrs) + + // Run `terraform output` to get the value of an output variable + autoscalingGroupName := terraform.Output(t, terraformOptions, "autoscaling_group_name") + // Verify we're getting back the outputs we expect + assert.Contains(t, autoscalingGroupName, "eg-test-ec2-autoscale-group") + + // Run `terraform output` to get the value of an output variable + launchTemplateArn := terraform.Output(t, terraformOptions, "launch_template_arn") + // Verify we're getting back the outputs we expect + assert.Contains(t, launchTemplateArn, "arn:aws:ec2:us-east-2:126450723953:launch-template") +} diff --git a/variables.tf b/variables.tf index a1013d0..9858e3c 100644 --- a/variables.tf +++ b/variables.tf @@ -10,12 +10,6 @@ variable "stage" { default = "" } -variable "environment" { - type = string - default = "" - description = "Environment, e.g. 'testing', 'UAT'" -} - variable "name" { type = string default = "app" From 68a99ee080d77e937e3fa8585bddff53a04234f8 Mon Sep 17 00:00:00 2001 From: aknysh Date: Wed, 25 Sep 2019 21:24:59 -0400 Subject: [PATCH 04/10] Add tests. Add Codefresh test pipeline --- README.md | 2 +- docs/terraform.md | 2 +- variables.tf | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c35bb63..5b7dca4 100644 --- a/README.md +++ b/README.md @@ -209,7 +209,7 @@ Available targets: | use_existing_security_group | If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed` | bool | `false` | no | | vpc_id | VPC ID for the EKS cluster | string | - | yes | | wait_for_capacity_timeout | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. Setting this to '0' causes Terraform to skip all Capacity Waiting behavior | string | `10m` | no | -| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | bool | `false` | no | +| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | number | `0` | no | | workers_role_policy_arns | List of policy ARNs that will be attached to the workers default role on creation | list(string) | `` | no | | workers_role_policy_arns_count | Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed` | number | `0` | no | | workers_security_group_id | The name of the existing security group that will be used in autoscaling group for EKS workers. If empty, a new security group will be created | string | `` | no | diff --git a/docs/terraform.md b/docs/terraform.md index 01e8d64..111c76a 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -72,7 +72,7 @@ | use_existing_security_group | If set to `true`, will use variable `workers_security_group_id` to run EKS workers using an existing security group that was created outside of this module, workaround for errors like `count cannot be computed` | bool | `false` | no | | vpc_id | VPC ID for the EKS cluster | string | - | yes | | wait_for_capacity_timeout | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. Setting this to '0' causes Terraform to skip all Capacity Waiting behavior | string | `10m` | no | -| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | bool | `false` | no | +| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | number | `0` | no | | workers_role_policy_arns | List of policy ARNs that will be attached to the workers default role on creation | list(string) | `` | no | | workers_role_policy_arns_count | Count of policy ARNs that will be attached to the workers default role on creation. Needed to prevent Terraform error `count can't be computed` | number | `0` | no | | workers_security_group_id | The name of the existing security group that will be used in autoscaling group for EKS workers. If empty, a new security group will be created | string | `` | no | diff --git a/variables.tf b/variables.tf index 9858e3c..09ea4a4 100644 --- a/variables.tf +++ b/variables.tf @@ -246,9 +246,9 @@ variable "min_elb_capacity" { } variable "wait_for_elb_capacity" { - type = bool + type = number description = "Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior" - default = false + default = 0 } variable "protect_from_scale_in" { From 0cd3c9c0854f8342cf7bb6dfdcd113148f71c55f Mon Sep 17 00:00:00 2001 From: aknysh Date: Wed, 25 Sep 2019 21:29:34 -0400 Subject: [PATCH 05/10] Add tests. Add Codefresh test pipeline --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 547862a..a1b32e3 100644 --- a/main.tf +++ b/main.tf @@ -132,7 +132,7 @@ resource "aws_security_group_rule" "ingress_cidr_blocks" { } data "aws_ami" "eks_worker" { - count = var.enabled && var.use_custom_image_id ? 1 : 0 + count = var.enabled && var.use_custom_image_id == false ? 1 : 0 most_recent = true name_regex = var.eks_worker_ami_name_regex From 57a78f8aca4a4129a48bb3a76fadf74d46037570 Mon Sep 17 00:00:00 2001 From: aknysh Date: Wed, 25 Sep 2019 21:39:27 -0400 Subject: [PATCH 06/10] Add tests. Add Codefresh test pipeline --- test/src/examples_complete_test.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index 04217c9..da9536d 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -43,10 +43,20 @@ func TestExamplesComplete(t *testing.T) { // Run `terraform output` to get the value of an output variable autoscalingGroupName := terraform.Output(t, terraformOptions, "autoscaling_group_name") // Verify we're getting back the outputs we expect - assert.Contains(t, autoscalingGroupName, "eg-test-ec2-autoscale-group") + assert.Contains(t, autoscalingGroupName, "eg-test-eks-workers") // Run `terraform output` to get the value of an output variable launchTemplateArn := terraform.Output(t, terraformOptions, "launch_template_arn") // Verify we're getting back the outputs we expect assert.Contains(t, launchTemplateArn, "arn:aws:ec2:us-east-2:126450723953:launch-template") + + // Run `terraform output` to get the value of an output variable + securityGroupName := terraform.Output(t, terraformOptions, "security_group_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-eks-workers-workers", securityGroupName) + + // Run `terraform output` to get the value of an output variable + workerRoleName := terraform.Output(t, terraformOptions, "worker_role_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-eks-workers-workers", workerRoleName) } From 740be23e17ef4d0cdf5d6d257d7d699d8928281f Mon Sep 17 00:00:00 2001 From: aknysh Date: Wed, 25 Sep 2019 22:04:25 -0400 Subject: [PATCH 07/10] Add tests. Add Codefresh test pipeline --- main.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index a1b32e3..cfc6b4f 100644 --- a/main.tf +++ b/main.tf @@ -36,6 +36,7 @@ resource "aws_iam_role" "default" { count = var.enabled && var.use_existing_aws_iam_instance_profile == false ? 1 : 0 name = module.label.id assume_role_policy = join("", data.aws_iam_policy_document.assume_role.*.json) + tags = module.label.tags } resource "aws_iam_role_policy_attachment" "amazon_eks_worker_node_policy" { @@ -154,6 +155,7 @@ module "autoscale_group" { name = var.name delimiter = var.delimiter attributes = var.attributes + tags = module.label.tags image_id = var.use_custom_image_id ? var.image_id : join("", data.aws_ami.eks_worker.*.id) iam_instance_profile_name = var.use_existing_aws_iam_instance_profile == false ? join("", aws_iam_instance_profile.default.*.name) : var.aws_iam_instance_profile_name @@ -168,7 +170,6 @@ module "autoscale_group" { ) user_data_base64 = base64encode(join("", data.template_file.userdata.*.rendered)) - tags = module.label.tags instance_type = var.instance_type subnet_ids = var.subnet_ids From 8e871e4f08fd35242b6f6a44c34c5aa375dfc07f Mon Sep 17 00:00:00 2001 From: aknysh Date: Wed, 25 Sep 2019 22:09:57 -0400 Subject: [PATCH 08/10] Add tests. Add Codefresh test pipeline --- README.md | 2 +- README.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b7dca4..b637b44 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ For a complete example, see [examples/complete](examples/complete) ```hcl provider "aws" { - region = var.region + region = var.region } locals { diff --git a/README.yaml b/README.yaml index b434d65..c84ca8b 100644 --- a/README.yaml +++ b/README.yaml @@ -79,7 +79,7 @@ usage: |- ```hcl provider "aws" { - region = var.region + region = var.region } locals { From d85bb5b204e9db5f49d80fc5a65ed43f927d882e Mon Sep 17 00:00:00 2001 From: aknysh Date: Thu, 26 Sep 2019 10:18:33 -0400 Subject: [PATCH 09/10] Remove `config_map_aws_auth.tpl`, it belongs to the cluster module --- README.md | 5 ++-- config_map_aws_auth.tpl | 16 ------------- docs/terraform.md | 5 ++-- examples/complete/outputs.tf | 13 ++++------ main.tf | 46 ++++++++++++++++-------------------- outputs.tf | 13 ++++------ 6 files changed, 32 insertions(+), 66 deletions(-) delete mode 100644 config_map_aws_auth.tpl diff --git a/README.md b/README.md index b637b44..e32d697 100644 --- a/README.md +++ b/README.md @@ -227,14 +227,13 @@ Available targets: | autoscaling_group_max_size | The maximum size of the AutoScaling Group | | autoscaling_group_min_size | The minimum size of the AutoScaling Group | | autoscaling_group_name | The AutoScaling Group name | -| config_map_aws_auth | Kubernetes ConfigMap configuration for worker nodes to join the EKS cluster. https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes | | launch_template_arn | ARN of the launch template | | launch_template_id | The ID of the launch template | | security_group_arn | ARN of the worker nodes Security Group | | security_group_id | ID of the worker nodes Security Group | | security_group_name | Name of the worker nodes Security Group | -| worker_role_arn | ARN of the worker nodes IAM role | -| worker_role_name | Name of the worker nodes IAM role | +| workers_role_arn | ARN of the worker nodes IAM role | +| workers_role_name | Name of the worker nodes IAM role | diff --git a/config_map_aws_auth.tpl b/config_map_aws_auth.tpl deleted file mode 100644 index 1734816..0000000 --- a/config_map_aws_auth.tpl +++ /dev/null @@ -1,16 +0,0 @@ -# The EKS service does not provide a cluster-level API parameter or resource to automatically configure the underlying Kubernetes cluster to allow worker nodes to join the cluster via AWS IAM role authentication. -# This is a Kubernetes ConfigMap configuration for worker nodes to join the cluster -# https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes - -apiVersion: v1 -kind: ConfigMap -metadata: - name: aws-auth - namespace: kube-system -data: - mapRoles: | - - rolearn: ${aws_iam_role_arn} - username: system:node:{{EC2PrivateDNSName}} - groups: - - system:bootstrappers - - system:nodes diff --git a/docs/terraform.md b/docs/terraform.md index 111c76a..5e9b0fd 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -90,12 +90,11 @@ | autoscaling_group_max_size | The maximum size of the AutoScaling Group | | autoscaling_group_min_size | The minimum size of the AutoScaling Group | | autoscaling_group_name | The AutoScaling Group name | -| config_map_aws_auth | Kubernetes ConfigMap configuration for worker nodes to join the EKS cluster. https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes | | launch_template_arn | ARN of the launch template | | launch_template_id | The ID of the launch template | | security_group_arn | ARN of the worker nodes Security Group | | security_group_id | ID of the worker nodes Security Group | | security_group_name | Name of the worker nodes Security Group | -| worker_role_arn | ARN of the worker nodes IAM role | -| worker_role_name | Name of the worker nodes IAM role | +| workers_role_arn | ARN of the worker nodes IAM role | +| workers_role_name | Name of the worker nodes IAM role | diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 43f6e9b..8281540 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -83,17 +83,12 @@ output "security_group_name" { value = module.eks_workers.security_group_name } -output "worker_role_arn" { +output "workers_role_arn" { description = "ARN of the worker nodes IAM role" - value = module.eks_workers.worker_role_arn + value = module.eks_workers.workers_role_arn } -output "worker_role_name" { +output "workers_role_name" { description = "Name of the worker nodes IAM role" - value = module.eks_workers.worker_role_name -} - -output "config_map_aws_auth" { - description = "Kubernetes ConfigMap configuration for worker nodes to join the EKS cluster. https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes" - value = module.eks_workers.config_map_aws_auth + value = module.eks_workers.workers_role_name } diff --git a/main.tf b/main.tf index cfc6b4f..7f24d91 100644 --- a/main.tf +++ b/main.tf @@ -5,6 +5,9 @@ locals { "kubernetes.io/cluster/${var.cluster_name}" = "owned" } ) + + workers_role_arn = var.use_existing_aws_iam_instance_profile ? join("", data.aws_iam_instance_profile.default.*.role_arn) : join("", aws_iam_role.default.*.arn) + workers_role_name = var.use_existing_aws_iam_instance_profile ? join("", data.aws_iam_instance_profile.default.*.role_name) : join("", aws_iam_role.default.*.name) } module "label" { @@ -146,6 +149,23 @@ data "aws_ami" "eks_worker" { owners = ["602401143452"] # Amazon } +data "template_file" "userdata" { + count = var.enabled ? 1 : 0 + template = file("${path.module}/userdata.tpl") + + vars = { + cluster_endpoint = var.cluster_endpoint + certificate_authority_data = var.cluster_certificate_authority_data + cluster_name = var.cluster_name + bootstrap_extra_args = var.bootstrap_extra_args + } +} + +data "aws_iam_instance_profile" "default" { + count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 + name = var.aws_iam_instance_profile_name +} + module "autoscale_group" { source = "git::https://github.com/cloudposse/terraform-aws-ec2-autoscale-group.git?ref=tags/0.2.0" @@ -220,29 +240,3 @@ module "autoscale_group" { cpu_utilization_low_statistic = var.cpu_utilization_low_statistic cpu_utilization_low_threshold_percent = var.cpu_utilization_low_threshold_percent } - -data "template_file" "userdata" { - count = var.enabled ? 1 : 0 - template = file("${path.module}/userdata.tpl") - - vars = { - cluster_endpoint = var.cluster_endpoint - certificate_authority_data = var.cluster_certificate_authority_data - cluster_name = var.cluster_name - bootstrap_extra_args = var.bootstrap_extra_args - } -} - -data "aws_iam_instance_profile" "default" { - count = var.enabled && var.use_existing_aws_iam_instance_profile ? 1 : 0 - name = var.aws_iam_instance_profile_name -} - -data "template_file" "config_map_aws_auth" { - count = var.enabled ? 1 : 0 - template = file("${path.module}/config_map_aws_auth.tpl") - - vars = { - aws_iam_role_arn = var.use_existing_aws_iam_instance_profile ? join("", data.aws_iam_instance_profile.default.*.role_arn) : join("", aws_iam_role.default.*.arn) - } -} diff --git a/outputs.tf b/outputs.tf index d921d68..65bae6b 100644 --- a/outputs.tf +++ b/outputs.tf @@ -68,17 +68,12 @@ output "security_group_name" { value = join("", aws_security_group.default.*.name) } -output "worker_role_arn" { +output "workers_role_arn" { description = "ARN of the worker nodes IAM role" - value = join("", aws_iam_role.default.*.arn) + value = local.workers_role_arn } -output "worker_role_name" { +output "workers_role_name" { description = "Name of the worker nodes IAM role" - value = join("", aws_iam_role.default.*.name) -} - -output "config_map_aws_auth" { - description = "Kubernetes ConfigMap configuration for worker nodes to join the EKS cluster. https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#required-kubernetes-configuration-to-join-worker-nodes" - value = join("", data.template_file.config_map_aws_auth.*.rendered) + value = local.workers_role_name } From 730d99cc66ff282661bdc959d996d6242b21bc6c Mon Sep 17 00:00:00 2001 From: aknysh Date: Thu, 26 Sep 2019 10:27:51 -0400 Subject: [PATCH 10/10] Remove `config_map_aws_auth.tpl`, it belongs to the cluster module --- test/src/examples_complete_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index da9536d..e7c8411 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -56,7 +56,7 @@ func TestExamplesComplete(t *testing.T) { assert.Equal(t, "eg-test-eks-workers-workers", securityGroupName) // Run `terraform output` to get the value of an output variable - workerRoleName := terraform.Output(t, terraformOptions, "worker_role_name") + workerRoleName := terraform.Output(t, terraformOptions, "workers_role_name") // Verify we're getting back the outputs we expect assert.Equal(t, "eg-test-eks-workers-workers", workerRoleName) }