Skip to content

Commit

Permalink
[EASI-4129] nginx CEDAR Caching (#2545)
Browse files Browse the repository at this point in the history
* implement local nginx cache strategy in docker compose with system roles purge example

* EASI-4129: dockerfile improvements

* nil deref and merge main

* EASI-4129: init cedarproxy k8s manifests

* EASI-4129: lint oops

* clean up caching helpers, remove old cache code, purge my systems cache

* add config var to allow using okta API locally

* add build action for cedarproxy

* fix build image workflow filter

* fix build image workflow context

* increase cache valid time to 24h

* add deploy pipeline for cedarproxy dev

* update step name

* EASI-4129: call correct script

* cache size is not cache time

* mention proxy within CEDAR docs

* remove memcache code, add proxy URL env var

* go.mod change for go-cache

* add once protection for client

* add comments

---------

Co-authored-by: Justin Woodson <jdwoodson@gmail.com>
  • Loading branch information
mynar7 and Jdwoodson committed May 9, 2024
1 parent a355d6c commit f758bb0
Show file tree
Hide file tree
Showing 23 changed files with 409 additions and 178 deletions.
9 changes: 5 additions & 4 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export OKTA_API_TOKEN=
export OKTA_TEST_USERNAME=
export OKTA_TEST_PASSWORD=
export OKTA_TEST_SECRET=
# Use OKTA when doing local dev
export USE_OKTA_LOCAL=false


# Launch Darkly configuration
export FLAG_SOURCE=LOCAL # LAUNCH_DARKLY, LOCAL, or FILE
Expand Down Expand Up @@ -106,9 +109,10 @@ PATH_add ./bin
# CEDAR
export CEDAR_CORE_MOCK=true
export CEDAR_INTAKE_ENABLED=false
# for CEDAR core caching
export CEDAR_PROXY_URL=""
export CEDAR_API_URL="webmethods-apigw.cedarimpl.cms.gov"
export CEDAR_API_KEY=""
export CEDAR_CACHE_INTERVAL="30m"
export CEDAR_CORE_API_VERSION="2.0.0"
export CEDAR_EMAIL_ADDRESS="EnterpriseArchitecture@notCMS.gov"

Expand All @@ -123,9 +127,6 @@ export AIR_CONFIG_DEBUG_WAIT="-c .airDebugWait.conf"
# Fix job codes when sending email locally
export ALT_JOB_CODES=true




# Load a local overrides file. Any changes you want to make for your local
# environment should live in that file.

Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/build_application_images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,47 @@ jobs:
if: ${{ failure() }}
run: |
./scripts/github-action-announce-broken-branch
build_cedarproxy_image:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Check for changes to cedarproxy folder
uses: dorny/paths-filter@v3
id: changes
with:
filters: |
cedarproxy:
- 'cedarproxy/**'
- name: Login to Docker Hub
uses: docker/login-action@v3
if: steps.changes.outputs.cedarproxy == 'true'
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Configure AWS credentials
if: steps.changes.outputs.cedarproxy == 'true'
uses: aws-actions/configure-aws-credentials@v4.0.2
with:
role-to-assume: ${{ secrets.AWS_INFRA_OIDC_ROLE_TO_ASSUME }}
aws-region: us-west-2
- name: Login to Amazon ECR
if: steps.changes.outputs.cedarproxy == 'true'
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Setup Docker Buildx
if: steps.changes.outputs.cedarproxy == 'true'
uses: docker/setup-buildx-action@v3
- name: Build, tag, and push image to Amazon ECR
if: steps.changes.outputs.cedarproxy == 'true'
uses: docker/build-push-action@v5
with:
context: ./cedarproxy/
file: ./cedarproxy/Dockerfile.cedarproxy
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/easi-cedarproxy:${{ env.GIT_HASH }}
- name: Announce failure
if: ${{ failure() }}
run: |
./scripts/github-action-announce-broken-branch
42 changes: 40 additions & 2 deletions .github/workflows/deploy_to_environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,44 @@ jobs:
run: |
echo "Deploy confirmed! 🚀"
deploy_cedar_proxy:
runs-on: ubuntu-latest
needs: confirm_deploy
environment: ${{ inputs.env }}
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.0.2
with:
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_TO_ASSUME }}
aws-region: us-west-2
- name: Check for changes to cedarproxy folder
uses: dorny/paths-filter@v3
id: changes
with:
filters: |
cedarproxy:
- 'pkg/cedar/core/gen/**'
- 'cedarproxy/**'
- name: Update ECS task definition and deploy Cedarproxy
if: ${{ contains(inputs.env, 'dev') && steps.changes.outputs.cedarproxy == 'true' }}
env:
ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }}
ECR_REPOSITORY: easi-cedarproxy
NEW_IMAGE_TAG: ${{ env.GIT_HASH }}
TASK_FAMILY: "easi-cedarproxy-${{ inputs.env }}"
ECS_CLUSTER: "${{ inputs.env }}-easi-app"
SERVICE_NAME: easi-cedarproxy
SECURITY_GROUP_NAME: "ecs-easi-cedarproxy-${{ inputs.env }}"
run: |
export TASK_REVISION=$(./scripts/update_ecs_task_definition.sh)
./scripts/deploy_ecs_service.sh
- name: Announce failure
if: ${{ failure() }}
run: |
./scripts/github-action-announce-broken-branch
database_actions:
runs-on: ubuntu-latest
needs: confirm_deploy
Expand All @@ -42,7 +80,7 @@ jobs:
uses: aws-actions/configure-aws-credentials@v4.0.2
with:
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_TO_ASSUME }}
aws-region: us-west-2
aws-region: us-west-2
- name: Clean the database
if: ${{ contains(inputs.env, 'dev') && vars.ENABLE_DEV_DB_CLEAN == '1' }}
env:
Expand Down Expand Up @@ -110,7 +148,7 @@ jobs:
if: ${{ failure() }}
run: |
./scripts/github-action-announce-broken-branch
deploy_frontend:
needs: [database_actions]
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ repos:
language: node
additional_dependencies: [dockerfilelint]
files: Dockerfile.*
exclude: Dockerfile.cedarproxy

