Skip to content

Commit

Permalink
Use official AWS lambda images for services (#744)
Browse files Browse the repository at this point in the history
  • Loading branch information
dwilkie authored Sep 14, 2024
1 parent 6f74686 commit 5eade55
Show file tree
Hide file tree
Showing 17 changed files with 290 additions and 170 deletions.
136 changes: 96 additions & 40 deletions .github/workflows/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: Services

env:
CI: true
ECR_REGISTRY: 324279636507.dkr.ecr.ap-southeast-1.amazonaws.com
GHCR_REGISTRY: ghcr.io/somleng
REPOSITORY_NAME: switch-services

jobs:
build:
Expand All @@ -11,6 +14,7 @@ jobs:
outputs:
matrix: ${{ steps.set-deployment-matrix.outputs.matrix }}
matrixLength: ${{ steps.set-deployment-matrix.outputs.matrixLength }}

defaults:
run:
working-directory: components/services
Expand Down Expand Up @@ -62,13 +66,15 @@ jobs:
"identifier": "switch-services-staging",
"environment": "staging",
"branch": "develop",
"image_tag": "staging"
"friendly_image_tag": "beta",
"image_tag": "stag-${{ github.sha }}"
},
{
"identifier": "switch-services",
"environment": "production",
"branch": "master",
"image_tag": "latest"
"friendly_image_tag": "latest",
"image_tag": "prod-${{ github.sha }}"
}
]
EOF
Expand All @@ -77,10 +83,96 @@ jobs:
echo "matrix={\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT
echo "matrixLength=$(echo $matrix | jq length)" >> $GITHUB_OUTPUT
build-packages:
name: Build Packages
runs-on: ubuntu-latest
if: needs.build.outputs.matrixLength > 0

strategy:
matrix: ${{fromJson(needs.build.outputs.matrix)}}

needs:
- build

steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
role-skip-session-tagging: true
role-duration-seconds: 3600
aws-region: ap-southeast-1

- name: Build image
uses: aws-actions/aws-codebuild-run-build@v1
with:
project-name: somleng-switch-arm64
buildspec-override: |
version: 0.2
phases:
build:
steps:
- name: Build
run: |
cd components/services
aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin ${{ env.ECR_REGISTRY }}
export DOCKER_BUILDKIT=1
docker buildx build --cache-from ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }}-arm64 --tag ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }}-arm64 --tag ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.image_tag }}-arm64 --push .
docker buildx imagetools create -t ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }} -t ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.image_tag }} ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }}-arm64
publish_images:
name: Publish Images
runs-on: ubuntu-latest

needs:
- build
- build-packages

strategy:
matrix: ${{fromJSON(needs.build.outputs.matrix)}}

steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
role-skip-session-tagging: true
role-duration-seconds: 3600
aws-region: ap-southeast-1

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Login to ECR
uses: docker/login-action@v3
with:
registry: ${{ env.ECR_REGISTRY }}

- name: Publish Images
run: |
docker image pull ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }}-arm64
docker tag ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }}-arm64 ${{ env.GHCR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }}-arm64
docker push ${{ env.GHCR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }}-arm64
docker buildx imagetools create -t ${{ env.GHCR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }} "${{ env.GHCR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.friendly_image_tag }}-arm64"
deploy:
name: Deploy
runs-on: ubuntu-latest
needs: build
needs:
- build
- build-packages

if: needs.build.outputs.matrixLength > 0
defaults:
run:
Expand All @@ -90,10 +182,6 @@ jobs:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ap-southeast-1
ECR_REGISTRY: 324279636507.dkr.ecr.ap-southeast-1.amazonaws.com
ECR_REPOSITORY: 324279636507.dkr.ecr.ap-southeast-1.amazonaws.com/somleng-switch-services
GHCR_REPOSITORY: ghcr.io/somleng/switch-services
IMAGE_TAG: ${{ github.sha }}

strategy:
matrix: ${{fromJson(needs.build.outputs.matrix)}}
Expand All @@ -113,42 +201,10 @@ jobs:
role-duration-seconds: 3600
aws-region: ap-southeast-1

