I denne oppgaven vil du lage en nettside ved hjelp av Amazon S3. En S3 Bucket skal lages med Terraform og statiske websider skal lages i React.js fra kildekode med NPM av Github actions, og lastes opp. Appen er en enkel "hello world"...
Vi skal se nærmer på;
- En workflow med to jobber - en jobb vil lage infrastruktur, den andre kompilere og publisere en webapp
- Mer avansert Github actions. For eksempel; Flere jobber og avhengigheter mellom jobber
- Mer avansert Github actions - Bruke funksjonen
github.issues.createComment
for å legge på kommentarer på Pull requests - Terraform i Pipeline - GitHub actions skal kjøre Terraform.
- Vi skal se hvordan vi kan bruke GitHub Actions til å bygge & publisere en enkel React.js webapp
- AWS - Hvordan bruke en open source modul til å spare masse tid, og publisere en enkel React.js webapp
Du må start emd å lage en fork av dette repositoryet til din egen GitHub konto.
- Logg på med din AWS bruker med URL, brukernavn og passord gitt i klassrommet
- Gå til tjenesten Cloud9 (Du nå søke på Cloud9 uten mellomrom i søket)
- Velg "Open IDE"
- Hvis du ikke ser ditt miljø, kan det hende du har valgt feil region. Hvilken region du skal bruke vil bli oppgitt i klasserommet.
- Når du skal autentisere deg mot din GitHub konto fra Cloud 9 trenger du et access token. Gå til https://github.com/settings/tokens og lag et nytt.
- NB. Ta vare på tokenet et sted, du trenger dette senere når du skal gjøre
git push
Access token må ha "repo" tillatelser, og "workflow" tillatelser.
Fra Terminal i Cloud 9. Klone repositoriet ditt med HTTPS URL. Eksempel ;
git clone https://github.com/≤github bruker>/03-terraform-iac.git
Får du denne feilmeldingen bash: /03-terraform-iac: Permission denied
- så glemte du å bytte ut med
ditt eget Github brukernavn :-)
OBS Når du gjør git push
senere og du skal autentisere deg, skal du bruke GitHub Access token når du blir bedt om passord,
så du trenger å ta vare på dette et sted.
For å slippe å autentisere seg hele tiden kan man få git til å cache nøkler i et valgfritt antall sekunder på denne måten;
git config --global credential.helper "cache --timeout=86400"
Konfigurer også brukernavnet og e-posten din for GitHub CLI. Da slipepr du advarsler i terminalen når du gjør commit senere.
git config --global user.name <github brukernavn>
git config --global user.email <email for github bruker>
I din fork av dette repositoriet, velg "actions" for å slå på støtte for GitHub actions i din fork.
Gå til demo-app katalogen
cd 03-terraform-iac
cd demo-app
npm install
npm run start
Du kan sjekke at applikasjonen kjører ved å trykke "Preview running applicaiton" i Cloud 9 miljøet idtt
Vi skal nå få denne webapplikasjonen til å kjøre i et AWS miljø, og vi skal lage den nødvendige infrastrukturen
- som riktig nok ikke er så veldig mye, med Terraform.
- En Terraform backend er en lagringsplass for Terraform metadata som beskriver hvordan infrakode og den faktiske infrastrukturen henger sammen.
- Følgende konfigurasjon forteller terraform at Backend er på Amazon AWS S3, i hvilken bucket, og hvilken statefil som skal brukes.
- Siden hver enkelt student har sin egen infrastruktur- og egen pipeline, må dere også ha deres egen, separate state fil.
- I provider.tf har vi en Backend for Terraform sin state basert på S3. Du må her erstatte
<studentnavn>
med ditt eget brukernavn
backend "s3" {
bucket = "pgr301-2021-terraform-state"
key = "<studentnavn>/terraform-in-pipeline.state"
region = "eu-west-1"
}
Vi skal nå gjøre Terraformkoden bedre, ved å fjerne hardkodingen av "glenn" i static_website.tf
filen. Det er ikke god praksis å hardkode
verdier ("glenn...") på denne måten.
- Lag en variables.tf i rotkatalogen, der du har sjekket ut koden fra github.
- Velg dit eget bucketnavn for
<the bucket name>
. Dette må være globalt unikt.
variable "bucket_name" {
description = "The name of the bucket to create"
default = "<the bucket name>"
}
For mer informasjon om variabler se her; https://www.terraform.io/docs/language/values/variables.html
Da kan vi istedet for å skrive
resource "aws_s3_bucket" "frontend" {
bucket = "glenn-demobucket"
acl = "public-read"
bruke følgende syntaks
resource "aws_s3_bucket" "frontend" {
bucket = var.bucket_name
acl = "public-read"
...Og istedet for
"Effect": "Allow",
"Resource": "arn:aws:s3:::glenn/*",
"Principal": "*"
}
.. Så kan vi skrive
"Effect": "Allow",
"Resource": "arn:aws:s3:::${var.bucket_name}/*",
"Principal": "*"
Du er nå klar for å teste terraform fra Cloud9
export AWS_REGION=eu-west-1
terraform init
terraform plan
terraform apply
Følg instruksjonene fra forrige lab https://github.com/glennbechdevops/02-CD-AWS-lamda-sls#hemmeligheter for å legge inn hemmelige verdier i ditt GitHub Repo for. Verdier gitt på Slack eller i klasserommet!
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- Modifiser filen
.github/workflows/pipeline.yaml
og tilpass denne ditt eget miljø. - I fil-utforskeren i Cloud 9 må du trykke på "tannhjulet" og slå på visning av skjulte filer for å få se denne.
- Du må endre på denne delen av filen,
- run: aws s3 cp build s3://<bucket_navn>> --recursive --region eu-west-1
working-directory: ./demo-app
- Du skal erstatte bucket navnet
<bucket_name>
med ditt eget bucketnavn som du valgte i variables.tf
Det kan være lurt på formatere terraformkode før du sjekker inn. Pipeline feiler på feil formatert kode.
terraform fmt --recursive
Commit filer og push
git add .github/workflows/pipeline.yaml
git add provider.tf
git add static_website.tf
git add variables.tf
git commit -m"run forest run"
git push
Du skal bruke Token du lage i noen steg tidligere når du blir bedt om passord.
Vi sette hemmeligheter på denne måten slik at terraform har tilgang til AWS nøkler, og har de rettighetene som er nødvendig.
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: eu-west-1
Her ser vi et steg i en pipeline med en if
- som bare skjer dersom det er en pull request
som bygges, vi ser også at
pipeline får lov til å fortsette dersom dette steget feiler.
- name: Terraform Plan
id: plan
if: github.event_name == 'pull_request'
run: terraform plan -no-color
continue-on-error: true
- Her setter vi en variabel lik all output fra et tidligere steg (!)
env:
PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
Her bruker vi også den innebyggede funksjonen github.issues.createComment
til å lage en kommentar til en Pull request, med innholdet av Terraform plan. Altså, hva kommer til å skje hvis vi kjører en apply på denne.
script: |
const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
#### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
#### Terraform Validation 🤖\`${{ steps.validate.outcome }}\`
#### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
<details><summary>Show Plan</summary>
\n
\`\`\`\n
${process.env.PLAN}
\`\`\`
</details>
*Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
Når noen gjør en Git push til main branch, kjører vi terraform apply
med ett flag --auto-approve
som gjør at terraform ikke
spør om lov før den kjører.
- name: Terraform Apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: terraform apply -auto-approve
Student webapp trenger infra laget av terraform. Vi kan da bruke needs
for å lage en avhengighet mellom en eller flere jobber;
student_webapp:
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: eu-west-1
needs: terraform
Å publisere en statisk website, og hoste denne på AWS S3 gjøres nå i to steg;
- npm build, som bygger et sett med statiske websider av applikasjonen
- kopiering av disse filene til en S3 bucket
- Gratulerer! Du har nå publisert din egent React.js web app på AWS.
- Prøv å endre på Javascript filene, følg med på pipeline i "actions" i GitHub, og se at endringene kommer ut.
- Lag en feature branch og en pull request. Endre terraform-koden noe, slik at du vil se resultatet av planen som en kommentar.
- Følg tutorial for hvordan dere kan lage egne terraform moduler; https://learn.hashicorp.com/tutorials/terraform/module-create