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

Revert "Feature/cd pipeline" #33

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
9 changes: 7 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ POSTGRES_PASSWORD="admin"

BASE_URL="http://localhost:7007"

GITHUB_CLIENT_ID="your-id"
GITHUB_CLIENT_SECRET="your-secret"

GITHUB_TOKEN="your-token"

GOOGLE_CLIENT_ID="your-id"
GOOGLE_CLIENT_SECRET="your-secret"
K8S_URL="k8s-url"
K8S_ACCOUNT_TOKEN="k8s-account-token"
K8S_CA_DATA="k8s-ca-data"
K8S_CA_FILE="k8s-ca-file"
86 changes: 4 additions & 82 deletions .github/workflows/cd-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,12 @@
name: Deploy backstage
on:
workflow_dispatch:
push:
branches:
- main


jobs:
create-and-push-image:
permissions:
id-token: write
contents: read
name: "Create and push the Docker image to GAR"
placeholder-job:
runs-on: ubuntu-latest
defaults:
run:
shell: bash

steps:
- name: Checkout
uses: actions/checkout@v4
- id: 'setup-qemu'
name: Set up QEMU
uses: docker/setup-qemu-action@v3
- id: 'docker-buildx-setup'
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- id: 'auth'
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v2'
with:
create_credentials_file: true
token_format: access_token
workload_identity_provider: 'projects/1006240973223/locations/global/workloadIdentityPools/deploy-backstage/providers/github-actions'
service_account: '[email protected]'
- id: 'login-gar'
name: "Login to GAR"
uses: docker/login-action@v3
with:
registry: europe-west10-docker.pkg.dev/code-idp/backstage-deploy
username: oauth2accesstoken
password: ${{ steps.auth.outputs.access_token }}
- id: 'build-and-push'
name: 'Build and Push docker Image'
uses: docker/build-push-action@v5
with:
push: true
context: .
file: ./Dockerfile
platforms: linux/amd64
tags: europe-west10-docker.pkg.dev/code-idp/backstage-deploy/backstage-image:${{ github.sha }}
build-args: |
APP_ENV=docker
deploy-image:
permissions:
id-token: write
contents: read
name: "Deploy image on cloud run"
runs-on: ubuntu-latest
defaults:
run:
shell: bash
needs: create-and-push-image
steps:
- name: Checkout
uses: actions/checkout@v4
- id: 'auth'
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v2'
with:
create_credentials_file: true
workload_identity_provider: 'projects/1006240973223/locations/global/workloadIdentityPools/deploy-backstage/providers/github-actions'
service_account: '[email protected]'
- id: 'deploy'
uses: 'google-github-actions/deploy-cloudrun@v2'
with:
service: 'backstage-deployment'
image: 'europe-west10-docker.pkg.dev/code-idp/backstage-deploy/backstage-image:${{ github.sha }}'
region: europe-west1
flags: '--port=7007 --add-cloudsql-instances=code-idp:europe-west10:backstage-pg'
env_vars: |
POSTGRES_HOST=/cloudsql/code-idp:europe-west10:backstage-pg
POSTGRES_PORT=5432
POSTGRES_USER=postgres
BASE_URL=https://backstage.foundations-software-engineering.com
secrets: |-
POSTGRES_PASSWORD=postgres-password:latest
GITHUB_TOKEN=github_token:latest
GOOGLE_CLIENT_ID=google_client_id:latest
GOOGLE_CLIENT_SECRET=google_client_secret:latest
- name: hello world
run: echo "Hello World"
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid

# Copy the built packages from the build stage
COPY --from=build --chown=node:node /app/packages/backend/dist/bundle/ ./
COPY --from=build --chown=node:node /app/minikube ./minikube/

ARG APP_ENV

Expand Down
123 changes: 123 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@ POSTGRES_PASSWORD="admin"

BASE_URL="http://localhost:7007"

GITHUB_CLIENT_ID="your-id"
GITHUB_CLIENT_SECRET="your-secret"

GOOGLE_CLIENT_ID= "google_client_id"
GOOGLE_CLIENT_SECRET= "google_client_secret"

GITHUB_TOKEN="your-token"

