Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(infrastructure): setup ci for lambda #4383

Closed
wants to merge 18 commits into from
Closed
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
149 changes: 149 additions & 0 deletions .github/workflows/deploy-lambda.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: Deploy lambda
on:
pull_request:
push:
branches:
- dev
- main
workflow_dispatch:
env:
TERRAFORM_ROOT: terraform/lambda
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
PNPM_VERSION: 8.13.1
TF_VAR_env: ${{ secrets.ENV }}
TF_VAR_env_vars: ${{ secrets.ENV_VARS }}
TF_VAR_zone_id: ${{ secrets.LAMBDA_ZONE_ID }}
TF_VAR_root_domain: ${{ secrets.ROOT_DOMAIN }}
TF_VAR_sub_domain: ${{ secrets.SUB_DOMAIN }}
TF_VAR_certificate_body: ${{ secrets.STAGING_LAMBDA_CERTIFICATE_BODY }}
TF_VAR_certificate_chain: ${{ secrets.STAGING_LAMBDA_CERTIFICATE_CHAIN }}
TF_VAR_private_key: ${{ secrets.STAGING_LAMBDA_PRIVATE_KEY }}
jobs:
deploy-staging:
runs-on: ubuntu-latest
name: Deploy lambda to staging
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

steps:
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off

- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.head_ref }}

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v3
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-2
mask-aws-account-id: true

- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version-file: .nvmrc
cache: pnpm

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-

- name: Cache turbo build setup
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-

- uses: pnpm/action-setup@v2
name: Install pnpm
with:
version: ${{ env.PNPM_VERSION }}
run_install: false

- name: Install dependencies
run: pnpm i

- uses: actions/labeler@v4
with:
sync-labels: true

- name: Check commit message
run: pnpm commitlint --from=HEAD^1

- name: format:check
run: pnpm format:check

- name: lint
run: pnpm lint

- name: jest
run: pnpm test

- name: tsc
run: pnpm tsc

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v3
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-2
mask-aws-account-id: true

- name: Terraform init
id: init
# run: terraform init
run: terraform init -backend-config="region=eu-west-2" -backend-config="bucket=nowplaying-staging-terraform-state" -backend-config="key=vpc/staging.tfstate" -input=false
working-directory: ${{ env.TERRAFORM_ROOT }}

- name: terraform workspace select
run: terraform workspace select -or-create staging
working-directory: ${{ env.TERRAFORM_ROOT }}

- name: Terraform fmt -check
id: fmt
run: terraform fmt -check
working-directory: ${{ env.TERRAFORM_ROOT }}

- name: Terraform validate
id: validate
run: terraform validate
working-directory: ${{ env.TERRAFORM_ROOT }}

- name: build lambda
run: ./scripts/build-lambda.sh

- name: Plan
run: terraform plan -out=tfplan -input=false
working-directory: ${{ env.TERRAFORM_ROOT }}

- name: choice
run: echo "choice"

- name: apply
run: terraform apply -auto-approve tfplan
working-directory: ${{ env.TERRAFORM_ROOT }}
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ newrelic_agent.log
.terraform
playwright-report
.turbo
*.tfvars
*.tfstate
.turbo
dist
lambda.zip
.terraform.lock.hcl
certs
certs
live.tfvars
staging.tfvars
!example.tfvars
8 changes: 8 additions & 0 deletions scripts/build-lambda.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

cd apps/lambda
pnpm build
cd ../../
cd terraform/lambda
cp -r ../../apps/lambda/dist/ dist
zip -r lambda.zip dist
1 change: 1 addition & 0 deletions scripts/deploy-lambda.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ if [ "$1" == "staging" ]; then
pnpm build
cd ../../
cd terraform/lambda
cp -r ../../apps/lambda/dist/ dist
terraform apply -var-file="envs/staging.tfvars" -auto-approve
elif [ "$1" == "live" ]; then
terraform workspace select live -or-create
Expand Down
2 changes: 1 addition & 1 deletion terraform/lambda/acm.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# required to add certificates + DNS for the API gateway rather than let cloudflare handle the routing

