Skip to content
This repository was archived by the owner on Dec 16, 2024. It is now read-only.

Commit d7d0547

Browse files
terraform (#983)
* terraform * format * config missing * fix env name * read namespace * temp env * use new tunnel hostname * remove cloudflare tunnel from deployment.tf * switch hosts * set default env --------- Co-authored-by: bread <[email protected]>
1 parent 8f33e96 commit d7d0547

File tree

13 files changed

+526
-56
lines changed

13 files changed

+526
-56
lines changed

.env.production

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
NODE_ENV=production
22
VITE_APP_TITLE="7TV"
33
VITE_APP_API_GQL="https://7tv.io/v3/gql"
4-
VITE_APP_API_GQL_WS="wss://7tv.io/v3/gql"
54
VITE_APP_API_EVENTS="wss://events.7tv.io/v3"
65
VITE_APP_API_REST="https://7tv.io/v3"
76
VITE_APP_API_EGVAULT="https://egvault.7tv.io"

.env.staging

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
NODE_ENV=production
22
VITE_APP_ENV=stage
33
VITE_APP_TITLE="7TV (Stage)"
4-
VITE_APP_API_GQL="https://stage.7tv.io/v3/gql"
5-
VITE_APP_API_GQL_WS="wss://stage.7tv.io/v3/gql"
6-
VITE_APP_API_EVENTS="wss://events.stage.7tv.io/v3"
7-
VITE_APP_API_REST="https://stage.7tv.io/v3"
8-
VITE_APP_API_EGVAULT="https://egvault.stage.7tv.io"
4+
VITE_APP_API_GQL="https://7tv.foo/v3/gql"
5+
VITE_APP_API_EVENTS="wss://events.7tv.foo/v3"
6+
VITE_APP_API_REST="https://7tv.foo/v3"
7+
VITE_APP_API_EGVAULT="https://egvault.7tv.foo"
98
VITE_APP_OLD="https://old.7tv.dev"
109
VITE_APP_FA_PRO=true
1110
VITE_APP_LOCALES=en_US,da_DK,de_DE,hu_HU,fr_FR,ko_KR,en_PT,pt_BR,es_ES,es_419,ru_RU,sv_SE

.github/workflows/ci.yaml

Lines changed: 143 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,26 @@ on:
1313
- labeled
1414
workflow_dispatch:
1515
inputs:
16-
deploy:
17-
description: "Deploy location"
18-
required: true
19-
default: "none"
20-
type: choice
21-
options:
22-
- production
23-
- staging
24-
- none
16+
deploy:
17+
description: "Which environment to deploy to"
18+
required: true
19+
default: "none"
20+
type: choice
21+
options:
22+
- prod
23+
- test
2524

2625
concurrency:
2726
group: ${{ github.workflow }}-${{ github.ref }}
2827
cancel-in-progress: true
2928

29+
env:
30+
DEPLOY: ${{ (inputs.deploy != 'none' && inputs.deploy) || ((github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'prod') || (github.event_name == 'push' && github.ref_type == 'branch' && github.ref_name == 'master') && 'prod') || ((github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'stage') || (github.event_name == 'push' && github.ref_type == 'branch' && github.ref_name == 'dev') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'staged')) && 'test') || 'none' }}
31+
3032
jobs:
3133
ci:
3234
name: Website Lint, Build, Test, Deploy
3335
runs-on: aws-runner
34-
env:
35-
DEPLOY_PROD: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'production') || (github.event_name == 'push' && github.ref_type == 'branch' && github.ref_name == 'master') }}
36-
DEPLOY_STAGE: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'staging') || (github.event_name == 'push' && github.ref_type == 'branch' && github.ref_name == 'dev') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'staged')) }}
3736
concurrency:
3837
group: ${{ github.workflow }}-ci-${{ github.ref }}
3938
cancel-in-progress: true
@@ -89,62 +88,158 @@ jobs:
8988
run: make lint
9089

9190
- name: Build App
92-
run: make ${{ (env.DEPLOY_PROD == 'true' && 'prod') || 'stage' }}
93-
94-
- name: Configure AWS credentials
95-
uses: aws-actions/configure-aws-credentials@v1
96-
if: ${{ env.DEPLOY_PROD == 'true' || env.DEPLOY_STAGE == 'true' }}
97-
with:
98-
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
99-
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
100-
aws-region: ${{ secrets.AWS_REGION }}
101-
102-
- name: Login to Amazon ECR
103-
id: login-ecr
104-
if: ${{ env.DEPLOY_PROD == 'true' || env.DEPLOY_STAGE == 'true' }}
105-
uses: aws-actions/amazon-ecr-login@v1
91+
run: make ${{ env.DEPLOY != 'none' && env.DEPLOY || 'stage' }}
10692