K8S_URL="k8s-url"
K8S_ACCOUNT_TOKEN="k8s-account-token"
K8S_CA_DATA="k8s-ca-data"
K8S_CA_FILE="k8s-ca-file"
```

<details>
Expand All @@ -54,6 +62,10 @@ All of the environment variables prefixed with POSTGRES_ should stay like they a
<br>
Keep it the same as it is right now, this is the url on which the application is running.

**`GITHUB_CLIENT`:**
<br>
These environment variables are to setup correct [authentication](https://backstage.io/docs/getting-started/configuration#setting-up-authentication). Please follow [these](#github-auth) steps.

**`GOOGLE_CLIENT`:**
<br>
These environment variables are to allow google login with your code.berlin email.
Expand All @@ -64,6 +76,11 @@ Use the link above and copy the client ID and secret.
<br>
This environment variable is to configure the [GitHub integration](https://backstage.io/docs/getting-started/configuration#setting-up-a-github-integration),
so that Backstage can interact with your GitHub account and for example create a repository for you. Please follow [these](#github-integration) steps for the setup.

**`K8S_URL`:**
<br>
These environment variables are to configure the [kubernetes plugin](https://backstage.io/docs/features/kubernetes/).
To setup you local minikube environment follow [these](#kubernetes) steps.
</details>

# Setup Essentials
Expand Down Expand Up @@ -113,6 +130,7 @@ then you can decide where you to run backstage:

1. [locally](#running-with-yarn-dev) with `yarn dev` (recommended for regular development due to short waiting time on changes)
2. inside of a [docker container](#running-with-docker-compose) (recommended only to test certain environments due to high waiting time because of high image build time (up to 5 mins))
3. inside of [minikube](#running-with-minikube) (only recommended to test to be the closest to the actual production environment (for testing))
<br>
!! Note this is based on assumption that we will host `Backstage` inside of the Kubernetes cluster where we host the other dev projects

Expand Down Expand Up @@ -157,6 +175,107 @@ To remove all containers (**IMPORTANT** this also removes the database container
yarn docker:remove-all
```

