diff --git a/README.md b/README.md index 3d1df43..a3eb5c8 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ packer validate template.json packer build \ -var="source_ami=" \ - -var="concourse_version=v3.14.1" \ + -var="concourse_version=v4.2.1" \ template.json ``` diff --git a/examples/default/example.tf b/examples/default/example.tf index 52e54f4..07e23b7 100644 --- a/examples/default/example.tf +++ b/examples/default/example.tf @@ -12,7 +12,7 @@ data "aws_subnet_ids" "main" { module "postgres" { source = "telia-oss/rds-cluster/aws" - version = "0.1.1" + version = "0.3.0" name_prefix = "example" username = "superuser" @@ -39,13 +39,17 @@ module "concourse_atc" { vpc_id = "${data.aws_vpc.main.id}" public_subnet_ids = ["${data.aws_subnet_ids.main.ids}"] private_subnet_ids = ["${data.aws_subnet_ids.main.ids}"] - postgres_connection = "${module.postgres.postgres_connection_string}" + postgres_host = "${module.postgres.endpoint}" + postgres_port = "${module.postgres.port}" + postgres_username = "${module.postgres.username}" + postgres_password = "" + postgres_database = "${module.postgres.database_name}" encryption_key = "" instance_ami = "" github_client_id = "" github_client_secret = "" github_users = ["itsdalmo"] - github_teams = ["telia-oss/some-team"] + github_teams = ["telia-oss:concourse-owners"] tags { environment = "prod" diff --git a/modules/atc/cloud-config.yml b/modules/atc/cloud-config.yml index 2a1bd56..fb6016d 100644 --- a/modules/atc/cloud-config.yml +++ b/modules/atc/cloud-config.yml @@ -51,13 +51,17 @@ write_files: TimeoutStopSec=1h PIDFile=/run/concourse.pid + Environment="CONCOURSE_GITHUB_CLIENT_ID=${github_client_id}" + Environment="CONCOURSE_GITHUB_CLIENT_SECRET=${github_client_secret}" ${github_users} ${github_teams} - Environment="CONCOURSE_BASIC_AUTH_USERNAME=${basic_auth_username}" - Environment="CONCOURSE_BASIC_AUTH_PASSWORD=${basic_auth_password}" - Environment="CONCOURSE_GITHUB_AUTH_CLIENT_ID=${github_client_id}" - Environment="CONCOURSE_GITHUB_AUTH_CLIENT_SECRET=${github_client_secret}" - Environment="CONCOURSE_POSTGRES_DATA_SOURCE=${concourse_postgres_source}" + + Environment="CONCOURSE_POSTGRES_HOST=${postgres_host}" + Environment="CONCOURSE_POSTGRES_PORT=${postgres_port}" + Environment="CONCOURSE_POSTGRES_USER=${postgres_username}" + Environment="CONCOURSE_POSTGRES_PASSWORD=${postgres_password}" + Environment="CONCOURSE_POSTGRES_DATABASE=${postgres_database}" + Environment="CONCOURSE_EXTERNAL_URL=${concourse_web_host}" Environment="CONCOURSE_LOG_LEVEL=${log_level}" Environment="CONCOURSE_TSA_LOG_LEVEL=${log_level}" @@ -66,6 +70,7 @@ write_files: Environment="CONCOURSE_SESSION_SIGNING_KEY=/concourse/keys/web/session_signing_key" Environment="CONCOURSE_ENCRYPTION_KEY=${encryption_key}" Environment="CONCOURSE_OLD_ENCRYPTION_KEY=${old_encryption_key}" + ${prometheus_bind_ip} ${prometheus_bind_port} diff --git a/modules/atc/main.tf b/modules/atc/main.tf index a44e9f2..82a941d 100644 --- a/modules/atc/main.tf +++ b/modules/atc/main.tf @@ -39,7 +39,7 @@ resource "aws_autoscaling_attachment" "internal_lb" { module "atc" { source = "telia-oss/asg/aws" - version = "0.1.1" + version = "0.2.0" name_prefix = "${var.name_prefix}-atc" user_data = "${data.template_file.atc.rendered}" @@ -61,29 +61,31 @@ data "template_file" "atc" { template = "${file("${path.module}/cloud-config.yml")}" vars { - stack_name = "${var.name_prefix}-atc-asg" - region = "${data.aws_region.current.name}" - target_group = "${aws_lb_target_group.internal.arn}" - atc_port = "${var.atc_port}" - tsa_port = "${var.tsa_port}" - basic_auth_username = "${var.basic_auth_username}" - basic_auth_password = "${var.basic_auth_password}" - github_client_id = "${var.github_client_id}" - github_client_secret = "${var.github_client_secret}" - github_users = "${length(var.github_users) > 0 ? "Environment=\"CONCOURSE_GITHUB_AUTH_USER=${join(",", var.github_users)}\"" : ""}" - github_teams = "${length(var.github_teams) > 0 ? "Environment=\"CONCOURSE_GITHUB_AUTH_TEAM=${join(",", var.github_teams)}\"" : ""}" - prometheus_bind_ip = "${var.prometheus_enabled == "true" ? "Environment=\"CONCOURSE_PROMETHEUS_BIND_IP=0.0.0.0\"" : ""}" - prometheus_bind_port = "${var.prometheus_enabled == "true" ? "Environment=\"CONCOURSE_PROMETHEUS_BIND_PORT=${var.prometheus_port}\"" : ""}" - start_node_exporter = "${var.prometheus_enabled == "true" ? "systemctl enable node_exporter.service --now" : "echo \"Prometheus disabled, not starting node-exporter\""}" - concourse_web_host = "${lower(var.web_protocol)}://${var.domain != "" ? var.domain : module.external_lb.dns_name}:${var.web_port}" - concourse_postgres_source = "${var.postgres_connection}" - log_group_name = "${aws_cloudwatch_log_group.atc.name}" - log_level = "${var.log_level}" - tsa_host_key = "${file("${var.concourse_keys}/tsa_host_key")}" - session_signing_key = "${file("${var.concourse_keys}/session_signing_key")}" - authorized_worker_keys = "${file("${var.concourse_keys}/authorized_worker_keys")}" - encryption_key = "${var.encryption_key}" - old_encryption_key = "${var.old_encryption_key}" + stack_name = "${var.name_prefix}-atc-asg" + region = "${data.aws_region.current.name}" + target_group = "${aws_lb_target_group.internal.arn}" + atc_port = "${var.atc_port}" + tsa_port = "${var.tsa_port}" + github_client_id = "${var.github_client_id}" + github_client_secret = "${var.github_client_secret}" + github_users = "${length(var.github_users) > 0 ? "Environment=\"CONCOURSE_MAIN_TEAM_GITHUB_USER=${join(",", var.github_users)}\"" : ""}" + github_teams = "${length(var.github_teams) > 0 ? "Environment=\"CONCOURSE_MAIN_TEAM_GITHUB_TEAM=${join(",", var.github_teams)}\"" : ""}" + prometheus_bind_ip = "${var.prometheus_enabled == "true" ? "Environment=\"CONCOURSE_PROMETHEUS_BIND_IP=0.0.0.0\"" : ""}" + prometheus_bind_port = "${var.prometheus_enabled == "true" ? "Environment=\"CONCOURSE_PROMETHEUS_BIND_PORT=${var.prometheus_port}\"" : ""}" + start_node_exporter = "${var.prometheus_enabled == "true" ? "systemctl enable node_exporter.service --now" : "echo \"Prometheus disabled, not starting node-exporter\""}" + concourse_web_host = "${lower(var.web_protocol)}://${var.domain != "" ? var.domain : module.external_lb.dns_name}:${var.web_port}" + postgres_host = "${var.postgres_host}" + postgres_port = "${var.postgres_port}" + postgres_username = "${var.postgres_username}" + postgres_password = "${var.postgres_password}" + postgres_database = "${var.postgres_database}" + log_group_name = "${aws_cloudwatch_log_group.atc.name}" + log_level = "${var.log_level}" + tsa_host_key = "${file("${var.concourse_keys}/tsa_host_key")}" + session_signing_key = "${file("${var.concourse_keys}/session_signing_key")}" + authorized_worker_keys = "${file("${var.concourse_keys}/authorized_worker_keys")}" + encryption_key = "${var.encryption_key}" + old_encryption_key = "${var.old_encryption_key}" } } @@ -168,7 +170,7 @@ resource "aws_route53_record" "main" { module "external_lb" { source = "telia-oss/loadbalancer/aws" - version = "0.1.0" + version = "0.2.0" name_prefix = "${var.name_prefix}-external" vpc_id = "${var.vpc_id}" @@ -219,7 +221,7 @@ resource "aws_lb_target_group" "external" { module "internal_lb" { source = "telia-oss/loadbalancer/aws" - version = "0.1.0" + version = "0.2.0" name_prefix = "${var.name_prefix}-internal" vpc_id = "${var.vpc_id}" diff --git a/modules/atc/variables.tf b/modules/atc/variables.tf index be1bf53..64fe50d 100644 --- a/modules/atc/variables.tf +++ b/modules/atc/variables.tf @@ -36,7 +36,7 @@ variable "max_size" { variable "instance_type" { description = "Type of instance to provision for the Concourse ATC." - default = "t2.small" + default = "t3.small" } variable "instance_ami" { @@ -52,18 +52,24 @@ variable "concourse_keys" { description = "Path to a directory containing the Concourse SSH keys. (See README.md)." } -variable "postgres_connection" { - description = "PostgreSQL connection string (Format: postgres://:@
:/)." +variable "postgres_host" { + description = "The DNS address of the postgres DB." } -variable "basic_auth_username" { - description = "Username to use for basic auth." - default = "" +variable "postgres_port" { + description = "The port on which the DB accepts connections." } -variable "basic_auth_password" { - description = "Password to use for basic auth." - default = "" +variable "postgres_username" { + description = "The master username for the database." +} + +variable "postgres_password" { + description = "Password for the master DB user." +} + +variable "postgres_database" { + description = "Name for the automatically created database." } variable "github_client_id" { @@ -83,7 +89,7 @@ variable "github_users" { } variable "github_teams" { - description = "GitHub team whose members will have admin access." + description = "GitHub team whose members will have admin access (:)." type = "list" default = [] } diff --git a/modules/worker/cloud-config.yml b/modules/worker/cloud-config.yml index b73b8b8..63ed391 100644 --- a/modules/worker/cloud-config.yml +++ b/modules/worker/cloud-config.yml @@ -118,7 +118,11 @@ write_files: TimeoutSec=infinity Environment="AWS_REGION=${region}" - ExecStart=/usr/local/bin/lifecycled --sns-topic=${lifecycle_topic} --handler=/usr/local/scripts/lifecycle-handler.sh + ExecStart=/usr/local/bin/lifecycled \ + --sns-topic=${lifecycle_topic} \ + --handler=/usr/local/scripts/lifecycle-handler.sh \ + --cloudwatch-group=${lifecycled_log_group_name} \ + --json [Install] WantedBy=multi-user.target diff --git a/modules/worker/main.tf b/modules/worker/main.tf index b5cc435..cc6ec67 100644 --- a/modules/worker/main.tf +++ b/modules/worker/main.tf @@ -3,6 +3,8 @@ # ------------------------------------------------------------------------------- data "aws_region" "current" {} +data "aws_caller_identity" "current" {} + resource "aws_security_group_rule" "atc_ingress_garbage_collection" { security_group_id = "${module.worker.security_group_id}" type = "ingress" @@ -32,7 +34,7 @@ resource "aws_security_group_rule" "atc_ingress_garden" { module "worker" { source = "telia-oss/asg/aws" - version = "0.1.1" + version = "0.2.0" name_prefix = "${var.name_prefix}-worker" user_data = "${data.template_file.worker.rendered}" @@ -55,18 +57,19 @@ data "template_file" "worker" { template = "${file("${path.module}/cloud-config.yml")}" vars { - stack_name = "${var.name_prefix}-worker-asg" - region = "${data.aws_region.current.name}" - lifecycle_topic = "${aws_sns_topic.worker.arn}" - tsa_host = "${var.tsa_host}" - tsa_port = "${var.tsa_port}" - log_group_name = "${aws_cloudwatch_log_group.worker.name}" - log_level = "${var.log_level}" - worker_team = "${var.worker_team}" - worker_key = "${file("${var.concourse_keys}/worker_key")}" - pub_worker_key = "${file("${var.concourse_keys}/worker_key.pub")}" - pub_tsa_host_key = "${file("${var.concourse_keys}/tsa_host_key.pub")}" - start_node_exporter = "${var.prometheus_enabled == "true" ? "systemctl enable node_exporter.service --now" : "echo \"Prometheus disabled, not starting node-exporter\""}" + stack_name = "${var.name_prefix}-worker-asg" + region = "${data.aws_region.current.name}" + lifecycle_topic = "${aws_sns_topic.worker.arn}" + lifecycled_log_group_name = "${aws_cloudwatch_log_group.worker_lifecycled.name}" + tsa_host = "${var.tsa_host}" + tsa_port = "${var.tsa_port}" + log_group_name = "${aws_cloudwatch_log_group.worker.name}" + log_level = "${var.log_level}" + worker_team = "${var.worker_team}" + worker_key = "${file("${var.concourse_keys}/worker_key")}" + pub_worker_key = "${file("${var.concourse_keys}/worker_key.pub")}" + pub_tsa_host_key = "${file("${var.concourse_keys}/tsa_host_key.pub")}" + start_node_exporter = "${var.prometheus_enabled == "true" ? "systemctl enable node_exporter.service --now" : "echo \"Prometheus disabled, not starting node-exporter\""}" } } @@ -74,12 +77,17 @@ resource "aws_cloudwatch_log_group" "worker" { name = "${var.name_prefix}-worker" } +resource "aws_cloudwatch_log_group" "worker_lifecycled" { + name = "${var.name_prefix}-worker-lifecycled" +} + data "aws_iam_policy_document" "worker" { statement { effect = "Allow" resources = [ "${aws_cloudwatch_log_group.worker.arn}", + "${aws_cloudwatch_log_group.worker_lifecycled.arn}", ] actions = [ @@ -115,11 +123,22 @@ data "aws_iam_policy_document" "worker" { ] } - # TODO: Scope this to lifecycled-* (as this is what lifecycled names the sqs queues) statement { effect = "Allow" - resources = ["*"] + actions = [ + "logs:DescribeLogStreams", + ] + + resources = [ + "*", + ] + } + + statement { + effect = "Allow" + + resources = ["arn:aws:sqs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:lifecycled-*"] actions = [ "sqs:*", @@ -133,8 +152,6 @@ data "aws_iam_policy_document" "worker" { resources = ["*"] actions = [ - "autoscaling:DescribeAutoScalingInstances", - "autoscaling:DescribeLifecycleHooks", "autoscaling:RecordLifecycleActionHeartbeat", "autoscaling:CompleteLifecycleAction", ] @@ -150,7 +167,7 @@ resource "aws_autoscaling_lifecycle_hook" "worker" { autoscaling_group_name = "${module.worker.id}" lifecycle_transition = "autoscaling:EC2_INSTANCE_TERMINATING" default_result = "CONTINUE" - heartbeat_timeout = "3600" + heartbeat_timeout = "300" notification_target_arn = "${aws_sns_topic.worker.arn}" role_arn = "${aws_iam_role.lifecycle.arn}" } diff --git a/modules/worker/variables.tf b/modules/worker/variables.tf index ac4cf4b..e4807b0 100644 --- a/modules/worker/variables.tf +++ b/modules/worker/variables.tf @@ -26,7 +26,7 @@ variable "max_size" { variable "instance_type" { description = "Type of instance to provision for the Concourse workers." - default = "m5.large" + default = "t3.large" } variable "instance_ami" { diff --git a/packer/template.json b/packer/template.json index a3bd951..5b597c8 100644 --- a/packer/template.json +++ b/packer/template.json @@ -5,40 +5,44 @@ "template_version": "", "ami_users": "" }, - "builders": [{ - "type": "amazon-ebs", - "region": "eu-west-1", - "source_ami": "{{user `source_ami`}}", - "instance_type": "m3.medium", - "ssh_username": "ec2-user", - "ami_name": "concourse-{{user `concourse_version`}}-{{timestamp}}", - "ami_users": "{{user `ami_users`}}", - "tags": { + "builders": [ + { + "type": "amazon-ebs", + "region": "eu-west-1", "source_ami": "{{user `source_ami`}}", - "concourse_version": "{{user `concourse_version`}}", - "template_version": "{{user `template_version`}}" + "instance_type": "m3.medium", + "ssh_username": "ec2-user", + "ami_name": "concourse-{{user `concourse_version`}}-{{timestamp}}", + "ami_users": "{{user `ami_users`}}", + "tags": { + "source_ami": "{{user `source_ami`}}", + "concourse_version": "{{user `concourse_version`}}", + "template_version": "{{user `template_version`}}" + } } - }], - "provisioners": [{ - "type": "shell", - "inline": [ - "sleep 30", - "sudo yum update -y", - "sudo yum install -y awslogs aws-cfn-bootstrap", - "curl -L https://github.com/concourse/concourse/releases/download/{{user `concourse_version`}}/concourse_linux_amd64 -o concourse", - "sudo chmod +x concourse", - "sudo chown root:root concourse", - "sudo mv concourse /usr/local/bin/concourse", - "curl -L https://github.com/lox/lifecycled/releases/download/v2.0.1/lifecycled-linux-amd64 -o lifecycled", - "sudo chmod +x lifecycled", - "sudo chown root:root lifecycled", - "sudo mv lifecycled /usr/local/bin/lifecycled", - "curl -L https://github.com/prometheus/node_exporter/releases/download/v0.16.0/node_exporter-0.16.0.linux-amd64.tar.gz -o node_exporter.tar.gz", - "tar xvzf node_exporter.tar.gz --strip=1 */node_exporter", - "rm node_exporter.tar.gz", - "sudo chmod +x node_exporter", - "sudo chown root:root node_exporter", - "sudo mv node_exporter /usr/local/bin/node_exporter" - ] - }] + ], + "provisioners": [ + { + "type": "shell", + "inline": [ + "sleep 30", + "sudo yum update -y", + "sudo yum install -y awslogs aws-cfn-bootstrap", + "curl -L https://github.com/concourse/concourse/releases/download/{{user `concourse_version`}}/concourse_linux_amd64 -o concourse", + "sudo chmod +x concourse", + "sudo chown root:root concourse", + "sudo mv concourse /usr/local/bin/concourse", + "curl -L https://github.com/lox/lifecycled/releases/download/v2.1.1/lifecycled-linux-amd64 -o lifecycled", + "sudo chmod +x lifecycled", + "sudo chown root:root lifecycled", + "sudo mv lifecycled /usr/local/bin/lifecycled", + "curl -L https://github.com/prometheus/node_exporter/releases/download/v0.16.0/node_exporter-0.16.0.linux-amd64.tar.gz -o node_exporter.tar.gz", + "tar xvzf node_exporter.tar.gz --strip=1 */node_exporter", + "rm node_exporter.tar.gz", + "sudo chmod +x node_exporter", + "sudo chown root:root node_exporter", + "sudo mv node_exporter /usr/local/bin/node_exporter" + ] + } + ] }