|
| 1 | +/** |
| 2 | + * This module adds a task definition configuration for deploying your app along with |
| 3 | + * a sidecar container that writes your secrets manager secret to an ephemeral file |
| 4 | + * that gets bind mounted into your app container. Note that this module is |
| 5 | + * dependent upon opting in to the secretsmanager.tf module. |
| 6 | + * |
| 7 | + * You can deploy this configuration using Fargate CLI: |
| 8 | + * fargate service deploy -r x |
| 9 | + * where "x" is the revision number that this module outputs (see terraform output) |
| 10 | + * |
| 11 | + * Note that if you deploy this configuration on top of your existing app, |
| 12 | + * you will need to re-deploy your app (image and envvars) afterwards. |
| 13 | + * If using fargate-create CLI you can run ./deploy.sh |
| 14 | + * |
| 15 | + */ |
| 16 | + |
| 17 | +variable "secret_dir" { |
| 18 | + type = string |
| 19 | + default = "/var/secret" |
| 20 | + description = "directory where secret is written" |
| 21 | +} |
| 22 | + |
| 23 | +variable "secret_sidecar_image" { |
| 24 | + type = string |
| 25 | + default = "quay.io/turner/secretsmanager-sidecar" |
| 26 | + description = "sidecar container that writes the secret to a file accessible by app container" |
| 27 | +} |
| 28 | + |
| 29 | +locals { |
| 30 | + secret_file = "${var.secret_dir}/${aws_secretsmanager_secret.sm_secret.name}" |
| 31 | + logs_group = "/fargate/service/${var.app}-${var.environment}" |
| 32 | +} |
| 33 | + |
| 34 | +resource "aws_ecs_task_definition" "secrets_sidecar" { |
| 35 | + family = "${var.app}-${var.environment}" |
| 36 | + requires_compatibilities = ["FARGATE"] |
| 37 | + network_mode = "awsvpc" |
| 38 | + cpu = "256" |
| 39 | + memory = "512" |
| 40 | + execution_role_arn = aws_iam_role.ecsTaskExecutionRole.arn |
| 41 | + task_role_arn = aws_iam_role.app_role.arn |
| 42 | + |
| 43 | + volume { |
| 44 | + name = "secret" |
| 45 | + } |
| 46 | + |
| 47 | + container_definitions = <<DEFINITION |
| 48 | +[ |
| 49 | + { |
| 50 | + "name": "${var.container_name}", |
| 51 | + "image": "${var.default_backend_image}", |
| 52 | + "essential": true, |
| 53 | + "dependsOn": [ |
| 54 | + { |
| 55 | + "containerName": "secrets", |
| 56 | + "condition": "SUCCESS" |
| 57 | + } |
| 58 | + ], |
| 59 | + "portMappings": [ |
| 60 | + { |
| 61 | + "protocol": "tcp", |
| 62 | + "containerPort": ${var.container_port}, |
| 63 | + "hostPort": ${var.container_port} |
| 64 | + } |
| 65 | + ], |
| 66 | + "environment": [ |
| 67 | + { |
| 68 | + "name": "PORT", |
| 69 | + "value": "${var.container_port}" |
| 70 | + }, |
| 71 | + { |
| 72 | + "name": "HEALTHCHECK", |
| 73 | + "value": "${var.health_check}" |
| 74 | + }, |
| 75 | + { |
| 76 | + "name": "ENABLE_LOGGING", |
| 77 | + "value": "false" |
| 78 | + }, |
| 79 | + { |
| 80 | + "name": "PRODUCT", |
| 81 | + "value": "${var.app}" |
| 82 | + }, |
| 83 | + { |
| 84 | + "name": "ENVIRONMENT", |
| 85 | + "value": "${var.environment}" |
| 86 | + }, |
| 87 | + { |
| 88 | + "name": "SECRET", |
| 89 | + "value": "${local.secret_file}" |
| 90 | + } |
| 91 | + ], |
| 92 | + "mountPoints": [ |
| 93 | + { |
| 94 | + "readOnly": true, |
| 95 | + "containerPath": "${var.secret_dir}", |
| 96 | + "sourceVolume": "secret" |
| 97 | + } |
| 98 | + ], |
| 99 | + "logConfiguration": { |
| 100 | + "logDriver": "awslogs", |
| 101 | + "options": { |
| 102 | + "awslogs-group": "${local.logs_group}", |
| 103 | + "awslogs-region": "us-east-1", |
| 104 | + "awslogs-stream-prefix": "ecs" |
| 105 | + } |
| 106 | + } |
| 107 | + }, |
| 108 | + { |
| 109 | + "name": "secrets", |
| 110 | + "image": "${var.secret_sidecar_image}", |
| 111 | + "essential": false, |
| 112 | + "environment": [ |
| 113 | + { |
| 114 | + "name": "SECRET_ID", |
| 115 | + "value": "${aws_secretsmanager_secret.sm_secret.arn}" |
| 116 | + }, |
| 117 | + { |
| 118 | + "name": "SECRET_FILE", |
| 119 | + "value": "${local.secret_file}" |
| 120 | + } |
| 121 | + ], |
| 122 | + "mountPoints": [ |
| 123 | + { |
| 124 | + "readOnly": false, |
| 125 | + "containerPath": "${var.secret_dir}", |
| 126 | + "sourceVolume": "secret" |
| 127 | + } |
| 128 | + ], |
| 129 | + "logConfiguration": { |
| 130 | + "logDriver": "awslogs", |
| 131 | + "options": { |
| 132 | + "awslogs-group": "${local.logs_group}", |
| 133 | + "awslogs-region": "us-east-1", |
| 134 | + "awslogs-stream-prefix": "ecs" |
| 135 | + } |
| 136 | + } |
| 137 | + } |
| 138 | +] |
| 139 | +DEFINITION |
| 140 | + |
| 141 | + tags = var.tags |
| 142 | + |
| 143 | + # avoid race condition: |
| 144 | + #"Too many concurrent attempts to create a new revision of the specified family" |
| 145 | + depends_on = [aws_ecs_task_definition.app] |
| 146 | +} |
| 147 | + |
| 148 | +data "template_file" "secrets_sidecar_deploy" { |
| 149 | + template = <<EOF |
| 150 | +#!/bin/bash |
| 151 | +set -e |
| 152 | +
|
| 153 | +AWS_PROFILE=$${aws_profile} |
| 154 | +AWS_DEFAULT_REGION=$${region} |
| 155 | +
|
| 156 | +echo "backing up running container configuration" |
| 157 | +fargate task describe -t $${current_taskdefinition} > backup.yml |
| 158 | +
|
| 159 | +echo "deploying new sidecar configuration" |
| 160 | +fargate service deploy -r $${sidecar_revision} |
| 161 | +
|
| 162 | +echo "re-deploying app configuration" |
| 163 | +fargate service deploy -f backup.yml |
| 164 | +fargate service env set -e SECRET=$${secret} |
| 165 | +EOF |
| 166 | + |
| 167 | + vars = { |
| 168 | + aws_profile = var.aws_profile |
| 169 | + region = var.region |
| 170 | + current_taskdefinition = aws_ecs_service.app.task_definition |
| 171 | + sidecar_revision = split(":", aws_ecs_task_definition.secrets_sidecar.arn)[6] |
| 172 | + secret = local.secret_file |
| 173 | + } |
| 174 | +} |
| 175 | + |
| 176 | +resource "local_file" "secrets_sidecar" { |
| 177 | + filename = "secrets-sidecar-deploy.sh" |
| 178 | + content = "${data.template_file.secrets_sidecar_deploy.rendered}" |
| 179 | +} |
| 180 | + |
| 181 | +# command to deploy the secrets sidecar configuration |
| 182 | +output "deploy_secrets_sidecar" { |
| 183 | + value = "fargate service deploy --revision ${split(":", aws_ecs_task_definition.secrets_sidecar.arn)[6]}" |
| 184 | +} |
0 commit comments