Skip to content

Commit 305156f

Browse files
committed
starterpack
0 parents  commit 305156f

21 files changed

+9111
-0
lines changed

.babelrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["@babel/preset-env", "@babel/preset-react"]
3+
}

.githooks/pre-commit

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh
2+
#
3+
# An example hook script to verify what is about to be committed.
4+
# Called by "git commit" with no arguments. The hook should
5+
# exit with non-zero status after issuing an appropriate message if
6+
# it wants to stop the commit.
7+
#
8+
LIST=$( git diff --name-only --cached --diff-filter=ACM -- *.{yml,yaml} )
9+
10+
if [ -n "$LIST" ]; then
11+
node_modules/yaml-lint/cli.js $LIST
12+
fi

.github/workflows/build-lambda.yml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Zip js to bucket x.y.z/src.zip from tag 'lambda-x.y.z'
2+
3+
on:
4+
push:
5+
tags:
6+
- lambda-*
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- name: Zip src-lambda-folder
14+
run: zip -rj src.zip src-lambda/
15+
- name: Get build version from tag
16+
id: release
17+
run: echo ::set-output name=tag::${GITHUB_REF:17}
18+
outputs:
19+
tag:
20+
description: 'The semantic version postfixing lambda- in the tagname'
21+
- name: Configure AWS credentials
22+
uses: aws-actions/configure-aws-credentials@v1
23+
with:
24+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
25+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
26+
aws-region: eu-north-1
27+
- name: Upload archive to lambda-src-bucket
28+
run: >-
29+
aws s3 cp src.zip <target>

.github/workflows/nodejs0.yml

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Starterpack - Build and upload assets and index
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- name: Use Node.js 12.x
14+
uses: actions/setup-node@v1
15+
with:
16+
node-version: '12.x'
17+
- run: npm ci
18+
- run: npm run build
19+
- uses: actions/upload-artifact@v1
20+
with:
21+
name: build-${{github.sha}}
22+
path: build/
23+
24+
upload-assets:
25+
needs: build
26+
runs-on: ubuntu-latest
27+
steps:
28+
- name: Download build from previous step
29+
uses: actions/download-artifact@v1
30+
with:
31+
name: build-${{github.sha}}
32+
- name: Echo build files
33+
run: >-
34+
ls build-${{github.sha}}
35+
- name: Configure AWS credentials
36+
uses: aws-actions/configure-aws-credentials@v1
37+
with:
38+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
39+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
40+
aws-region: eu-north-1
41+
42+
upload-index:
43+
needs: upload-assets
44+
runs-on: ubuntu-latest
45+
steps:
46+
- uses: actions/checkout@v2
47+
- name: Use Node.js 12.x
48+
uses: actions/setup-node@v1
49+
with:
50+
node-version: '12.x'
51+
- name: Build index
52+
run: >-
53+
node src-index/main.js
54+
- name: Show index
55+
run: >-
56+
cat index.html
57+
- name: Configure AWS credentials
58+
uses: aws-actions/configure-aws-credentials@v1
59+
with:
60+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
61+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
62+
aws-region: eu-north-1
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Deploy version to production
2+
3+
on:
4+
push:
5+
tags:
6+
- '[0-9]+.[0-9]+.[0-9]+'
7+
8+
jobs:
9+
upload:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Configure AWS credentials
13+
uses: aws-actions/configure-aws-credentials@v1
14+
with:
15+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
16+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
17+
aws-region: eu-north-1
18+
- name: Trigger lambda for build of index.html from AWS CLI
19+
run: >-
20+
aws lambda invoke
21+
--function-name <function_name>
22+
--payload '{ "sha": "${{github.sha}}" }'
23+
response.json

