Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
ARG RUBY_VERSION
ARG NODE_VERSION
ARG CHAMBER_VERSION=2.13.4

### dev

Expand Down Expand Up @@ -56,6 +57,7 @@ FROM ${TARGETARCH}_jemalloc as production
ARG NODE_VERSION
ARG TARGETARCH
ARG REVISION
ARG CHAMBER_VERSION

ENV RAILS_ENV production
ENV NODE_ENV production
Expand All @@ -82,8 +84,14 @@ RUN curl -L https://fly.io/install.sh | sh
ENV FLYCTL_INSTALL="/root/.fly"
ENV PATH="$FLYCTL_INSTALL/bin:$PATH"

# Set up chamber for SSM-based secrets management
RUN curl -fL "https://github.com/segmentio/chamber/releases/download/v${CHAMBER_VERSION}/chamber-v${CHAMBER_VERSION}-linux-${TARGETARCH}" \
-o /usr/local/bin/chamber \
&& chmod +x /usr/local/bin/chamber

COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build --chown=www /usr/src/intercode /usr/src/intercode
RUN chmod +x /usr/src/intercode/bin/entrypoint.sh

# The following two lines are to enable heroku exec support: https://devcenter.heroku.com/articles/exec#using-with-docker
ADD ./.profile.d /app/.profile.d
Expand All @@ -93,4 +101,5 @@ WORKDIR /usr/src/intercode

USER www
ENV PATH=/opt/node/bin:$PATH
CMD bundle exec bin/rails server -p $PORT -b 0.0.0.0
ENTRYPOINT ["/usr/src/intercode/bin/entrypoint.sh"]
CMD ["bundle", "exec", "bin/rails", "server", "-p", "3000", "-b", "0.0.0.0"]
8 changes: 8 additions & 0 deletions bin/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
set -e

if [ -n "$CHAMBER_SERVICE" ]; then
exec chamber exec "$CHAMBER_SERVICE" -- "$@"
else
exec "$@"
fi
1 change: 1 addition & 0 deletions fly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ release_command = "bundle exec rails release:perform --trace"
strategy = "bluegreen"

[env]
CHAMBER_SERVICE = "intercode_production"
ASSETS_HOST = "assets.neilhosting.net"
AUTOSCALE_MIN_INSTANCES = "2"
AUTOSCALE_MAX_INSTANCES = "10"
Expand Down
10 changes: 10 additions & 0 deletions terraform/modules/intercode_aws_resources/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ resource "aws_iam_group_policy" "this" {
Action = ["events:PutRule", "events:PutTargets"]
Resource = "*"
},
{
Sid = "SsmParameterAccess"
Effect = "Allow"
Action = [
"ssm:GetParametersByPath",
"ssm:GetParameter",
"ssm:GetParameters",
]
Resource = "arn:aws:ssm:${local.region}:${local.account_id}:parameter/${var.name}/*"
},
]
})
}
Expand Down
10 changes: 10 additions & 0 deletions terraform/modules/intercode_aws_resources/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,13 @@ output "iam_access_key_secret" {
value = aws_iam_access_key.this.secret
sensitive = true
}

output "chamber_service" {
description = "Value to set as CHAMBER_SERVICE in the app's environment. Chamber will load all SSM parameters under this path prefix at boot."
value = var.name
}

output "ssm_path_prefix" {
description = "SSM Parameter Store path prefix where app secrets are stored (e.g. for use with aws ssm put-parameter for manually-managed secrets)."
value = "/${var.name}"
}
35 changes: 35 additions & 0 deletions terraform/modules/intercode_aws_resources/ssm.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
locals {
ssm_path_prefix = "/${var.name}"
}

resource "aws_ssm_parameter" "aws_access_key_id" {
name = "${local.ssm_path_prefix}/AWS_ACCESS_KEY_ID"
type = "SecureString"
value = aws_iam_access_key.this.id
}

resource "aws_ssm_parameter" "aws_secret_access_key" {
name = "${local.ssm_path_prefix}/AWS_SECRET_ACCESS_KEY"
type = "SecureString"
value = aws_iam_access_key.this.secret
}

resource "aws_ssm_parameter" "aws_s3_bucket" {
name = "${local.ssm_path_prefix}/AWS_S3_BUCKET"
type = "String"
value = aws_s3_bucket.uploads.bucket
}

resource "aws_ssm_parameter" "aws_region" {
name = "${local.ssm_path_prefix}/AWS_REGION"
type = "String"
value = local.region
}

resource "aws_ssm_parameter" "secrets" {
for_each = var.secrets

name = "${local.ssm_path_prefix}/${each.key}"
type = "SecureString"
value = each.value
}
7 changes: 7 additions & 0 deletions terraform/modules/intercode_aws_resources/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ variable "alarm_email_destinations" {
type = set(string)
default = []
}

variable "secrets" {
description = "Map of secret name to value for manually-managed secrets (e.g. DATABASE_URL, SECRET_KEY_BASE). Written to SSM Parameter Store as SecureString and loaded by chamber at app boot."
type = map(string)
sensitive = true
default = {}
}
Loading