10793
- name: Make build context
108-
if: ${{ env.DEPLOY_PROD == 'true' || env.DEPLOY_STAGE == 'true' }}
94+
if: env.DEPLOY != 'none'
10995
run: |
11096
docker context create builders
11197
11298
- name: Setup buildx
11399
uses: docker/setup-buildx-action@v2
114-
if: ${{ env.DEPLOY_PROD == 'true' || env.DEPLOY_STAGE == 'true' }}
100+
if: env.DEPLOY != 'none'
115101
with:
116102
install: true
117103
endpoint: builders
118104

105+
- name: Login to GitHub Container Registry
106+
uses: docker/login-action@v2
107+
if: env.DEPLOY != 'none'
108+
with:
109+
registry: ghcr.io
110+
username: ${{ github.actor }}
111+
password: ${{ github.token }}
112+
119113
- name: Build docker image
120-
uses: docker/build-push-action@v3
121-
if: ${{ env.DEPLOY_PROD == 'true' || env.DEPLOY_STAGE == 'true' }}
114+
uses: docker/build-push-action@v4
115+
if: env.DEPLOY != 'none'
122116
with:
123117
context: .
124118
file: docker/partial.Dockerfile
125119
tags: |
126-
${{ steps.login-ecr.outputs.registry }}/${{ (env.DEPLOY_PROD == 'true' && '7tv') || '7tv-stage' }}/website:latest
127-
${{ steps.login-ecr.outputs.registry }}/${{ (env.DEPLOY_PROD == 'true' && '7tv') || '7tv-stage' }}/website:${{ github.sha }}
120+
ghcr.io/seventv/website:${{ env.DEPLOY }}-${{ github.sha }}
121+
ghcr.io/seventv/website:${{ env.DEPLOY }}-latest
128122
push: true
129123

130-
- name: Update deployment template
131-
uses: danielr1996/[email protected]
132-
if: ${{ env.DEPLOY_PROD == 'true' || env.DEPLOY_STAGE == 'true' }}
133-
env:
134-
IMAGE: ${{ steps.login-ecr.outputs.registry }}/${{ (env.DEPLOY_PROD == 'true' && '7tv') || '7tv-stage' }}/website:${{ github.sha }}
135-
with:
136-
input: k8s/${{ (env.DEPLOY_PROD == 'true' && 'production') || 'staging' }}.template.yaml
137-
output: k8s/deploy.yaml
124+
validate:
125+
name: API Deploy Validation
126+
needs: ci
127+
runs-on: ubuntu-latest
128+
permissions:
129+
pull-requests: write
130+
defaults:
131+
run:
132+
working-directory: ./terraform
138133

139-
- name: Setup Kubectl
140-
uses: azure/[email protected]
134+
steps:
135+
- name: Checkout code
136+
id: ok
137+
if: env.DEPLOY != 'none'
138+
uses: actions/checkout@v3
139+
140+
- name: "Setup Terraform"
141+
if: steps.ok.outcome == 'success'
142+
uses: hashicorp/setup-terraform@v1
143+
with:
144+
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
141145