.gitignore

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
node_modules/
2+
build/
3+
.DS_Store
4+
index.html
5+
6+
7+
# Terraform
8+
**/.terraform/*
9+
10+
# .tfstate files
11+
*.tfstate
12+
*.tfstate.*
13+
14+
# Crash log files
15+
crash.log
16+
17+
# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
18+
# .tfvars files are managed as part of configuration and so should be included in
19+
# version control.
20+
#
21+
# example.tfvars
22+
23+
# Ignore override files as they are usually used to override resources locally and so
24+
# are not checked in
25+
override.tf
26+
override.tf.json
27+
*_override.tf
28+
*_override.tf.json
29+
30+
# Include override files you do wish to add to version control using negated pattern
31+
#
32+
# !example_override.tf
33+
34+
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
35+
# example: *tfplan*

ALTERNATIVER.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Alternativer
2+
* Bytte ut git-sha med [build-numbers](https://github.com/marketplace/actions/build-number-generator)
3+
* tester på deploytid
4+
* CSS og bilder inn i `npm run build`
5+
* Backend (helsesjekker og overvåking)
6+
* Database
7+
* Pålogging
8+
* Sikkerhet (vault eller andre, aws systems manager + KMS)
9+
* terraform outputs som som github-secret
10+
* terraform på ci
11+
* secrets lokalt for å kjøre terraform
12+
* secrets lokalt for å trigge githubaction
13+
* bedre lambda-testing fra lokal maskin
14+
* logging på lambdaer

README.md

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Immutable-webapp
2+
En implementasjon av stukturen fra https://immutablewebapps.org/ .
3+
4+
[Slides](https://docs.google.com/presentation/d/1gcnwG0NzTiAlQ9NrjWCTa6c0yCiKYEkowBLn9BSKbjA/present)
5+
6+
## Bli kjent
7+
8+
### Om appen
9+
10+
### Lokal oppstart
11+
12+
* Kjør opp appen med `npm install && npm run start`
13+
* Generer en index.html med `node src-index/main.js`
14+
* Gjør deg kjent med hvor de forskjellige inputene og env-variablene i appen kommer fra
15+
16+
## Min første immutable webapp
17+
18+
Felles mål her er en immutable webapp med to S3-buckets og et CDN foran som hoster index.html og kildekode.
19+
20+
Nyttige lenker:
21+
* Om du ikke er veldig kjent i aws-konsollen fra før, anbefaler jeg å sjekke ut de forskjellige servicene
22+
underveise
23+
- https://console.aws.amazon.com/s3
24+
- https://console.aws.amazon.com/cloudfront
25+
- https://console.aws.amazon.com/route53
26+
* [Terraform-docs](https://www.terraform.io/docs/providers/aws/r/s3_bucket.html)
27+
* [AWS-cli-docs](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html)
28+
29+
30+
### Testmiljø med buckets
31+
32+
Opprett to [buckets](https://www.terraform.io/docs/providers/aws/r/s3_bucket.html) med terraform som skal bli der vi server asset og host. Start i `terraform/test/main.tf`. Husk at S3-bucketnavn må være unike innenfor en region!
33+
34+
Anbefalt terraform-output for begge buckets:
35+
* bucket_domain_name - denne lenken kan du bruke til å aksessere filene du har lastet opp
36+
* id - navnet på bucketen du har opprettet
37+
38+
Når begge bucket er oppprettet uten mer oppsett, og du kan gå inn i konsollen på web og manuelt laste opp en tilfeldig fil. Den vil ikke tilgjengelig på internett via `bucket_domain_name/filnavn`, ettersom default-policyen er at bucket er private. Vi kan konfigurere public tilgang ved å bruke acl-parameteret på en bucket eller en bucket policy. Sistnevnte er anbefalt av AWS ettersom bucketacl er et eldre og skjørere konsept.
39+
40+
Opprett bucketpolicies for begge bøttene ved å bruke [`aws_s3_bucket_policy`](https://www.terraform.io/docs/providers/aws/r/s3_bucket_policy.html). I policy-atributtet kan du bruke en [templatefile](https://www.terraform.io/docs/configuration/functions/templatefile.html) med fila `policy/public_bucket.json.tpl`. Denne trenger en variabel `bucket_arn`. Bruk atributtet fra bucketen for å sende inn rett arn.
41+
42+
Se [policy.md](terraform/test/policy/policy.md) for en forklaring på innholdet i policyen.
43+
44+
45+
### Bruke AWS-cliet til opplasting av filer
46+
47+
Bygg assets lokalt med `npm run build` og bruk aws-cliet til å laste opp alt innholdet i build-mappen til asset-bucketen under navnet `assets/id`. Velg en tilfeldig id for testen, senere skal vi bruke githash! Test at fila blir tilgjengelig i browseren på `<bucket_domain_name>/assets/id/main.js` og sett rett cachcontrol-headers.
48+
49+
50+
`aws s3 cp <LocalPath> <S3Uri>`
51+
52+
Se [AWS-cli-docs](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html) for `aws s3 cp`
53+
54+
<details><summary>Tips</summary>
55+
<p>
56+
57+
- bruk følgende S3-uri `s3://bucket-name/assets/1/`
58+
- `--recursive` laster opp hele mappen
59+
- `--cache-control public,max-age=31536000,immutable` setter cache-controls-headerne til alltid lagre som beskrevet i https://immutablewebapps.org/
60+
</p>
61+
</details>
62+
63+
Gjør endringer i `sha` og `url` i `src-index/main.js` for å peke på bucket og fila du har lastet opp over.
64+
Bygg index.html (`node src-index/main.js`) og bruk `aws s3 cp` igjen for å kopiere index.html til host-bucket. Husk rett headers
65+
66+
Om du nå går på `<bucket_domain_name>/index.html` bør du se en kjørende applikasjon.
67+
68+
<details><summary>Tips</summary>
69+
<p>
70+
71+
- Bruk `index.html` både som localPath og `s3://bucket-host-name/index.html` som S3Uri ettersom vi kun laster opp en fil
72+
- `--cache-control no-store` setter cache-controls-headerne til aldri lagre som beskrevet i https://immutablewebapps.org/
73+
</p>
74+
</details>
75+
76+
77+
### Autodeploy av assets med Github Actions
78+
79+
Nå skal vi la Github Actions overta bygging av assets og opplasting til assets-bucketen under unike versjonsnavn.
80+
For enkelhets skyld er versjonsnavnet her `assets/sha/`. Vi skal bruke de samme kommandoene som over,
81+
men la det utførest av github.
82+
83+
- I `.github/workflows/nodejs.yml` er det starten på en workflow. Fullfør denne slik at bygg og kopier filer til assets-bucketen skjer på hver push.
84+
- I run-delen av en githubaction kan man hente ut commit med `${{github.sha}}`, se [docs](https://help.github.com/en/actions/reference/contexts-and-expression-syntax-for-github-actions)
85+
86+
Det finnes en githook som linter yml-filer for å slippe unna enkelte yml-feil i workflow-definisjonen.
87+
Om du ønsker å ta den i bruk kan du kjøre kommandoen `git config core.hooksPath .githooks`
88+
89+
90+
### Autodeploy til host
91+
- Utvid `.github/workflows/nodejs.yml` til også å generere og laste opp index.html i host-bucketen. Sjekk ut tilgjengelige variable for node i [docs](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables).
92+
93+
94+
### CDN
95+
96+
AWS CloudFront er Amazon sin CDN-provider, se [terraform-docs](https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html).
97+
Om du gjør dette for første gang anbefaler jeg at du starter med et cloudfront-domene og heller endrer til eget domene i neste steg.
98+
99+
For å mappe terraform-input til rett verdier, anbefaler jeg å se i aws-konsollen på CloudFront og velge "Create a distribution".
100+
En gotcha som er fin å vite om, dersom du [ikke setter verdier i ttl-atributtene](https://github.com/terraform-providers/terraform-provider-aws/issues/1994) til terraform vil dette gjøre at CloudFront velger å bruker cachecontrol-headers fra origin, tilsvarende `Use Origin Cache Headers` fra AWS-console'en.
101+
102+
Figuren bakerst i slidesettet gir en slags oversikt av hvordan CloudFront passer inn som server for både host og assets - men dette var også den vanskeligste delen av oppgaven å beskrive! Så vær så snill å stikk innom Tine eller andre om det ikke gir mening.
103+
104+
Test ut endringer i `App.jsx` og deploy ny versjon av assets og index for å sjekke caching og endringer.
105+
- OBS: Nå kan du bruke `domain_name` outputen fra cloudfront som erstatning for `my-url` i `src-index/main.js`
106+
107+
<details><summary>Tips</summary>
108+
<p>
109+
- du trenger en `origin` pr. s3 bucket
110+
- `enabled`, `restrictions`, `viewer_certificate` kan være default
111+
- `default_root_object` er `index.html`
112+
- `default_cache_behavior` og `ordered_cache_behavior` kan ha like configparameter, men default må peke på host-bucket og ordered_cache_behavior på assets. Path `assets/*` matcher url-strukturen fra index.html
113+
</p>
114+
</details>
115+
116+
117+
## Alternativer videre (bruk rekkefølgen som står eller plukk selv om du ønsker noe spesielt)
118+
119+
Cirka frem til punktet "Lag et eget domene" kan du finne et løsningsforslag i repoet https://github.com/kleivane/immutable-webapp .
120+
121+
* Lag et prodmiljø
122+
* La terraform opprette en [iam-bruker](https://www.terraform.io/docs/providers/aws/r/iam_user.html) som bruker av github med rettigheter kun til opplasting i buckets. [Rettighetssimulatoren](http://awspolicygen.s3.amazonaws.com/policygen.html) for iam kan hjelpe litt
123+
* Ta i bruk remote [backend i S3 ](https://www.terraform.io/docs/backends/types/s3.html)
124+
* Trekk ut til en felles terraform-modul
125+
* Trekk ut bygging av index.html til en lambda
126+
* Lambdaen trenger kildekode i egen bucket
127+
* La tagging i github `lambda-x.y.z` trigge bygging og release av ny kildekode
128+
* Provisjoner lambda med terraform pr miljø og send inn versjon av kildekoden som skal brukes
129+
* Lag et eget domene i Route 53 slik at du har en egen url
130+
* Lag sertifikat fra certification manager
131+
* Legg inn alias og sertifikat (`viewer_certificate`) i cloudfront. Merk av `ssl_support_method = sni-only` for å unngå ekstra kostnader!
132+
* Opprett alias i route53 med en ny [record](https://www.terraform.io/docs/providers/aws/r/route53_record.html)
133+
* *Alias record typically have a type of A or AAAA, but they work like a CNAME record*
134+
* Ta i bruk https://github.com/nektos/act for kjøring av github-actions lokalt
135+
* Skriv tester! https://terratest.gruntwork.io/
136+
* Trekk ut prodmiljø i en egen AWS-account
137+
* Rull ut dockercontaineren fra https://github.com/kleivane/static-json
138+
* Test ut [workspaces](https://www.terraform.io/docs/state/workspaces.html) for terraform-endringer
139+
* Bruk moduler fra https://github.com/cloudposse/, feks https://github.com/cloudposse/terraform-aws-cloudfront-cdn
140+
* Flytt cachecontrol fra hver enkelt fil til lambda@edge
141+
* Bruk en annen skyprovider

dev-index.html

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="x-ua-compatible" content="ie=edge">
6+
<title>Dev!</title>
7+
<meta name="description" content="Immutable webapp.">
8+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
9+
</head>
10+
<body>
11+
<!-- environment variables -->
12+
<script>
13+
env = {
14+
ENV_NAME: 'dev',
15+
GIT_SHA: 'sha',
16+
API_URL: 'api',
17+
CREATED_AT: new Date().toISOString()
18+
}
19+
</script>
20+
21+
<!-- application binding -->
22+
<app-root></app-root>
23+
24+
</body>
25+
</html>

0 commit comments

Comments
 (0)