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

EASI-4671: Refactor configuration to build frontend for k8s as static content #2911

Merged
merged 15 commits into from
Dec 6, 2024
Merged
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
25 changes: 24 additions & 1 deletion .github/workflows/deploy_to_eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ jobs:
uses: aws-actions/amazon-ecr-login@v2
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set env vars with direnv # This allows docker build of FE files to pull from .envrc
uses: HatsuneMiku3939/direnv-action@v1
- name: Calculate build args
id: calculate-build-args
run: |
echo "VITE_LD_CLIENT_ID=${VITE_LD_CLIENT_ID}" >> $GITHUB_OUTPUT
echo "VITE_OKTA_CLIENT_ID=${VITE_OKTA_CLIENT_ID}" >> $GITHUB_OUTPUT
echo "VITE_OKTA_SERVER_ID=${VITE_OKTA_SERVER_ID}" >> $GITHUB_OUTPUT
echo "VITE_OKTA_ISSUER=${VITE_OKTA_ISSUER}" >> $GITHUB_OUTPUT
echo "VITE_OKTA_DOMAIN=${VITE_OKTA_DOMAIN}" >> $GITHUB_OUTPUT
echo "VITE_OKTA_REDIRECT_URI=${VITE_OKTA_REDIRECT_URI}" >> $GITHUB_OUTPUT
- name: Build, tag, and push image to Amazon ECR
uses: docker/build-push-action@v6
with:
Expand All @@ -44,6 +55,13 @@ jobs:
cache-to: type=gha,mode=max,scope=${{ env.GIT_REF_NAME }}-easi-frontend
cache-from: type=gha,scope=${{ env.GIT_REF_NAME }}-easi-frontend
tags: ${{ steps.login-ecr.outputs.registry }}/easi-frontend:${{ env.GIT_HASH }}
build-args: |
VITE_LD_CLIENT_ID=${{ steps.calculate-build-args.outputs.VITE_LD_CLIENT_ID }}
VITE_OKTA_CLIENT_ID=${{ steps.calculate-build-args.outputs.VITE_OKTA_CLIENT_ID }}
VITE_OKTA_SERVER_ID=${{ steps.calculate-build-args.outputs.VITE_OKTA_SERVER_ID }}
VITE_OKTA_ISSUER=${{ steps.calculate-build-args.outputs.VITE_OKTA_ISSUER }}
VITE_OKTA_DOMAIN=${{ steps.calculate-build-args.outputs.VITE_OKTA_DOMAIN }}
VITE_OKTA_REDIRECT_URI=${{ steps.calculate-build-args.outputs.VITE_OKTA_REDIRECT_URI }}
- name: Announce failure
if: ${{ failure() }}
run: |
Expand Down Expand Up @@ -74,4 +92,9 @@ jobs:
run: aws eks update-kubeconfig --name dev-easi-poc-cluster --region us-west-2
- name: Deploy to EKS
run: |
./scripts/deploy_eks_env.sh
. ./scripts/deploy_eks_env.sh
echo "# EKS Ingress URLs" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- [EASi](http://${EASI_INGRESS})" >> $GITHUB_STEP_SUMMARY
echo "- [Mailcatcher](http://${EMAIL_INGRESS})" >> $GITHUB_STEP_SUMMARY
echo "- [Minio Console](http://${MINIO_CONSOLE_INGRESS})" >> $GITHUB_STEP_SUMMARY
37 changes: 0 additions & 37 deletions Dockerfile.backend_k8s

This file was deleted.

36 changes: 35 additions & 1 deletion Dockerfile.frontend_k8s
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,38 @@ COPY tsconfig.json .eslintrc vite.config.ts apollo.config.js index.html ./
COPY public ./public
COPY src ./src

ENTRYPOINT [ "yarn", "start" ]
# Pass in from outside (.envrc)
ARG VITE_LD_CLIENT_ID
ARG VITE_OKTA_CLIENT_ID
ARG VITE_OKTA_SERVER_ID
ARG VITE_OKTA_ISSUER
ARG VITE_OKTA_DOMAIN
ARG VITE_OKTA_REDIRECT_URI

# Difficult (depend on k8s instantiation of ingress)
# ARG VITE_API_ADDRESS
# ARG VITE_GRAPHQL_ADDRESS

ENV VITE_OKTA_CLIENT_ID=${VITE_OKTA_CLIENT_ID} \
VITE_OKTA_SERVER_ID=${VITE_OKTA_SERVER_ID} \
VITE_LD_CLIENT_ID=${VITE_LD_CLIENT_ID} \
VITE_APP_ENV=local \
VITE_OKTA_ISSUER=${VITE_OKTA_ISSUER} \
# VITE_API_ADDRESS=${VITE_API_ADDRESS} \
# VITE_GRAPHQL_ADDRESS=${VITE_GRAPHQL_ADDRESS} \
VITE_LOCAL_AUTH_ENABLED=true \
VITE_OKTA_DOMAIN=${VITE_OKTA_DOMAIN} \
VITE_OKTA_REDIRECT_URI=${VITE_OKTA_REDIRECT_URI}

RUN yarn build

#
# Final layer to export just built HTML
#
FROM nginx:1.27.1-alpine

# Copy built files from yarn build layer
COPY --from=build /app/build /usr/share/nginx/html

# https://github.com/nginxinc/docker-nginx/blob/04d0c5754673d6880b91e94c3cebaa767d9a1af7/Dockerfile
ENTRYPOINT ["nginx", "-g", "daemon off;"]
2 changes: 1 addition & 1 deletion deploy/base/easi/easi-backend_deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ spec:
protocol: TCP
resources: {}
command:
- ./bin/easi
- /easi/easi
- serve
restartPolicy: Always
20 changes: 0 additions & 20 deletions deploy/base/easi/easi-frontend_configmap.yaml

This file was deleted.

5 changes: 1 addition & 4 deletions deploy/base/easi/easi-frontend_deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ spec:
- name: easi-frontend
image: easi-frontend:latest
imagePullPolicy: Never
envFrom:
- configMapRef:
name: easi-frontend-configmap
ports:
- containerPort: 3000
- containerPort: 80
protocol: TCP
resources: {}
restartPolicy: Always
4 changes: 2 additions & 2 deletions deploy/base/easi/easi-frontend_service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
name: easi-frontend
spec:
ports:
- port: 3000
targetPort: 3000
- port: 80
targetPort: 80
selector:
app: easi-frontend
1 change: 0 additions & 1 deletion deploy/base/easi/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ resources:
- easi-backend_configmap.yaml
- easi-backend_deployment.yaml
- easi-backend_service.yaml
- easi-frontend_configmap.yaml
- easi-frontend_deployment.yaml
- easi-frontend_service.yaml
- email_deployment.yaml
Expand Down
16 changes: 1 addition & 15 deletions deploy/base/ingress/easi_ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,11 @@ spec:
service:
name: easi-frontend
port:
number: 3000
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: easi-backend
port:
number: 8080
- path: /mail
pathType: Prefix
backend:
service:
name: email
port:
number: 1080
- path: /minio
pathType: Prefix
backend:
service:
name: minio
port:
number: 9001
4 changes: 0 additions & 4 deletions deploy/overlays/pr/easi/easi-backend_deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
path: /spec/template/spec/containers/0/imagePullPolicy
value: Always

- op: replace
path: /spec/template/spec/containers/0/command
value: ["/easi/easi", "serve"]

- op: replace
path: /spec/template/spec/containers/0/resources
value:
Expand Down
9 changes: 0 additions & 9 deletions deploy/overlays/pr/easi/easi-frontend_configmap.yaml

This file was deleted.

3 changes: 0 additions & 3 deletions deploy/overlays/pr/easi/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ patches:
- path: easi-backend_configmap.yaml
target:
name: easi-backend-configmap
- path: easi-frontend_configmap.yaml
target:
name: easi-frontend-configmap

# Patches for deployment changes
- path: easi-backend_deployment.yaml
Expand Down
17 changes: 1 addition & 16 deletions deploy/overlays/pr/ingress/easi_ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
value:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/healthcheck-path: /api/v1/healthcheck
- op: replace
path: /spec
value:
Expand All @@ -21,25 +20,11 @@
service:
name: easi-frontend
port:
number: 3000
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: easi-backend
port:
number: 8080
- path: /mail
pathType: Prefix
backend:
service:
name: email
port:
number: 1080
- path: /minio
pathType: Prefix
backend:
service:
name: minio
port:
number: 9001
32 changes: 20 additions & 12 deletions scripts/k8s_dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,30 @@ if kubectl get ns "$NAMESPACE" > /dev/null 2>&1; then
}
fi