# Kubernetes
The following talks about two different topics (it is highly encourged to watch a short [tutorial](https://www.youtube.com/watch?v=PziYflu8cB8) on Kubernetes before continuing):

1. How to setup minikube and how to use Backstage to monitor pods that are running inside of Kubernetes.
2. How to run Backstage itself inside of the minikube cluster (and still be able to monitor the pods that are running in Kubernetes, which means the first step is a pre-requisite of this step).
The reason for having the second step is more for testing purposes because this setup is the closest to the actual production environment

> Note again here the second step is only true if we actually host Backstage in the same cluster as the other deployments

## Setup with `minikube`
Pre-requisite: Docker installed

To setup minikube and the [Kubernetes plugin](https://backstage.io/docs/features/kubernetes/) so that we can monitor Kubernetes pods
through Backstage we need to do the following:
1. Install `kubectl`
<br>
1.1 Install the correct version of `kubectl` depending on your operation system: [linux](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/),
[macOS](https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/) or [windows](https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/). On macOS installing with
homebrew is recommended by me.
<br>
1.2 Quick Note about `kubectl`: `kubectl` is the cli tool that can interact with an existing Kubernetes cluster and it has different `contexts` for different cluster.
If this is your first time installing `kubectl` and you most likely do not have a cluster that you are connected to at this point, we will set up a local cluster with `minikube`
in the following setup, and that will automatically set your context to the correct cluster (in this case `minikube`).
To see all your contexts run `kubectl config get-contexts`.
2. Install `minikube`
<br>
2.1 Follow [this guide](https://minikube.sigs.k8s.io/docs/start/#installation) to install minikube and also how to run minikube inside of a docker, make sure you install minikube for the correct system.
Installing on macOS with homebrew is recommended by me.
<br>
2.2 Start minikube clutser with `minikube start` (can take a few minutes)
<br>
NOTE: If you have installed kubectl, `minikube start` will automatically set your current context to the `minikube` context!
<br>
2.3 To test if the installation worked run: `kubectl get pods -A` and you should have an output similiar to this:
```
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-5d78c9869d-4jq4h 1/1 Running 0 9m43s
kube-system etcd-minikube 1/1 Running 0 9m56s
kube-system kube-apiserver-minikube 1/1 Running 0 9m58s
kube-system kube-controller-manager-minikube 1/1 Running 0 9m58s
kube-system kube-proxy-8dzhs 1/1 Running 0 9m44s
kube-system kube-scheduler-minikube 1/1 Running 0 9m56s
kube-system storage-provisioner 1/1 Running 1 (9m39s ago) 9m56s
```
3. Setup `minikube` for Backstage
<br>
<br>
**3.1 Create a service account so that backstage can access the cluster**
```sh
kubectl apply -f minikube/clusterrolebinding.yaml

kubectl get secrets cluster-admin-secret -o jsonpath="{.data['token']}" | base64 --decode; echo
```
copy and paste that token in the K8S_ACCOUNT_TOKEN environment variable in your .env
<br>
<br>
**3.2 Get the certificate authority for minikube**
```sh
cat ~/.minikube/ca.crt | base64
```
copy and paste that certificate in the K8S_CA_DATA environment variable in your .env
<br>
<br>
**3.3 Get the URL that `minikube` is running on**
```sh
kubectl cluster-info
```
copy and paste the first URL in the K8S_URL environment variable in your .env
<br>
<br>
**3.4 Run pod in `minikube` to be inspected by `Backstage`**
```sh
kubectl apply -f minikube/test-deployment.yaml
```

> NOTE: we leave the K8S_CA_FILE environment variable empty for now because that is only needed if you run Backstage in the cluster,
for now it is recommended only to run it [locally](#running-with-yarn-dev) or run in [docker](#running-with-docker-compose) to be able to run it inside of minikube read [here](#running-with-minikube)

4. [Run](#running-environments) backstage (recommended [locally](#running-with-yarn-dev))
<br>
NOTE: If you want to run backstage inside of the docker container you need to change the K8S_URL variable to: https://host.docker.internal:[YOUR-PORT]
<br>

4.1 Click on `test-minikube`
<br>
<img height="200" alt="img" src="./images/backstage-example.svg">

4.2 Click on `Kubernetes`
<br>
<img height="150" alt="img" src="./images/backstage-kubernetes.svg">

4.3 Now you should see this:
<br>
<img height="200" alt="img" src="./images/backstage-kube-success.svg">

5. To see how you can expose your own Backstage entities follow
[this](https://backstage.io/docs/features/kubernetes/configuration#surfacing-your-kubernetes-components-as-part-of-an-entity) guide

## Running with `minikube`
Work in progress -> Not necessary for development right now.

# Configuration
To get a better understanding of how the app-config.yaml files work please refer to [this](https://backstage.io/docs/conf/writing).
Specifically the part about the [config files](https://backstage.io/docs/conf/writing#configuration-files) is important to understand.
Expand Down Expand Up @@ -186,6 +305,10 @@ This file changes some base values that are necessary to build the correct image
- auth.github because we set the NODE_ENV to production for the image
- catalog because it interprets the paths from local directories differently in the image

**`app-config.production.yaml`:**
<br>
This file adds one line to the kubernetes plugin setup, which is only needed if the app is hosted inside of a kubernetes cluster.

# Testing

Before committing your changes, run the tests pls. ✨
Expand Down
12 changes: 12 additions & 0 deletions app-config.docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,15 @@ catalog:
pullRequestBranchName: backstage-integration
rules:
- allow: [Component, System, API, Resource, Location]
locations:
- type: file
target: minikube/catalog-info.yaml


auth:
environment: production
providers:
github:
production:
clientId: ${GITHUB_CLIENT_ID}
clientSecret: ${GITHUB_CLIENT_SECRET}
15 changes: 15 additions & 0 deletions app-config.production.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Only difference here is that we need a caFile if it is deployed inside of a kube cluster
kubernetes:
serviceLocatorMethod:
type: multiTenant
clusterLocatorMethods:
- type: config
clusters:
- url: ${K8S_URL}
name: "k8s"
authProvider: serviceAccount
skipTLSVerify: false
skipMetricsLookup: true
serviceAccountToken: ${K8S_ACCOUNT_TOKEN}
caData: ${K8S_CA_DATA}
caFile: ${K8S_CA_FILE}
21 changes: 21 additions & 0 deletions app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ catalog:
rules:
- allow: [User, Group]

- type: file
target: ../../minikube/catalog-info.yaml

- type: url
target: https://github.com/backstage/software-templates/blob/main/scaffolder-templates/react-ssr-template/template.yaml
rules:
Expand All @@ -69,7 +72,25 @@ auth:
# see https://backstage.io/docs/auth/ to learn about auth providers
environment: development
providers:
github:
development:
clientId: ${GITHUB_CLIENT_ID}
clientSecret: ${GITHUB_CLIENT_SECRET}
google:
development:
clientId: ${GOOGLE_CLIENT_ID}
clientSecret: ${GOOGLE_CLIENT_SECRET}

kubernetes:
serviceLocatorMethod:
type: multiTenant
clusterLocatorMethods:
- type: config
clusters:
- url: ${K8S_URL}
name: 'k8s'
authProvider: serviceAccount
skipTLSVerify: false
skipMetricsLookup: true
serviceAccountToken: ${K8S_ACCOUNT_TOKEN}
caData: ${K8S_CA_DATA}
37 changes: 37 additions & 0 deletions deployments/backstage-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# kubernetes/backstage.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage
namespace: backstage
spec:
replicas: 1
selector:
matchLabels:
app: backstage
template:
metadata:
labels:
app: backstage
spec:
# serviceAccountName: staging-rem-backend-service-acc
containers:
- name: backstage
image: notemann27/backstage:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 7007
envFrom:
- secretRef:
name: backstage-secrets
# Uncomment if health checks are enabled in your app:
# https://backstage.io/docs/plugins/observability#health-checks
# readinessProbe:
# httpGet:
# port: 7007
# path: /healthcheck
# livenessProbe:
# httpGet:
# port: 7007
# path: /healthcheck
Loading
Loading