diff --git a/.github/workflows/deploy-aggregator.yaml b/.github/workflows/deploy-aggregator.yaml new file mode 100644 index 0000000..97d14cb --- /dev/null +++ b/.github/workflows/deploy-aggregator.yaml @@ -0,0 +1,83 @@ +name: Create and publish SSO Aggregator helm chart + +on: + push: + branches: + - main + - dev + paths: + - aggregator/** + - helm/aggregator/** + - .github/workflows/deploy-aggregator.yaml + +env: + GITHUB_REGISTRY: ghcr.io + IMAGE_NAME: bcgov/sso-aggregator + +jobs: + build-and-push-image: + runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v4 + + - name: Setup Tools + uses: ./.github/actions/setup-tools + + - name: Log in to the GitHub Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=sha,format=long + + - name: Build and push Docker image + uses: docker/build-push-action@v3 + with: + context: aggregator + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Set env to Sandbox + if: (github.ref == 'refs/heads/dev' && github.event_name == 'push') + run: | + cat >> $GITHUB_ENV <> $GITHUB_ENV <> $GITHUB_ENV <> $GITHUB_ENV <> $GITHUB_ENV <> $GITHUB_ENV < ## Deployment -The helm charts for the promtail instances and grafana dashboard can be installed with make commands. These automate adding environment variables from .env files in their directories. See the directory readmes for more information. +The helm charts for the promtail instances and grafana dashboard can be installed with make commands. These automate adding environment variables from .env files in their directories. See the directory readmes for more information. They will deploy on merge to dev for sandbox, and main for production. The Loki setup is deployed with terraform into AWS. It deploys automatically on merge to dev/main. -GitHub CD pipeline scripts are triggered based on the directory that has changed; there is a recommended deployment order when deploying the resources for the very first time: - -1. `Loki`: deploys the `MinIO` and `Loki` resources, `read`, `write`, and `gateway`. -1. `Aggregator`: deploys the `Aggregator` and `Compactor` with the `Postgres DB`. -1. `Grafana`: deploys the `Grafana` dashboard with the two `datasources` configured above. -1. `Promtail`: deploys the `Promtail` in multiple namespaces to collect the Keycloak disk logs. +GitHub CD pipeline scripts are triggered based on the directory that has changed; When deploying for the first time you should deploy promtail last, as it will give not found errors until the receiving resources (loki and aggregator) are up and running. The terraform account for deployment is restricted to the required resource types for this repository. If adding new resources not currently required, you will get a permission denied error. Expand the permissions on the `sso-dashboard-boundary` as needed. +## Service accounts + +Service accounts are already generated and added to github secrets, see below for the related OC secret to see the token value. If needing to recreate the service account, see the [service-account-generator directory](/service-account-generator/README.md) for how to do so. + ## GitHub secrets The following secrets are set in the GitHub secrets of the repository and can be found in [OCP secret](https://console.apps.silver.devops.gov.bc.ca/k8s/ns/6d70e7-tools/secrets/sso-team-sso-dashboard-github-secrets) @@ -75,19 +75,11 @@ The following secrets are set in the GitHub secrets of the repository and can be ### Sandbox - `SANDBOX_OPENSHIFT_SERVER`: the OpenShift online server URL. -- `SANDBOX_OPENSHIFT_TOKEN`: : the OpenShift session token. - - please the find the secret in [Sandbox Deployer Secret](https://console.apps.gold.devops.gov.bc.ca/k8s/ns/c6af30-tools/secrets/oc-deployer-token-9tgwm) -- `SANDBOX_OPENSHIFT_NAMESPACE`: the namespace name to deploy `Grafana`, `Loki`, and `Aggregator`. -- `SANDBOX_SSO_CLIENT_ID`: the SSO integration credentials, `client id`, to set in `Grafana` and `MinIO` dashboard UI. -- `SANDBOX_SSO_CLIENT_SECRET`: the SSO integration credentials, `client secret`, to set in `Grafana` and `MinIO` dashboard UI. - - please find the integration `#4492 SSO Dashboard` via [CSS app](https://bcgov.github.io/sso-requests) +- `SANDBOX_OPENSHIFT_TOKEN`: The OpenShift session token. The token can be found in the sso-dashboard-deployer-e4ca1d-token secret in the prod namespace. +- `GRAFANA_SANDBOX_ENV`: Contains all secrets necessary to deploy grafana as an env file, see [the example env file](/helm/grafana/.env.example) for the list. The values are saved in the openshift secret sso-grafana-env in the tools namespace for reference. ### Production - `PROD_OPENSHIFT_SERVER`: the OpenShift online server URL. -- `PROD_OPENSHIFT_TOKEN`: : the OpenShift session token. - - please the find the secret in [Sandbox Deployer Secret](https://console.apps.gold.devops.gov.bc.ca/k8s/ns/eb75ad-tools/secrets/oc-deployer-token-b99cz) -- `PROD_OPENSHIFT_NAMESPACE`: the namespace name to deploy `Grafana`, `Loki`, and `Aggregator`. -- `PROD_SSO_CLIENT_ID`: the SSO integration credentials, `client id`, to set in `Grafana` and `MinIO` dashboard UI. -- `PROD_SSO_CLIENT_SECRET`: the SSO integration credentials, `client secret`, to set in `Grafana` and `MinIO` dashboard UI. - - please find the integration `#4492 SSO Dashboard` via [CSS app](https://bcgov.github.io/sso-requests) +- `PROD_OPENSHIFT_TOKEN`: The OpenShift session token. The token can be found in the sso-dashboard-deployer-eb75ad-token secret in the prod namespace. +- `GRAFANA_PROD_ENV`: Contains all secrets necessary to deploy grafana as an env file, see [the example env file](/helm/grafana/.env.example) for the list. The values are saved in the openshift secret sso-grafana-env in the tools namespace for reference. diff --git a/helm/aggregator/Makefile b/helm/aggregator/Makefile index b213d3f..ce5e054 100644 --- a/helm/aggregator/Makefile +++ b/helm/aggregator/Makefile @@ -1,6 +1,5 @@ SHELL := /usr/bin/env bash NAMESPACE= -IMAGE_TAG=dev NAME=sso-aggregator ifndef NAMESPACE @@ -8,8 +7,7 @@ $(error NAMESPACE is not set) endif define arguments - "${NAME}" . -n "${NAMESPACE}" -f values.yaml -f "values-${NAMESPACE}.yaml" \ - --set image.tag="${IMAGE_TAG}" + "${NAME}" . -n "${NAMESPACE}" -f values.yaml -f "values-${NAMESPACE}.yaml" endef .PHONY: helm-dep diff --git a/helm/aggregator/templates/deployment-compactor.yaml b/helm/aggregator/templates/deployment-compactor.yaml index 4f391ca..5011f13 100644 --- a/helm/aggregator/templates/deployment-compactor.yaml +++ b/helm/aggregator/templates/deployment-compactor.yaml @@ -60,34 +60,73 @@ spec: - name: RETENTION_PERIOD value: {{ .Values.compactor.retentionPeriod }} - name: RC_WEBHOOK - value: {{ .Values.compactor.webhookUrl }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: RC_WEBHOOK - name: DEV_KEYCLOAK_URL - value: {{ .Values.compactor.dev.keycloakUrl }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: DEV_KEYCLOAK_URL - name: DEV_KEYCLOAK_CLIENT_ID - value: {{ .Values.compactor.dev.keycloakClientId }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: DEV_KEYCLOAK_CLIENT_ID - name: DEV_KEYCLOAK_USERNAME - value: {{ .Values.compactor.dev.keycloakUsername }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: DEV_KEYCLOAK_USERNAME - name: DEV_KEYCLOAK_PASSWORD - value: {{ .Values.compactor.dev.keycloakPassword }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: DEV_KEYCLOAK_PASSWORD - name: TEST_KEYCLOAK_URL - value: {{ .Values.compactor.test.keycloakUrl }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: TEST_KEYCLOAK_URL - name: TEST_KEYCLOAK_CLIENT_ID - value: {{ .Values.compactor.test.keycloakClientId }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: TEST_KEYCLOAK_CLIENT_ID - name: TEST_KEYCLOAK_USERNAME - value: {{ .Values.compactor.test.keycloakUsername }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: TEST_KEYCLOAK_USERNAME - name: TEST_KEYCLOAK_PASSWORD - value: {{ .Values.compactor.test.keycloakPassword }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: TEST_KEYCLOAK_PASSWORD - name: PROD_KEYCLOAK_URL - value: {{ .Values.compactor.prod.keycloakUrl }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: PROD_KEYCLOAK_URL - name: PROD_KEYCLOAK_CLIENT_ID - value: {{ .Values.compactor.prod.keycloakClientId }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: PROD_KEYCLOAK_CLIENT_ID - name: PROD_KEYCLOAK_USERNAME - value: {{ .Values.compactor.prod.keycloakUsername }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: PROD_KEYCLOAK_USERNAME - name: PROD_KEYCLOAK_PASSWORD - value: {{ .Values.compactor.prod.keycloakPassword }} + valueFrom: + secretKeyRef: + name: {{ .Values.compactor.secret }} + key: PROD_KEYCLOAK_PASSWORD resources: {{- toYaml .Values.compactor.resources | nindent 12 }} diff --git a/helm/aggregator/values-e4ca1d-prod.yaml b/helm/aggregator/values-e4ca1d-prod.yaml index e9c3827..da74deb 100644 --- a/helm/aggregator/values-e4ca1d-prod.yaml +++ b/helm/aggregator/values-e4ca1d-prod.yaml @@ -1,4 +1,9 @@ -replicaCount: 2 +replicaCount: 1 + +image: + repository: ghcr.io/bcgov/sso-aggregator + tag: dev + pullPolicy: IfNotPresent patroni: replicaCount: 2 @@ -8,22 +13,7 @@ patroni: compactor: enabled: true retentionPeriod: '3 months' - webhookUrl: - dev: - keycloakUrl: - keycloakClientId: - keycloakUsername: - keycloakPassword: - test: - keycloakUrl: - keycloakClientId: - keycloakUsername: - keycloakPassword: - prod: - keycloakUrl: - keycloakClientId: - keycloakUsername: - keycloakPassword: + secret: sso-aggregator autoscaling: enabled: true diff --git a/helm/aggregator/values-eb75ad-tools.yaml b/helm/aggregator/values-eb75ad-tools.yaml index d9f6bad..0cecc80 100644 --- a/helm/aggregator/values-eb75ad-tools.yaml +++ b/helm/aggregator/values-eb75ad-tools.yaml @@ -1,4 +1,9 @@ -replicaCount: 10 +replicaCount: 1 + +image: + repository: ghcr.io/bcgov/sso-aggregator + tag: main + pullPolicy: IfNotPresent patroni: replicaCount: 2 @@ -8,22 +13,7 @@ patroni: compactor: enabled: true retentionPeriod: '6 months' - webhookUrl: - dev: - keycloakUrl: - keycloakClientId: - keycloakUsername: - keycloakPassword: - test: - keycloakUrl: - keycloakClientId: - keycloakUsername: - keycloakPassword: - prod: - keycloakUrl: - keycloakClientId: - keycloakUsername: - keycloakPassword: + secret: sso-aggregator autoscaling: enabled: true diff --git a/helm/aggregator/values.yaml b/helm/aggregator/values.yaml index 2437379..412e5e8 100644 --- a/helm/aggregator/values.yaml +++ b/helm/aggregator/values.yaml @@ -93,6 +93,7 @@ patroni: size: 10Gi compactor: + secret: sso-aggregator enabled: false retentionPeriod: '1 year' resources: diff --git a/helm/grafana/.env.example b/helm/grafana/.env.example index fdb3721..5a65551 100644 --- a/helm/grafana/.env.example +++ b/helm/grafana/.env.example @@ -27,28 +27,3 @@ DS_AGGREGATOR_DATABASE= LOKI_AUTH_TOKEN= API_GATEWAY_URL= -# # production creds -# NAME=sso-grafana -# NAMESPACE=eb75ad-tools -# SSO_CLIENT_ID= -# SSO_CLIENT_SECRET= - -# DS_SSO_LOGS_USERNAME= -# DS_SSO_LOGS_PASSWORD= -# DS_SSO_LOGS_DATABASE= - -# DS_KEYCLOAK_DEV_USERNAME= -# DS_KEYCLOAK_DEV_PASSWORD= -# DS_KEYCLOAK_DEV_DATABASE= - -# DS_KEYCLOAK_TEST_USERNAME= -# DS_KEYCLOAK_TEST_PASSWORD= -# DS_KEYCLOAK_TEST_DATABASE= - -# DS_KEYCLOAK_PROD_USERNAME= -# DS_KEYCLOAK_PROD_PASSWORD= -# DS_KEYCLOAK_PROD_DATABASE= - -# DS_AGGREGATOR_USERNAME= -# DS_AGGREGATOR_PASSWORD= -# DS_AGGREGATOR_DATABASE= diff --git a/helm/grafana/Makefile b/helm/grafana/Makefile index 77dcbb3..b8117a2 100644 --- a/helm/grafana/Makefile +++ b/helm/grafana/Makefile @@ -1,4 +1,4 @@ -include /$(PWD)/.env +-include /$(PWD)/.env SHELL := /usr/bin/env bash diff --git a/helm/grafana/values-eb75ad-tools.yaml b/helm/grafana/values-eb75ad-tools.yaml index 31b529c..4fe7f03 100644 --- a/helm/grafana/values-eb75ad-tools.yaml +++ b/helm/grafana/values-eb75ad-tools.yaml @@ -88,9 +88,13 @@ grafana: type: loki access: proxy orgId: 1 - url: http://sso-loki-gateway + url: basicAuth: false isDefault: true + jsonData: + httpHeaderName1: "Authorization" + secureJsonData: + httpHeaderValue1: - name: SSO Aggregator type: postgres access: proxy diff --git a/helm/promtail-loki/Makefile b/helm/promtail-loki/Makefile index e992dc7..804b4b5 100644 --- a/helm/promtail-loki/Makefile +++ b/helm/promtail-loki/Makefile @@ -1,8 +1,8 @@ -include /$(PWD)/.env +-include /$(PWD)/.env SHELL := /usr/bin/env bash NAMESPACE="" -NAME=sso-promtail-loki +NAME=sso-promtail-aws-loki ifndef NAMESPACE $(error NAMESPACE is not set) @@ -10,7 +10,7 @@ endif define arguments "${NAME}" . -n "${NAMESPACE}" -f values.yaml -f "values-${NAMESPACE}.yaml" \ - --set promtail.config.clients[0].headers.Authorization="Bearer ${LOKI_AUTH_TOKEN}" + --set promtail.config.clients[0].headers.Authorization="Bearer ${LOKI_AUTH_TOKEN}" \ --set promtail.config.clients[0].url="${API_GATEWAY_URL}/loki/api/v1/push" endef diff --git a/helm/promtail-loki/values.yaml b/helm/promtail-loki/values.yaml index 515e068..05ebabf 100644 --- a/helm/promtail-loki/values.yaml +++ b/helm/promtail-loki/values.yaml @@ -1,7 +1,7 @@ # see https://github.com/grafana/helm-charts/blob/main/charts/promtail/values.yaml promtail: - nameOverride: sso-promtail-loki - fullnameOverride: sso-promtail-loki + nameOverride: sso-promtail-aws-loki + fullnameOverride: sso-promtail-aws-loki daemonset: enabled: false @@ -47,7 +47,7 @@ promtail: defaultVolumes: - name: positions persistentVolumeClaim: - claimName: sso-promtail-loki-positions + claimName: sso-promtail-aws-loki-positions defaultVolumeMounts: - name: positions diff --git a/service-account-generator/README.md b/service-account-generator/README.md new file mode 100644 index 0000000..a1afd92 --- /dev/null +++ b/service-account-generator/README.md @@ -0,0 +1,20 @@ +# Generating service accounts for the CICD pipeline + +The github actions need service accounts to run. The script `generate_sa.sh` will create a service acount for the prod environment of a given openshift project and give that account the roles in the dev, test, and prod environments for deploying the repositorie's resources. + +## Generate the service accounts + +While logged into the **Gold** instance run: + +` +./generate_sa.sh <> +` + +The service account, roles, and rolebindings will be created. + +## Update the github action secrets + +Each service account will generate a secret in the `-prod` namespace with the name `sso-dashboard-deployer-<>-token-#####`. Copy this token into the GithHub secrets on this repos: + +SANDBOX_OPENSHIFT_TOKEN +PROD_OPENSHIFT_TOKEN diff --git a/service-account-generator/generator.sh b/service-account-generator/generator.sh new file mode 100755 index 0000000..602961f --- /dev/null +++ b/service-account-generator/generator.sh @@ -0,0 +1,51 @@ +#!/bin/bash +set -e + +usage() { + cat < + +Available licence plates: + - e4ca1d + - eb75ad + +Examples: + $ $0 e4ca1d +EOF +} + +if [ "$#" -lt 1 ]; then + usage + exit 1 +fi + +licence_plate=$1 + +# create service account in prod +oc -n "$licence_plate"-prod create sa sso-dashboard-deployer-"$licence_plate" + +create_role_and_binding() { + if [ "$#" -lt 2 ]; then exit 1; fi + licence_plate=$1 + env=$2 + namespace="$licence_plate-$env" + + oc process -f ./templates/role.yaml -p NAMESPACE="$namespace" | oc -n "$namespace" apply -f - + + oc -n "$namespace" create rolebinding sso-dashboard-deployer-role-binding-"$namespace" \ + --role=sso-dashboard-deployer-"$namespace" \ + --serviceaccount="$licence_plate"-prod:sso-dashboard-deployer-"$licence_plate" +} + +# for dev, test, prod and tools create the role and role binding +create_role_and_binding "$licence_plate" "tools" + +create_role_and_binding "$licence_plate" "prod" + +create_role_and_binding "$licence_plate" "test" + +create_role_and_binding "$licence_plate" "dev" diff --git a/service-account-generator/templates/role.yaml b/service-account-generator/templates/role.yaml new file mode 100644 index 0000000..68826f0 --- /dev/null +++ b/service-account-generator/templates/role.yaml @@ -0,0 +1,246 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: sso-dashboard-deployer-role-template +objects: +- kind: Role + apiVersion: authorization.openshift.io/v1 + metadata: + name: sso-dashboard-deployer-${NAMESPACE} + namespace: ${NAMESPACE} + labels: + created-by: local + role: deployer + annotations: + openshift.io/description: deployer + openshift.io/reconcile-protect: 'false' + rules: + - verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + attributeRestrictions: + apiGroups: + - '' + resources: + - configmaps + - endpoints + - persistentvolumeclaims + - pods + - pods/exec + - replicationcontrollers + - secrets + - services + - verbs: + - get + - list + - watch + attributeRestrictions: + apiGroups: + - '' + resources: + - pods/log + - pods/status + - verbs: + - create + - delete + - get + - list + - patch + - update + attributeRestrictions: + apiGroups: + - '' + resources: + - serviceaccounts + - verbs: + - list + attributeRestrictions: + apiGroups: + - '' + resources: + - events + - verbs: + - get + - list + - update + - watch + attributeRestrictions: + apiGroups: + - image.openshift.io + resources: + - imagestreamimages + - imagestreammappings + - imagestreams + - imagestreamtags + - verbs: + - create + - delete + - get + - list + - patch + - update + attributeRestrictions: + apiGroups: + - apps + resources: + - statefulsets + - verbs: + - create + - delete + - get + - list + - patch + - update + - watch + attributeRestrictions: + apiGroups: + - batch + resources: + - cronjobs + - jobs + - verbs: + - create + - delete + - get + - patch + - update + attributeRestrictions: + apiGroups: + - policy + resources: + - poddisruptionbudgets + - verbs: + - create + - delete + - get + - list + - patch + - update + attributeRestrictions: + apiGroups: + - rbac.authorization.k8s.io + - authorization.openshift.io + resources: + - rolebindings + - roles + - verbs: + - create + - delete + - get + - list + - patch + - update + attributeRestrictions: + apiGroups: + - apps + - extensions + resources: + - deployments + - replicasets + - verbs: + - create + - delete + - get + - list + - patch + - update + attributeRestrictions: + apiGroups: + - networking.k8s.io + resources: + - networkpolicies + - verbs: + - create + - delete + - get + - list + - patch + - update + attributeRestrictions: + apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + - verbs: + - delete + attributeRestrictions: + apiGroups: + - image.openshift.io + resources: + - imagestreamtags + - verbs: + - get + attributeRestrictions: + apiGroups: + - project.openshift.io + resources: + - projects + - verbs: + - create + - get + - patch + - update + attributeRestrictions: + apiGroups: + - apps.openshift.io + resources: + - deploymentconfigs + - verbs: + - create + - delete + - get + - patch + - update + attributeRestrictions: + apiGroups: + - route.openshift.io + resources: + - routes + - verbs: + - create + attributeRestrictions: + apiGroups: + - route.openshift.io + resources: + - routes/custom-host + - verbs: + - create + attributeRestrictions: + apiGroups: + - template.openshift.io + resources: + - processedtemplates + - verbs: + - create + - delete + - get + - list + - patch + - update + attributeRestrictions: + apiGroups: + - ops.gov.bc.ca + resources: + - sysdig-teams + - verbs: + - create + - delete + - get + - list + - patch + - update + attributeRestrictions: + apiGroups: + - porter.devops.gov.bc.ca + resources: + - transportserverclaims +parameters: +- name: NAMESPACE + required: true + description: the namespace the role is built in