GitLab

If you already have a Git repository consider using that and skip this step.

Note: To complete this task, you must be a cluster administrator.

Add the Helm Charts Repository

Add the charts repository to the local registry and update the local chart repositories.

helm repo add gitlab https://charts.gitlab.io/
helm repo update

Adjust GitLab Configuration

Create a file named gitlab-values.yaml based on the example configuration as seen below and replace {CLUSTER_DOMAIN} with the base domain of your cluster and change {GITLAB_URI} to the URL at which you want to access your GitLab instance.

Example GitLab Configuration

# Example values for gitlab/gitlab chart

## NOTICE
# Due to the scope and complexity of this chart, all possible values are
# not documented in this file. Extensive documentation for these values
# and more can be found at https://gitlab.com/gitlab-org/charts/gitlab/

## The global properties are used to configure multiple charts at once.
## Extended documentation at doc/charts/globals.md
global:
  ## GitLab operator is Alpha. Not for production use.
  operator:
    enabled: false
    rollout:
      # Enables automatic pause for deployment rollout. This must be set to `true` to fix
      # Helm's issue with 3-way merge. See: 
      #   https://gitlab.com/gitlab-org/charts/gitlab/issues/1262
      #   https://github.com/helm/helm/issues/3805
      autoPause: true

  ## doc/installation/deployment.md#deploy-the-community-edition
  edition: ce

  ## doc/charts/globals.md#gitlab-version
  # gitlabVersion: master

  ## doc/charts/globals.md#application-resource
  application:
    create: false
    links: [ ]
    allowClusterRoles: true
  ## doc/charts/globals.md#configure-host-settings
  hosts:
    domain: { CLUSTER_DOMAIN }
    https: false
    gitlab:
      name: { GITLAB_URI }

  ## doc/charts/globals.md#configure-ingress-settings
  ingress:
    configureCertmanager: false
    annotations: { }
    enabled: true
    tls:
      enabled: false
      secretName: gitlab-tls-secret

  gitlab:
  initialRootPassword: { }

  psql:
    password: { }

  redis:
    password:
      enabled: true

  gitaly:
    enabled: true
    authToken: { }
    # secret: 
    # key: 
    serviceName: gitlab-unicorn
    internal:
      names: [ 'default' ]
    external: [ ]
    tls:
      enabled: false

  ## doc/charts/globals.md#configure-minio-settings
  minio:
    enabled: true
    credentials: { }
    # secret: 

  ## doc/charts/globals.md#configure-grafana-integration
  grafana:
    enabled: false

  ## doc/charts/globals.md#configure-appconfig-settings
  ## Rails based portions of this chart share many settings
  appConfig:
    ## doc/charts/globals.md#general-application-settings
    enableUsagePing: true
    enableSeatLink: true
    enableImpersonation:
    defaultCanCreateGroup: true
    usernameChangingEnabled: true
    issueClosingPattern:
    defaultTheme:
    defaultProjectsFeatures:
      issues: true
      mergeRequests: true
      wiki: true
      snippets: true
      builds: true
    webhookTimeout:
    maxRequestDurationSeconds:

    ## doc/charts/globals.md#cron-jobs-related-settings
    cron_jobs: { }
    ## doc/charts/globals.md#gravatarlibravatar-settings
    gravatar:
      plainUrl:
      sslUrl:

    ## doc/charts/globals.md#hooking-analytics-services-to-the-gitlab-instance
    extra:
      googleAnalyticsId:
      piwikUrl:
      piwikSiteId:

    ## doc/charts/globals.md#omniauth
    omniauth:
      enabled: true
      autoSignInWithProvider:
      syncProfileFromProvider: [ ]
      syncProfileAttributes: [ 'email' ]
      allowSingleSignOn: [ 'saml' ]
      blockAutoCreatedUsers: true
      autoLinkLdapUser: false
      autoLinkSamlUser: false
      externalProviders: [ ]
      allowBypassTwoFactor: [ ]
      providers:
        - secret: gitlab-oauth2
          key: provider

  ## End of global.appConfig

  ## doc/charts/geo.md
  geo:
    enabled: false

  ## doc/charts/globals.md#configure-gitlab-shell-settings
  shell:
    authToken: { }
    # secret: 
    # key: 
    hostKeys: { }
    # secret: 

  ## Rails application secrets
  ## Secret created according to doc/installation/secrets.md#gitlab-rails-secret
  ## If allowing shared-secrets generation, this is OPTIONAL.
  railsSecrets: { }
  # secret: 

  ## Rails generic setting, applicable to all Rails-based containers
  rails:
    bootsnap: # Enable / disable Shopify/Bootsnap cache
      enabled: true

  ## doc/charts/globals.md#configure-registry-settings
  registry:
    bucket: registry
    certificate: { }
    # secret: 
    httpSecret: { }
    # secret: 
    # key: 

  ## GitLab Runner
  ## Secret created according to doc/installation/secrets.md#gitlab-runner-secret
  ## If allowing shared-secrets generation, this is OPTIONAL.
  runner:
    registrationToken: { }
    # secret: 

  ## Timezone for containers.
  time_zone: UTC

  ## Global Service Annotations
  service:
    annotations: { }

  ## Global Deployment Annotations
  deployment:
    annotations: { }

  antiAffinity: soft

  ## doc/installation/secrets.md#gitlab-workhorse-secret
  workhorse: { }
  # secret: 
  # key: 

  ## doc/charts/globals.md#configure-unicorn
  webservice:
    workerTimeout: 60

  ## doc/charts/globals.md#custom-certificate-authorities
  # configuration of certificates container & custom CA injection
  certificates:
    image:
      repository: registry.gitlab.com/gitlab-org/build/cng/alpine-certificates
      tag: 20171114-r3
    customCAs: [ ]
    # - secret: custom-CA
    # - secret: more-custom-CAs

  ## kubectl image used by hooks to carry out specific jobs
  kubectl:
    image:
      repository: registry.gitlab.com/gitlab-org/build/cng/kubectl
      tag: 1.13.12
      pullSecrets: [ ]
    securityContext:
      # in most base images, this is `nobody:nogroup`
      runAsUser: 65534
      fsGroup: 65534
  busybox:
    image:
      repository: busybox
      tag: latest