locals {
domain_name = var.env == "live" ? "nowplaying.${var.root_domain}" : "nowplaying-${var.env}.${var.root_domain}"
domain_name = var.env == "live" ? "nowplaying.${var.root_domain}" : "nowplaying-staging.${var.root_domain}"
}

resource "aws_acm_certificate" "root_domain" {
Expand Down
6 changes: 3 additions & 3 deletions terraform/lambda/domain.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
resource "aws_acm_certificate" "cert" {
private_key = file("${path.module}/certs/${var.env}/private-key.pem")
certificate_body = file("${path.module}/certs/${var.env}/certificate.pem")
certificate_chain = file("${path.module}/certs/${var.env}/certificate-chain.pem")
private_key = var.private_key
certificate_body = var.certificate_body
certificate_chain = var.certificate_chain
tags = {
Name = "Nowplaying certificate for ${var.env}"
stage = var.env
Expand Down
5 changes: 5 additions & 0 deletions terraform/lambda/envs/example.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
zone_id = ""
env = ""
env_vars = {}
root_domain = ""
sub_domain = ""
2 changes: 1 addition & 1 deletion terraform/lambda/gateway.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ resource "aws_apigatewayv2_api" "lambda" {
}

resource "aws_apigatewayv2_domain_name" "domain_name" {
domain_name = var.env == "live" ? "nowplaying.${var.root_domain}" : "nowplaying.${var.env}.${var.root_domain}"
domain_name = var.env == "live" ? "nowplaying.${var.root_domain}" : "nowplaying-staging.${var.root_domain}"

domain_name_configuration {
certificate_arn = aws_acm_certificate.cert.arn
Expand Down
21 changes: 7 additions & 14 deletions terraform/lambda/lambda.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
data "archive_file" "lambda_archive" {
type = "zip"
source_dir = "${path.module}/../../apps/lambda/dist"
output_path = "${path.module}/lambda.zip"
}

resource "aws_iam_role" "lambda_exec" {
name = "nowplaying-${var.env}-exec-role"
assume_role_policy = jsonencode({
Expand Down Expand Up @@ -42,14 +36,13 @@ resource "aws_iam_role_policy_attachment" "lambda_policy" {
}

resource "aws_lambda_function" "lambda" {
function_name = "api-gw-lambda-${var.env}"
runtime = "nodejs20.x"
handler = "index.handler"
role = aws_iam_role.lambda_exec.arn
filename = "${path.module}/lambda.zip"
source_code_hash = data.archive_file.lambda_archive.output_base64sha256
timeout = 30
memory_size = 128
function_name = "api-gw-lambda-${var.env}"
runtime = "nodejs20.x"
handler = "index.handler"
role = aws_iam_role.lambda_exec.arn
filename = "${path.module}/lambda.zip"
timeout = 30
memory_size = 128

environment {
variables = var.env_vars
Expand Down
2 changes: 1 addition & 1 deletion terraform/lambda/remote.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
data "terraform_remote_state" "vpc" {
backend = "s3"
workspace = var.env
workspace = "nowplaying-${var.env}"
config = {
bucket = var.env == "live" ? "nowplaying-live-terraform-state" : "nowplaying-staging-terraform-state"
key = var.env == "live" ? "vpc/live.tfstate" : "vpc/staging.tfstate"
Expand Down
15 changes: 15 additions & 0 deletions terraform/lambda/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,18 @@ variable "sub_domain" {
type = string
description = "The sub domain for the route53 record"
}

variable "private_key" {
type = string
description = "The private key for the certificate"
}

variable "certificate_body" {
type = string
description = "The certificate body for the certificate"
}

variable "certificate_chain" {
type = string
description = "The certificate chain for the certificate"
}
Loading