- repo: local
hooks:
Expand Down
70 changes: 70 additions & 0 deletions cedarproxy/Dockerfile.cedarproxy
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
FROM nginx:mainline as builder

ARG ENABLED_MODULES=cachepurge

SHELL ["/bin/bash", "-exo", "pipefail", "-c"]

RUN if [ "$ENABLED_MODULES" = "" ]; then \
echo "No additional modules enabled, exiting"; \
exit 1; \
fi

COPY ./modules/ /modules/

RUN apt-get update \
&& apt-get install -y --no-install-suggests --no-install-recommends \
patch make wget mercurial devscripts debhelper dpkg-dev \
quilt lsb-release build-essential \
&& hg clone -r ${NGINX_VERSION}-${PKG_RELEASE%%~*} https://hg.nginx.org/pkg-oss/ \
&& cd pkg-oss \
&& mkdir /tmp/packages \
&& for module in $ENABLED_MODULES; do \
echo "Building $module for nginx-$NGINX_VERSION"; \
if [ -d /modules/$module ]; then \
echo "Building $module from user-supplied sources"; \
# check if module sources file is there and not empty
if [ ! -s /modules/$module/source ]; then \
echo "No source file for $module in modules/$module/source, exiting"; \
exit 1; \
fi; \
# some modules require build dependencies
if [ -f /modules/$module/build-deps ]; then \
echo "Installing $module build dependencies"; \
apt-get update && apt-get install -y --no-install-suggests --no-install-recommends $(cat /modules/$module/build-deps | xargs); \
fi; \
# if a module has a build dependency that is not in a distro, provide a
# shell script to fetch/build/install those
# note that shared libraries produced as a result of this script will
# not be copied from the builder image to the main one so build static
if [ -x /modules/$module/prebuild ]; then \
echo "Running prebuild script for $module"; \
/modules/$module/prebuild; \
fi; \
/pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \
BUILT_MODULES="$BUILT_MODULES $(echo $module | tr '[A-Z]' '[a-z]' | tr -d '[/_\-\.\t ]')"; \
elif make -C /pkg-oss/debian list | grep -P "^$module\s+\d" > /dev/null; then \
echo "Building $module from pkg-oss sources"; \
cd /pkg-oss/debian; \
make rules-module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \
mk-build-deps --install --tool="apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes" debuild-module-$module/nginx-$NGINX_VERSION/debian/control; \
make module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \
find ../../ -maxdepth 1 -mindepth 1 -type f -name "*.deb" -exec mv -v {} /tmp/packages/ \;; \
BUILT_MODULES="$BUILT_MODULES $module"; \
else \
echo "Don't know how to build $module module, exiting"; \
exit 1; \
fi; \
done \
&& echo "BUILT_MODULES=\"$BUILT_MODULES\"" > /tmp/packages/modules.env \
&& rm -rf /var/lib/apt/lists/*

FROM nginx:mainline
ENV NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx
COPY ./nginx.conf /etc/nginx/templates/nginx.conf.template
RUN --mount=type=bind,target=/tmp/packages/,source=/tmp/packages/,from=builder \
apt-get update \
&& . /tmp/packages/modules.env \
&& for module in $BUILT_MODULES; do \
apt-get install --no-install-suggests --no-install-recommends -y /tmp/packages/nginx-module-${module}_${NGINX_VERSION}*.deb; \
done \
&& rm -rf /var/lib/apt/lists/*
1 change: 1 addition & 0 deletions cedarproxy/modules/cachepurge/source
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz
56 changes: 56 additions & 0 deletions cedarproxy/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# load_module modules/ngx_cache_purge_module.so;
load_module modules/ngx_http_cache_purge_module.so;

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;


events {
worker_connections 1024;
}


http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

# include /etc/nginx/conf.d/*.conf;

proxy_cache_path /nginxcache keys_zone=cedarcorecache:10m;
proxy_cache_valid 200 302 24h;

server {
listen 8001;

server_name cedarproxy;

location / {
proxy_pass https://${CEDAR_API_URL}/;
proxy_pass_request_headers on;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_cache cedarcorecache;
proxy_cache_key $uri$is_args$args;
proxy_cache_purge PURGE from all;
}
}
}
48 changes: 48 additions & 0 deletions deploy/base/cedarproxy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: cedarproxy-configmap
namespace: easi
data:
CEDAR_API_URL: webmethods-apigw.cedarimpl.cms.gov

---

apiVersion: apps/v1
kind: Deployment
metadata:
name: cedarproxy
namespace: easi
spec:
selector:
matchLabels:
app: cedarproxy
template:
metadata:
labels:
app: cedarproxy
spec:
containers:
- name: cedarproxy
image: cedarproxy:latest
imagePullPolicy: Never
envFrom:
- configMapRef:
name: cedarproxy-configmap
resources: {}
ports:
- containerPort: 8001

---

apiVersion: v1
kind: Service
metadata:
name: cedarproxy
namespace: easi
spec:
selector:
app: cedarproxy
ports:
- port: 8001
targetPort: 8001
3 changes: 2 additions & 1 deletion deploy/base/easi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ data:
CEDAR_CORE_MOCK: 'true'
CEDAR_INTAKE_ENABLED: 'false'
CEDAR_API_KEY: ''
CEDAR_API_URL: "webmethods-apigw.cedardev.cms.gov"
CEDAR_PROXY_URL: ""
CEDAR_API_URL: "webmethods-apigw.cedarimpl.cms.gov"
CEDAR_CORE_API_VERSION: "2.0.0"
CEDAR_CACHE_INTERVAL: "30m"
CEDAR_EMAIL_ADDRESS: "EnterpriseArchitecture@notCMS.gov"
Expand Down
1 change: 1 addition & 0 deletions deploy/base/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ resources:
- minio.yaml
- easi-client.yaml
- easi.yaml
- cedarproxy.yaml
9 changes: 9 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ services:
- CEDAR_INTAKE_ENABLED
- CEDAR_API_KEY
- CEDAR_API_URL
- CEDAR_PROXY_URL=cedarproxy:8001
- CEDAR_CORE_API_VERSION
- CEDAR_CACHE_INTERVAL
- CEDAR_EMAIL_ADDRESS
Expand Down Expand Up @@ -70,9 +71,17 @@ services:
- ALT_JOB_CODES
- OKTA_API_URL
- OKTA_API_TOKEN
- USE_OKTA_LOCAL
depends_on:
db_migrate:
condition: service_completed_successfully # Only start if migrations completed successfully
cedarproxy:
image: cedarproxy:latest
environment:
- CEDAR_API_URL
build:
dockerfile: Dockerfile.cedarproxy
context: ./cedarproxy/
easi_client:
image: easi_client:latest
minio:
Expand Down
Loading

0 comments on commit f758bb0

Please sign in to comment.