## End of global

upgradeCheck:
  enabled: true
  image: { }
  # repository: 
  # tag: 
  securityContext:
    # in alpine/debian/busybox based images, this is `nobody:nogroup`
    runAsUser: 65534
    fsGroup: 65534
  tolerations: [ ]
  resources:
    requests:
      cpu: 50m

## Installation & configuration of jetstack/cert-manager
## See requirements.yaml for current version
certmanager:
  createCustomResource: true
  nameOverride: cert-manager
  # Install cert-manager chart. Set to false if you already have cert-manager
  # installed or if you are not using cert-manager.
  install: false
  # Other cert-manager configurations from upstream
  # See https://github.com/jetstack/cert-manager/blob/master/deploy/charts/cert-manager/README.md#configuration
  rbac:
    create: true
  webhook:
    enabled: false

## doc/charts/nginx/index.md
## doc/architecture/decisions.md#nginx-ingress
## Installation & configuration of charts/nginx
nginx-ingress:
  enabled: false

## Installation & configuration of stable/prometheus
## See requirements.yaml for current version
prometheus:
  install: false

## Installation & configuration of stable/prostgresql
## See requirements.yaml for current version
postgresql:
  postgresqlUsername: gitlab
  # This just needs to be set. It will use a second entry in existingSecret for postgresql-postgres-password
  postgresqlPostgresPassword: bogus
  install: true
  postgresqlDatabase: gitlabhq_production

  usePasswordFile: true
  #existingSecret: 'bogus'
  initdbScriptsConfigMap: 'bogus'
  metrics:
    enabled: true
    ## Optionally define additional custom metrics
    ## ref: https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file