142-
- name: Deploy to k8s
143-
if: ${{ env.DEPLOY_PROD == 'true' || env.DEPLOY_STAGE == 'true' }}
146+
- name: "Terraform Init"
147+
if: steps.ok.outcome == 'success'
148+
id: init
144149
env:
145-
KUBE_CONFIG_DATA: ${{ (env.DEPLOY_PROD == 'true' && secrets.KUBECONFIG) || secrets.KUBECONFIG_STAGE }}
150+
TF_WORKSPACE: ${{ env.DEPLOY }}
151+
run: terraform init
152+
continue-on-error: true
153+
154+
- name: "Terraform Workspace"
155+
if: steps.ok.outcome == 'success'
156+
run: terraform workspace select -or-create=true ${{ env.DEPLOY }}
157+
158+
- name: Terraform fmt
159+
if: steps.ok.outcome == 'success'
160+
id: fmt
161+
run: terraform fmt -check
162+
continue-on-error: true
163+
164+
- name: Terraform Validate
165+
if: steps.ok.outcome == 'success'
166+
id: validate
167+
run: terraform validate -no-color
168+
169+
- name: Terraform Variables
170+
if: steps.ok.outcome == 'success'
146171
run: |
147-
mkdir -p ~/.kube
148-
(echo $KUBE_CONFIG_DATA | base64 -d) >> ~/.kube/config
172+
cat <<EOF > *.auto.tfvars
173+
image_url="ghcr.io/seventv/website:${{ env.DEPLOY }}-${{ github.sha }}"
174+
image_pull_policy="IfNotPresent"
149175
150-
kubectl apply -f k8s/deploy.yaml
176+
EOF
177+
178+
- name: "Terraform Plan"
179+
if: steps.ok.outcome == 'success'
180+
id: plan
181+
run: terraform plan -no-color
182+
183+
- uses: actions/github-script@v6
184+
if: steps.ok.outcome == 'success' && github.event_name == 'pull_request'
185+
env:
186+
PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
187+
with:
188+
github-token: ${{ secrets.GITHUB_TOKEN }}
189+
script: |
190+
// 1. Retrieve existing bot comments for the PR
191+
const { data: comments } = await github.rest.issues.listComments({
192+
owner: context.repo.owner,
193+
repo: context.repo.repo,
194+
issue_number: context.issue.number,
195+
})
196+
const botComment = comments.find(comment => {
197+
return comment.user.type === 'Bot' && comment.body.includes('Terraform Format and Style')
198+
})
199+
200+
// 2. Prepare format of the comment
201+
const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
202+
#### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
203+
#### Terraform Validation 🤖\`${{ steps.validate.outcome }}\`
204+
<details><summary>Validation Output</summary>
205+
206+
\`\`\`\n
207+
${{ steps.validate.outputs.stdout }}
208+
\`\`\`
209+
210+
</details>
211+
212+
#### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
213+
214+
<details><summary>Show Plan</summary>
215+
216+
\`\`\`\n
217+
${process.env.PLAN}
218+
\`\`\`
219+
220+
</details>
221+
222+
*Actor: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Workflow: \`${{ github.workflow }}\`*`;
223+
224+
// 3. If we have a comment, update it, otherwise create a new one
225+
if (botComment) {
226+
github.rest.issues.updateComment({
227+
owner: context.repo.owner,
228+
repo: context.repo.repo,
229+
comment_id: botComment.id,
230+
body: output
231+
})
232+
} else {
233+
github.rest.issues.createComment({
234+
issue_number: context.issue.number,
235+
owner: context.repo.owner,
236+
repo: context.repo.repo,
237+
body: output
238+
})
239+
}
240+
241+
- name: "Terraform Apply"
242+
if: steps.ok.outcome == 'success'
243+
id: apply
244+
run: terraform apply -no-color -auto-approve
245+
continue-on-error: true

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,17 @@ sw.*
9292

9393
/server/out
9494
stats.html
95+
96+
# Terraform local state files
97+
**/.terraform/*
98+
*.tfstate
99+
*.tfstate.*
100+
*.tfplan
101+
crash.log
102+
*.tfvars
103+
override.tf
104+
override.tf.json
105+
*_override.tf
106+
*_override.tf.json
107+
.terraformrc
108+
terraform.rc

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
"editor.formatOnSave": true,
33
"javascript.preferences.importModuleSpecifier": "project-relative",
44
"javascript.preferences.quoteStyle": "double",
5-
"editor.defaultFormatter": "esbenp.prettier-vscode"
5+
"editor.defaultFormatter": "esbenp.prettier-vscode",
6+
"[terraform]": {
7+
"editor.defaultFormatter": "hashicorp.terraform"
8+
}
69
}

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,9 @@ deps:
2525
dev_deps:
2626
yarn
2727
$(MAKE) -C server dev_deps
28+
29+
terraform:
30+
terraform -chdir=./terraform init
31+
32+
deploy:
33+
terraform -chdir=./terraform apply -auto-approve

docker/full.Dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
FROM node:18 as node-builder
22
WORKDIR /tmp/build
3+
ARG FA_TOKEN="<none>"
4+
ENV FA_TOKEN=${FA_TOKEN}
35

46
COPY package.json .
57
COPY yarn.lock .
68

9+
RUN npm config set "@fortawesome:registry" https://npm.fontawesome.com/
10+
RUN npm config set '//npm.fontawesome.com/:_authToken' $(echo ${FA_TOKEN})
11+
712
RUN yarn && apt-get update && \
813
apt-get install -y \
914
make && \
@@ -12,7 +17,6 @@ FROM node:18 as node-builder
1217
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
1318

1419
COPY . .
15-
1620
ARG MODE=production
1721

1822
RUN make ${MODE}

terraform/.terraform.lock.hcl

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

terraform/config.template.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
GQL_API_URL: ${gql_api_url}
2+
WEBSITE_URL: ${website_url}
3+
WEBSITE_BIND: "0.0.0.0:3000"

0 commit comments

Comments
 (0)