Skip to content

Commit b5761b3

Browse files
authored
Move deployment config to repo and add QA environment (#744)
1 parent 83b80af commit b5761b3

18 files changed

+1393
-14
lines changed

.env.example

-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,2 @@
11
DATABASE_URL=postgresql://postgres@db/disclosure-checker
22
SESSION_EXPIRES_IN_MINUTES=60
3-
4-
# Uncomment this line to enable http credentials site-wise.
5-
# HTTP_AUTH_ENABLED=1
6-
7-
# Following are the credentials, also used in the back office.
8-
# Even if the `HTTP_AUTH_ENABLED` is disabled, the back office still will use them.
9-
HTTP_AUTH_USER=test
10-
HTTP_AUTH_PASSWORD=test

.github/workflows/deploy.yml

+87-6
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,13 @@ jobs:
5555
5656
- name: Push to ECR
5757
run: |
58-
docker tag ${{ vars.ECR_URL }}:$SHA ${{ vars.ECR_URL }}:staging.latest
59-
docker tag ${{ vars.ECR_URL }}:$SHA ${{ vars.ECR_URL }}:production.latest
58+
docker tag ${{ vars.ECR_URL }}:$SHA
6059
docker push ${{ vars.ECR_URL }}:$SHA
61-
docker push ${{ vars.ECR_URL }}:staging.latest
62-
docker push ${{ vars.ECR_URL }}:production.latest
6360
6461
deploy-staging:
6562
runs-on: ubuntu-latest
6663
needs: build
64+
environment: staging
6765

6866
env:
6967
KUBE_NAMESPACE: ${{ secrets.KUBE_NAMESPACE }}
@@ -80,6 +78,11 @@ jobs:
8078
build_tag=$PREFIX-$branch-$short_sha
8179
echo "build_tag=$build_tag" >> $GITHUB_OUTPUT
8280
81+
- name: Tag build and push to ECR
82+
run: |
83+
docker tag ${{ vars.ECR_URL }}:$SHA ${{ vars.ECR_URL }}:staging.latest
84+
docker push ${{ vars.ECR_URL }}:staging.latest
85+
8386
- name: Authenticate to the cluster
8487
env:
8588
KUBE_CERT: ${{ secrets.KUBE_CERT }}
@@ -95,7 +98,7 @@ jobs:
9598
- name: Rollout restart deployment
9699
run: |
97100
kubectl set image -n ${KUBE_NAMESPACE} \
98-
deployment/disclosure-checker-deployment-staging \
101+
config/kubernetes/staging \
99102
webapp="${{ vars.ECR_URL }}:$SHA"
100103
101104
- name: Send deploy notification to product Slack channel
@@ -128,6 +131,79 @@ jobs:
128131
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
129132
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
130133

134+
deploy-qa:
135+
runs-on: ubuntu-latest
136+
needs: build
137+
environment: qa
138+
139+
env:
140+
KUBE_NAMESPACE: ${{ secrets.KUBE_NAMESPACE }}
141+
142+
steps:
143+
- name: Checkout
144+
uses: actions/checkout@v4
145+
146+
- name: Store build tag
147+
id: vars
148+
run: |
149+
branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}
150+
short_sha=$(git rev-parse --short $SHA)
151+
build_tag=$PREFIX-$branch-$short_sha
152+
echo "build_tag=$build_tag" >> $GITHUB_OUTPUT
153+
154+
- name: Tag build and push to ECR
155+
run: |
156+
docker tag ${{ vars.ECR_URL }}:$SHA ${{ vars.ECR_URL }}:qa.latest
157+
docker push ${{ vars.ECR_URL }}:qa.latest
158+
159+
- name: Authenticate to the cluster
160+
env:
161+
KUBE_CERT: ${{ secrets.KUBE_CERT }}
162+
KUBE_TOKEN: ${{ secrets.KUBE_TOKEN }}
163+
KUBE_CLUSTER: ${{ secrets.KUBE_CLUSTER }}
164+
run: |
165+
echo "${KUBE_CERT}" > ca.crt
166+
kubectl config set-cluster ${KUBE_CLUSTER} --certificate-authority=./ca.crt --server=https://${KUBE_CLUSTER}
167+
kubectl config set-credentials deploy-user --token=${KUBE_TOKEN}
168+
kubectl config set-context ${KUBE_CLUSTER} --cluster=${KUBE_CLUSTER} --user=deploy-user --namespace=${KUBE_NAMESPACE}
169+
kubectl config use-context ${KUBE_CLUSTER}
170+
171+
- name: Rollout restart deployment
172+
run: |
173+
kubectl set image -n ${KUBE_NAMESPACE} \
174+
config/kubernetes/qa \
175+
webapp="${{ vars.ECR_URL }}:$SHA"
176+
177+
- name: Send deploy notification to product Slack channel
178+
uses: slackapi/slack-github-action@v1.25.0
179+
with:
180+
payload: |
181+
{
182+
"attachments": [
183+
{
184+
"color": "#1d990c",
185+
"text": "${{ github.actor }} deployed *${{ steps.vars.outputs.build_tag }}* to *QA*",
186+
"fields": [
187+
{
188+
"title": "Project",
189+
"value": "Disclosure Checker",
190+
"short": true
191+
}
192+
],
193+
"actions": [
194+
{
195+
"text": "Visit Job",
196+
"type": "button",
197+
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
198+
}
199+
]
200+
}
201+
]
202+
}
203+
env:
204+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
205+
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
206+
131207
deploy-production:
132208
runs-on: ubuntu-latest
133209
needs: deploy-staging
@@ -149,6 +225,11 @@ jobs:
149225
build_tag=$PREFIX-$branch-$short_sha
150226
echo "build_tag=$build_tag" >> $GITHUB_OUTPUT
151227
228+
- name: Tag build and push to ECR
229+
run: |
230+
docker tag ${{ vars.ECR_URL }}:$SHA ${{ vars.ECR_URL }}:production.latest
231+
docker push ${{ vars.ECR_URL }}:production.latest
232+
152233
- name: Authenticate to the cluster
153234
env:
154235
KUBE_CERT: ${{ secrets.KUBE_PROD_CERT }}
@@ -164,7 +245,7 @@ jobs:
164245
- name: Rollout restart deployment
165246
run: |
166247
kubectl set image -n ${KUBE_NAMESPACE} \
167-
deployment/disclosure-checker-deployment-production \
248+
config/kubernetes/production \
168249
webapp="${{ vars.ECR_URL }}:$SHA"
169250
170251
- name: Send deploy notification to product Slack channel
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: disclosure-checker-configmap-production
5+
namespace: disclosure-checker-production
6+
data:
7+
EXTERNAL_URL: https://check-when-to-disclose-caution-conviction.service.gov.uk
8+
RACK_ENV: production
9+
RAILS_ENV: production
10+
RAILS_MAX_THREADS: "3"
11+
RAILS_SERVE_STATIC_FILES: enabled
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
apiVersion: batch/v1
2+
kind: CronJob
3+
metadata:
4+
name: disclosure-checker-cronjob-production
5+
namespace: disclosure-checker-production
6+
spec:
7+
schedule: "0 3 * * *"
8+
concurrencyPolicy: Forbid
9+
startingDeadlineSeconds: 300
10+
jobTemplate:
11+
spec:
12+
ttlSecondsAfterFinished: 86400 # 24 hours
13+
backoffLimit: 3
14+
template:
15+
metadata:
16+
labels:
17+
tier: worker
18+
spec:
19+
restartPolicy: Never
20+
containers:
21+
- name: cronjob-daily-tasks
22+
image: 754256621582.dkr.ecr.eu-west-2.amazonaws.com/family-justice/disclosure-checker:production.latest
23+
imagePullPolicy: Always
24+
command: ['bin/rails', 'daily_tasks']
25+
# non-secret env vars defined in `config_map.yaml`
26+
envFrom:
27+
- configMapRef:
28+
name: disclosure-checker-configmap-production
29+
env:
30+
# external secrets defined in `secrets.yml`
31+
- name: SECRET_KEY_BASE
32+
valueFrom:
33+
secretKeyRef:
34+
name: disclosure-checker-secrets-production
35+
key: secret_key_base
36+
- name: SENTRY_DSN
37+
valueFrom:
38+
secretKeyRef:
39+
name: disclosure-checker-secrets-production
40+
key: sentry_dsn
41+
#
42+
# secrets created by `terraform`
43+
#
44+
- name: DATABASE_URL
45+
valueFrom:
46+
secretKeyRef:
47+
name: rds-instance-disclosure-checker-production
48+
key: url
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: disclosure-checker-deployment-production
5+
namespace: disclosure-checker-production
6+
spec:
7+
replicas: 2
8+
revisionHistoryLimit: 5
9+
strategy:
10+
type: RollingUpdate
11+
rollingUpdate:
12+
maxUnavailable: 0
13+
maxSurge: 100%
14+
selector:
15+
matchLabels:
16+
app: disclosure-checker-web-production
17+
template:
18+
metadata:
19+
labels:
20+
app: disclosure-checker-web-production
21+
tier: frontend
22+
spec:
23+
containers:
24+
- name: webapp
25+
image: 754256621582.dkr.ecr.eu-west-2.amazonaws.com/family-justice/disclosure-checker:production.latest
26+
imagePullPolicy: Always
27+
ports:
28+
- containerPort: 3000
29+
resources:
30+
requests:
31+
cpu: 125m
32+
memory: 500Mi
33+
limits:
34+
cpu: 250m
35+
memory: 1Gi
36+
readinessProbe:
37+
httpGet:
38+
path: /ping.json
39+
port: 3000
40+
httpHeaders:
41+
- name: X-Forwarded-Proto
42+
value: https
43+
- name: X-Forwarded-Ssl
44+
value: "on"
45+
initialDelaySeconds: 15
46+
periodSeconds: 10
47+
livenessProbe:
48+
httpGet:
49+
path: /ping.json
50+
port: 3000
51+
httpHeaders:
52+
- name: X-Forwarded-Proto
53+
value: https
54+
- name: X-Forwarded-Ssl
55+
value: "on"
56+
initialDelaySeconds: 30
57+
periodSeconds: 10
58+
# non-secret env vars defined in `config_map.yaml`
59+
envFrom:
60+
- configMapRef:
61+
name: disclosure-checker-configmap-production
62+
env:
63+
# external secrets defined in `secrets.yml`
64+
- name: SECRET_KEY_BASE
65+
valueFrom:
66+
secretKeyRef:
67+
name: disclosure-checker-secrets-production
68+
key: secret_key_base
69+
- name: SENTRY_DSN
70+
valueFrom:
71+
secretKeyRef:
72+
name: disclosure-checker-secrets-production
73+
key: sentry_dsn
74+
#
75+
# secrets created by `terraform`
76+
#
77+
- name: DATABASE_URL
78+
valueFrom:
79+
secretKeyRef:
80+
name: rds-instance-disclosure-checker-production
81+
key: url
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
apiVersion: networking.k8s.io/v1
2+
kind: Ingress
3+
metadata:
4+
name: disclosure-checker-ingress-production
5+
namespace: disclosure-checker-production
6+
annotations:
7+
external-dns.alpha.kubernetes.io/set-identifier: disclosure-checker-ingress-production-disclosure-checker-production-green
8+
external-dns.alpha.kubernetes.io/aws-weight: "100"
9+
nginx.ingress.kubernetes.io/server-snippet: |
10+
location ~* \.(php|cgi|xml)$ {
11+
deny all; access_log off;
12+
}
13+
if ($host ~* .justice.gov.uk$) {
14+
return 301 https://check-when-to-disclose-caution-conviction.service.gov.uk$request_uri;
15+
}
16+
location = /.well-known/security.txt {
17+
return 301 https://raw.githubusercontent.com/ministryofjustice/security-guidance/main/contact/vulnerability-disclosure-security.txt;
18+
}
19+
spec:
20+
ingressClassName: default
21+
tls:
22+
- hosts:
23+
- disclosure-checker-production.apps.live.cloud-platform.service.justice.gov.uk
24+
- hosts:
25+
- check-when-to-disclose-caution-conviction.service.justice.gov.uk
26+
secretName: disclosure-checker-tls-certificate
27+
- hosts:
28+
- check-when-to-disclose-caution-conviction.service.gov.uk
29+
secretName: disclosure-checker-tls-certificate-gds
30+
rules:
31+
- host: disclosure-checker-production.apps.live.cloud-platform.service.justice.gov.uk
32+
http:
33+
paths:
34+
- path: /
35+
pathType: Prefix
36+
backend:
37+
service:
38+
name: disclosure-checker-service-production
39+
port:
40+
number: 80
41+
- host: check-when-to-disclose-caution-conviction.service.justice.gov.uk
42+
http:
43+
paths:
44+
- path: /
45+
pathType: Prefix
46+
backend:
47+
service:
48+
name: disclosure-checker-service-production
49+
port:
50+
number: 80
51+
- host: check-when-to-disclose-caution-conviction.service.gov.uk
52+
http:
53+
paths:
54+
- path: /
55+
pathType: Prefix
56+
backend:
57+
service:
58+
name: disclosure-checker-service-production
59+
port:
60+
number: 80
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: disclosure-checker-service-production
5+
namespace: disclosure-checker-production
6+
labels:
7+
app: disclosure-checker-web-production
8+
spec:
9+
ports:
10+
- port: 80
11+
name: http
12+
targetPort: 3000
13+
selector:
14+
app: disclosure-checker-web-production

config/kubernetes/qa/config_map.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: disclosure-checker-configmap-qa
5+
namespace: disclosure-checker-qa
6+
data:
7+
DEV_TOOLS_ENABLED: "1"
8+
EXTERNAL_URL: https://disclosure-checker-qa.apps.live.cloud-platform.service.justice.gov.uk
9+
RACK_ENV: production
10+
RAILS_ENV: production
11+
RAILS_MAX_THREADS: "3"
12+
RAILS_SERVE_STATIC_FILES: enabled

0 commit comments

Comments
 (0)