## Installation & configuration charts/registry
## doc/architecture/decisions.md#registry
## doc/charts/registry/
# registry: 
#   enabled: false

## Automatic shared secret generation
## doc/installation/secrets.md
## doc/charts/shared-secrets
shared-secrets:
  enabled: true
  rbac:
    create: true

## Installation & configuration of gitlab/gitlab-runner
## See requirements.yaml for current version
gitlab-runner:
  install: false
  rbac:
    create: false
  runners:
    locked: false
    cache:
      cacheType: s3
      s3BucketName: runner-cache
      cacheShared: true
      s3BucketLocation: us-east-1
      s3CachePath: gitlab-runner
      s3CacheInsecure: false

## Settings for individual sub-charts under GitLab
gitlab:
  ## doc/charts/gitlab/task-runner
  task-runner:
    replicas: 1
Note: In this configuration example, global.hosts.https and global.ingress.tls are intentionally disabled to prevent issues caused by self-signed certificates. If GitLab is installed based on the Helm Chart 'gitlab/gitlab', it will install the latest version of Gitlab for which a Helm Chart exists. For future versions of Gitlab, this sample configuration may need to be adjusted to the latest default configuration of gitlab/values.yaml ( see version-specific changes in the upgrade documentation for GitLab).

Create Keycloak Realm

For using Keycloak as identity provider for GitLab authorization the following steps are necessary:

Create the Realm

Create a realm fsw (called below {KEYCLOAK_REALM} ) and change to this realm:

  1. Go to the Add realm page

  2. Enter name: fsw

  3. Click Create

This realm will be later also used by Solution Designer to store the users and their roles.

Create a Keycloak Client