APPLICATION_VERSION="$(git rev-parse @)"
APPLICATION_DATETIME="$(date --rfc-3339='seconds' --utc)"
APPLICATION_TS="$(date --date="$APPLICATION_DATETIME" '+%s')"

export APPLICATION_VERSION
export APPLICATION_DATETIME
export APPLICATION_TS

# Build Docker images
(
echo "🐋 Building easi-frontend:${NAMESPACE} image 🐋"
docker build -f ../Dockerfile.frontend_k8s -t easi-frontend:"$NAMESPACE" ../.

# APPLICATION_VERSION=$(git rev-parse HEAD)
# APPLICATION_DATETIME="$(date --rfc-3339='seconds' --utc)"
# APPLICATION_TS="$(date --date="$APPLICATION_DATETIME" '+%s')"
# echo "APPLICATION_DATETIME=${APPLICATION_DATETIME}"
# echo "APPLICATION_TS=${APPLICATION_TS}"
# echo "APPLICATION_VERSION=${APPLICATION_VERSION}"
docker build -f ../Dockerfile.frontend_k8s -t easi-frontend:"$NAMESPACE" ../. \
--build-arg VITE_LD_CLIENT_ID=63231d448bd05a111f06195b \
--build-arg VITE_OKTA_CLIENT_ID=0oa2e913coDQeG19S297 \
--build-arg VITE_OKTA_SERVER_ID=aus2e96etlbFPnBHt297 \
--build-arg VITE_OKTA_ISSUER=https://test.idp.idm.cms.gov/oauth2/aus2e96etlbFPnBHt297 \
--build-arg VITE_OKTA_DOMAIN=https://test.idp.idm.cms.gov \
--build-arg VITE_OKTA_REDIRECT_URI=http://localhost:3000/implicit/callback

echo "🐋 Building easi-backend:${NAMESPACE} image 🐋"
# docker build -f ../Dockerfile --build-arg APPLICATION_DATETIME="${APPLICATION_DATETIME}" --build-arg APPLICATION_TS="${APPLICATION_TS}" --build-arg APPLICATION_VERSION="${APPLICATION_VERSION}" -t easi-backend:latest ../.
docker build -f ../Dockerfile.backend_k8s --target build -t easi-backend:"$NAMESPACE" ../.
docker build -f ../Dockerfile -t easi-backend:"$NAMESPACE" ../. \
--build-arg APPLICATION_DATETIME="${APPLICATION_DATETIME}" \
--build-arg APPLICATION_TS="${APPLICATION_TS}" \
--build-arg APPLICATION_VERSION="${APPLICATION_VERSION}"

echo "🐋 Building db-migrate:${NAMESPACE} image 🐋"
docker build -f ../Dockerfile.db_migrations --build-arg TAG=9.10-alpine -t db-migrate:"$NAMESPACE" ../.
Expand Down Expand Up @@ -134,7 +143,6 @@ delete_temp_dir() {
kustomize edit set namespace "$NAMESPACE"
kustomize build > manifest.yaml

sed -i'' -E "s/easi-backend.localdev.me/${NAMESPACE}-backend.localdev.me/" manifest.yaml
sed -i'' -E "s/easi.localdev.me/${NAMESPACE}.localdev.me/" manifest.yaml
sed -i'' -E "s/email.localdev.me/${NAMESPACE}-email.localdev.me/" manifest.yaml
sed -i'' -E "s/minio.localdev.me/${NAMESPACE}-minio.localdev.me/" manifest.yaml
Expand All @@ -143,7 +151,7 @@ delete_temp_dir() {
)

(
TEMPDIR=$(mktemp -d ../tmp.ingress.XXXXX)
TEMPDIR=$(mktemp -d ../tmp.easi.XXXXX)
cd "$TEMPDIR" || exit
kustomize create --resources ../deploy/base/easi
kustomize edit set namespace "$NAMESPACE"
Expand Down
16 changes: 13 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import store from './store';

import './index.scss';

const apiHost = new URL(import.meta.env.VITE_API_ADDRESS || '').host;
const apiHost = new URL(
import.meta.env.VITE_API_ADDRESS || window.location.origin
).host;

// Initialize tracker for Google Analytics
ReactGA.initialize([
Expand Down Expand Up @@ -61,12 +63,20 @@ function getAuthHeader(targetUrl: string) {
/**
* Setup client for GraphQL
*/

// Pull the graphql address from the vite environment variables
// However, if we don't have a VITE_GRAPHQL_ADDRESS, we should simply assume that the API is hosted on the same domain & port as the frontend
// We also assume a path of /api/graph/query should be tacked onto that
const graphqlAddress =
import.meta.env.VITE_GRAPHQL_ADDRESS ||
`${window.location.origin}/api/graph/query`;

const uploadLink = createUploadLink({
uri: import.meta.env.VITE_GRAPHQL_ADDRESS
uri: graphqlAddress
});

const authLink = setContext((request, { headers }) => {
const header = getAuthHeader(import.meta.env.VITE_GRAPHQL_ADDRESS as string);
const header = getAuthHeader(graphqlAddress);
return {
headers: {
...headers,
Expand Down
10 changes: 7 additions & 3 deletions src/sagas/actionSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ import { call, put, StrictEffect, takeLatest } from 'redux-saga/effects';
import { Action } from 'types/action';
import { postAction } from 'types/routines';

// Pull the API address from the vite environment variables
// However, if we don't have a VITE_API_ADDRESS, we should simply assume that the API is hosted on the same domain & port as the frontend
// We also assume a path of /api/v1 should be tacked onto that
const apiAddress =
import.meta.env.VITE_API_ADDRESS || `${window.location.origin}/api/v1`;

export function postSystemIntakeActionRequest(formData: Action) {
return axios.post(
`${import.meta.env.VITE_API_ADDRESS}/system_intake/${
formData.intakeId
}/actions`,
`${apiAddress}/system_intake/${formData.intakeId}/actions`,
formData
);
}
Expand Down
Loading
Loading