- name: Login to AWS ECR
uses: docker/login-action@v3
with:
registry: ${{ env.ECR_REGISTRY }}

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
provenance: false
platforms: linux/arm64
cache-from: type=gha,scope=${{ matrix.identifier }}
cache-to: type=gha,mode=max,scope=${{ matrix.identifier }}
context: components/services
tags: |
${{ env.ECR_REPOSITORY }}:${{ matrix.image_tag }}
${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
${{ env.GHCR_REPOSITORY }}:${{ matrix.image_tag }}
- name: Deploy Lambda
run: |
aws lambda update-function-code --function-name ${{ matrix.identifier }} \
--image-uri ${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} \
--image-uri ${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY_NAME }}:${{ matrix.image_tag }}-arm64 \
--architectures "arm64" \
--publish
Expand Down
29 changes: 11 additions & 18 deletions components/services/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
ARG FUNCTION_DIR="/function"
ARG RUBY_VERSION=3.3
FROM public.ecr.aws/docker/library/ruby:$RUBY_VERSION-alpine AS build-image
FROM public.ecr.aws/lambda/ruby:$RUBY_VERSION AS build-image

RUN apk update && \
apk upgrade && \
apk add --update --no-cache build-base postgresql-dev

RUN gem install bundler
RUN dnf update && \
dnf -y install postgresql-devel openssl-devel gcc make

ARG FUNCTION_DIR
RUN mkdir -p ${FUNCTION_DIR}
Expand All @@ -15,11 +12,11 @@ WORKDIR ${FUNCTION_DIR}

ENV BUNDLE_APP_CONFIG="${FUNCTION_DIR}/.bundle"

RUN bundle config --local deployment true && \
RUN gem install bundler && \
bundle config --local deployment true && \
bundle config --local path "vendor/bundle" && \
bundle config --local without 'development test'

RUN bundle install --jobs 20 --retry 5
bundle config --local without 'development test' && \
bundle install

RUN rm -rf vendor/bundle/ruby/*/cache/ && find vendor/ -name "*.o" -delete && find vendor/ -name "*.c"

Expand All @@ -28,23 +25,19 @@ COPY app/ ${FUNCTION_DIR}/app/
COPY config/ ${FUNCTION_DIR}/config/
COPY lib/ ${FUNCTION_DIR}/lib/

#############################
# #############################

FROM public.ecr.aws/docker/library/ruby:$RUBY_VERSION-alpine
FROM public.ecr.aws/lambda/ruby:$RUBY_VERSION

ARG FUNCTION_DIR
WORKDIR ${FUNCTION_DIR}

ENV BUNDLE_APP_CONFIG="${FUNCTION_DIR}/.bundle"
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}

RUN apk update && \
apk upgrade && \
apk add --update --no-cache postgresql-dev && \
gem install bundler && \
gem install aws_lambda_ric
RUN dnf update && \
dnf -y install postgresql-devel

ENV RUBY_YJIT_ENABLE=true

ENTRYPOINT [ "/usr/local/bundle/bin/aws_lambda_ric" ]
CMD [ "app.App::Handler.process" ]
1 change: 1 addition & 0 deletions components/services/config/app_settings.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "yaml"
require "erb"
require "pathname"

class AppSettings
DEFAULT_SETTINGS_PATH = Pathname(File.expand_path("app_settings.yml", __dir__))
Expand Down
3 changes: 3 additions & 0 deletions components/services/config/application.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
require "bundler"
Bundler.require(:default)

require_relative "app_settings"
require_relative "initializers/aws_stubs"

Expand Down
2 changes: 2 additions & 0 deletions components/services/config/initializers/aws_stubs.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require "aws-sdk-core"

if %w[development test].include?(AppSettings.env)
Aws.config[:ssm] = {
stub_responses: {
Expand Down
1 change: 1 addition & 0 deletions components/services/lib/encrypted_credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require "tempfile"
require "openssl"
require "base64"
require "pathname"

module EncryptedCredentials
class EncryptedFile
Expand Down
1 change: 1 addition & 0 deletions infrastructure/core/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions infrastructure/core/codebuild.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ resource "aws_iam_role_policy_attachment" "codebuild_ecr_public" {
policy_arn = "arn:aws:iam::aws:policy/AmazonElasticContainerRegistryPublicPowerUser"
}

resource "aws_iam_role_policy_attachment" "codebuild_ecr" {
role = aws_iam_role.codebuild.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser"
}

resource "aws_codebuild_project" "amd64" {
name = "${local.codebuild_identifier}-amd64"

Expand Down
Loading

0 comments on commit 5eade55

Please sign in to comment.