Note: {GITLAB_URI} refers to the URL, where GitLab will be available in your cluster.
  1. Navigate to the Configure → Clients page

  2. Click the Create button in the right upper corner of the table

  3. Set the following parameters:

    • Client ID: gitlab-client

    • Client Protocol: openid-connect

    • Root URL: {GITLAB_URI}

  4. Create the client by clicking on Save

  5. In the client configuration page Clients → gitlab-client set the following parameters:

    • Access Type: confidential (Need to be set first)

    • Standard Flow Enabled: ON

    • Implicit Flow Enabled: ON

    • Direct Access Grants Enabled: ON

    • Service Accounts Enabled: ON

    • Authorization Enabled: ON

    • Valid Redirect URIs: {GITLAB_URI}/*

    • Web Origins: {GITLAB_URI}

    • Save the configuration by clicking on Save

  6. Navigate to the tab Mappers in the Clients → gitlab-client page

  7. Click the Builtin button in the right upper corner of the table

  8. Select the following built-in token mappers of type User Property

    • email

    • username

    • given name

    • full name

    • family name

  9. Add selected mappers by clicking on Add selected

  10. Navigate to the tab Credentials in the Clients → gitlab-client page

  11. Save the secret (called below {KEYCLOAK_CLIENT_SECRET}) that is used to create the gitlab-oauth2 secret

Create the OAuth Secret

The following steps show how to enable the OAuth authorization using Keycloak as identity provider:

  1. Define the configuration of the OAuth authorization and save it in an environment variable:

    • {KEYCLOAK_CLIENT_SECRET} refers to the Keycloak Client secret of Create a Keycloak Client

    • {KEYCLOAK_URI} refers to the Keycloak URL of project foundation in the cluster

    • {KEYCLOAK_REALM} refers to the realm fsw of Create the Realm

     export OMNI_AUTH_CFG="name: 'oauth2_generic'
     app_id: 'gitlab-client'
     app_secret: '{KEYCLOAK_CLIENT_SECRET}'
     args:  
         client_options:
         site: 'https://{KEYCLOAK_URI}'
         user_info_url: '/auth/realms/{KEYCLOAK_REALM}/protocol/openid-connect/userinfo'
         authorize_url: '/auth/realms/{KEYCLOAK_REALM}/protocol/openid-connect/auth'
         token_url: '/auth/realms/{KEYCLOAK_REALM}/protocol/openid-connect/token'
         user_response_structure:
         id_path: 'sub'
         attributes:
             name: 'name'
             email: 'email'
             nickname: 'username'
             first_name: 'given_name'
             last_name: 'family_name'"
  2. Create a secret containing the omni-auth config. The secret must be named gitlab-oauth2 and should contain the key named provider with the previously created content

     $ oc -n foundation-gitlab create secret generic \
     "gitlab-oauth2" --type="Opaque" \
     --from-literal="provider"="${OMNI_AUTH_CFG}"
Note: The secret gitlab-oauth2 is configured in the Example GitLab Configuration ( global.appConfig.omniauth.providers.secret)

Create the TLS Secret

Create a secret containing the TLS settings. The files are referring to the certificate chain and the private key, that are used for SSL communication with the cluster. Commonly these are the same certificate settings as they are used for the default router certificate.

Note: The secret router-certs-{name} (where {name} is the name of the Ingress Controller) in the openshift-ingress namespace contains the default certificate generated by the operator. See User-provided certificates for default ingress.
# Export default router certificates from openshift-ingress namespace
$ oc get secret router-certs-default -n openshift-ingress -o yaml|grep -A2 '^data:'|tail -2 | awk -F: '{system("echo "$2" |base64 --decode > "$1)}'
# Create gitlab-tls-secret in namespace gitlab
$ oc -n foundation-gitlab create secret tls \
gitlab-tls-secret \
--cert=./tls.crt \
--key=./tls.key
# Remove temporary created certificate files
rm ./tls.crt ./tls.key

Create Security Context Constraints

Create a SecurityContextConstraint (SCC) that allows you that these serviceaccounts can run as any user.

oc -n foundation-gitlab adm policy add-scc-to-user anyuid -z default
oc -n foundation-gitlab adm policy add-scc-to-user anyuid -z gitlab-shared-secrets
Note: The Security Context Constraint (SCC) anyuid for the service account default has negative effects on other Pods that require storage space, typically databases, resulting in insufficient permissions within the containers. Therefore, the separate project gitlab-foundation is used for the GitLab installation.

Start the Helm Chart Installation

Note: The helm certificate and key files in the folder {cert_folder} that were created in section Install Helm Tiller with TLS are used to run the helm install command.

Run the helm install command and pass in the configuration file:

# To do - Replace placeholder {cert_folder}
$ export SECRET_FOLDER={cert_folder}
$ export HELM_TLS_CA_CERT=$SECRET_FOLDER/ca.pem
$ export HELM_TLS_CERT=$SECRET_FOLDER/cert.pem
$ export HELM_TLS_KEY=$SECRET_FOLDER/key.pem
$ helm upgrade --tls --install gitlab gitlab/gitlab \
  --timeout 600 \
  -f gitlab-values.yaml \
  --namespace foundation-gitlab \
  --tiller-namespace foundation-gitlab
Note: To test the helm chart you can use the options --dry-run --debug.

Now gitlab installation should start create a new release. The command returns immediately and does not wait until the app's cluster objects are ready.

You can find the new gitlab release by running the ls command:

helm ls

Validate the GitLab Installation

Check on the status of the release by running the status command:

helm status gitlab --tls --tiller-namespace foundation-gitlab 

Wait until all cluster objects of this release are ready, and when it is ready, you can access GitLab using the URL specified by {GITLAB_URI} in the sample configuration file gitlab-values.yaml, or by inspecting the route.

oc -n foundation get route

To login use the initial password of the root account. It was placed in a secret, that ends with -initial-root-password.

oc -n foundation-gitlab get secret gitlab-gitlab-initial-root-password -o jsonpath="{.data.password}" | base64 -d; echo