281 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Org Mode
		
	
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Org Mode
		
	
	
	
	
	
#+TITLE: ROSA Ruby On Rails Workshop
 | 
						|
#+AUTHOR: James Blair
 | 
						|
#+DATE: <2023-08-18 Fri 13:30>
 | 
						|
 | 
						|
* Introduction
 | 
						|
 | 
						|
This document captures the setup steps for a 90-minute, hands-on [[https://rubyonrails.org/][Ruby On Rails]] workshop on [[https://www.redhat.com/en/technologies/cloud-computing/openshift][Openshift]].
 | 
						|
 | 
						|
Within the session, participants will:
 | 
						|
 - Gain an understanding of OpenShift and containers.
 | 
						|
 - Work with a Ruby codebase in [[https://bitbucket.org/product/][Bitbucket]].
 | 
						|
 - Deploy the application on Openshift using several methods.
 | 
						|
 - Create continuous delivery pipelines with [[https://tekton.dev/docs/][Tekton]].
 | 
						|
 | 
						|
* Pre-requisites
 | 
						|
 | 
						|
 This guide assumes you have an existing Openshift 4.10+ cluster with cluster admin permissions.
 | 
						|
 | 
						|
 In my case I have a Red Hat OpenShift on AWS (ROSA) cluster provisioned through the Red Hat [[https://demo.redhat.com][demo system]].
 | 
						|
 | 
						|
 | 
						|
* 1 - Preparing the cluster
 | 
						|
 | 
						|
To get start let's ensure we are logged in to the cluster in our terminal with the ~oc~ cli.
 | 
						|
 | 
						|
#+begin_src bash
 | 
						|
oc login --server <URL> --token <TOKEN>
 | 
						|
#+end_src
 | 
						|
 | 
						|
 | 
						|
* 2 - Deploy Bitbucket
 | 
						|
 | 
						|
Now that we're logged into the cluster, let's create the namespace to deploy Bitbucket into.
 | 
						|
 | 
						|
#+begin_src bash :results output
 | 
						|
oc new-project bitbucket
 | 
						|
#+end_src
 | 
						|
 | 
						|
#+RESULTS:
 | 
						|
#+begin_example
 | 
						|
Now using project "bitbucket" on server "https://api.rosa-zc2fk.nhwo.p1.openshiftapps.com:6443".
 | 
						|
 | 
						|
You can add applications to this project with the 'new-app' command. For example, try:
 | 
						|
 | 
						|
    oc new-app rails-postgresql-example
 | 
						|
 | 
						|
to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:
 | 
						|
 | 
						|
    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname
 | 
						|
 | 
						|
#+end_example
 | 
						|
 | 
						|
Once the namespace is created we can deploy Bitbucket using the official Bitbucket image from Atlassian.
 | 
						|
 | 
						|
#+begin_src bash :results output
 | 
						|
cat << EOF | oc --namespace bitbucket apply --filename -
 | 
						|
kind: Deployment
 | 
						|
apiVersion: apps/v1
 | 
						|
metadata:
 | 
						|
  name: bitbucket
 | 
						|
  namespace: bitbucket
 | 
						|
  labels:
 | 
						|
    app: bitbucket
 | 
						|
spec:
 | 
						|
  replicas: 1
 | 
						|
  selector:
 | 
						|
    matchLabels:
 | 
						|
      deployment: bitbucket
 | 
						|
  template:
 | 
						|
    metadata:
 | 
						|
      labels:
 | 
						|
        deployment: bitbucket
 | 
						|
    spec:
 | 
						|
      volumes:
 | 
						|
        - name: bitbucket-volume
 | 
						|
          emptyDir: {}
 | 
						|
      containers:
 | 
						|
        - name: bitbucket
 | 
						|
          image: docker.io/atlassian/bitbucket-server@sha256:30556d63fc935a1c3c9da41e6fff617e452ad7a52060a92b6a20f9179dd637a5
 | 
						|
          ports:
 | 
						|
            - containerPort: 7990
 | 
						|
              protocol: TCP
 | 
						|
            - containerPort: 7999
 | 
						|
              protocol: TCP
 | 
						|
          resources:
 | 
						|
            limits:
 | 
						|
              cpu: 500m
 | 
						|
              memory: 4096Mi
 | 
						|
          volumeMounts:
 | 
						|
            - name: bitbucket-volume
 | 
						|
              mountPath: /var/atlassian/application-data/bitbucket
 | 
						|
          terminationMessagePath: /dev/termination-log
 | 
						|
          terminationMessagePolicy: File
 | 
						|
          imagePullPolicy: IfNotPresent
 | 
						|
      restartPolicy: Always
 | 
						|
      terminationGracePeriodSeconds: 30
 | 
						|
      dnsPolicy: ClusterFirst
 | 
						|
      securityContext: {}
 | 
						|
      schedulerName: default-scheduler
 | 
						|
  strategy:
 | 
						|
    type: RollingUpdate
 | 
						|
    rollingUpdate:
 | 
						|
      maxUnavailable: 25%
 | 
						|
      maxSurge: 25%
 | 
						|
  revisionHistoryLimit: 10
 | 
						|
  progressDeadlineSeconds: 600
 | 
						|
EOF
 | 
						|
#+end_src
 | 
						|
 | 
						|
#+RESULTS:
 | 
						|
: deployment.apps/bitbucket created
 | 
						|
 | 
						|
Now, let's verify that the Bitbucket pod started successfully.
 | 
						|
 | 
						|
#+begin_src bash :results output
 | 
						|
oc --namespace bitbucket get pods
 | 
						|
#+end_src
 | 
						|
 | 
						|
#+RESULTS:
 | 
						|
: NAME                         READY   STATUS    RESTARTS   AGE
 | 
						|
: bitbucket-74bc96b849-5nbvl   1/1     Running   0          45s
 | 
						|
 | 
						|
As this is running successfully, let's expose it with a ~route~ so that we can access it from our web browser.
 | 
						|
 | 
						|
#+begin_src bash :results output
 | 
						|
oc --namespace bitbucket create route edge bitbucket --service=bitbucket --port=7990
 | 
						|
oc --namespace bitbucket get route
 | 
						|
#+end_src
 | 
						|
 | 
						|
#+RESULTS:
 | 
						|
: route.route.openshift.io/bitbucket created
 | 
						|
: NAME        HOST/PORT                                                       PATH   SERVICES    PORT   TERMINATION   WILDCARD
 | 
						|
: bitbucket   bitbucket-bitbucket.apps.rosa-zc2fk.nhwo.p1.openshiftapps.com          bitbucket   7990   edge          None
 | 
						|
 | 
						|
Once we open the Bitbucket route in our browser, we need to follow a short setup process manually before we can continue with the rest of our automation.
 | 
						|
 | 
						|
 1. Select your language ~English (United States)~.
 | 
						|
 2. Select ~internal~ and click ~Next~.
 | 
						|
 | 
						|
You'll then be prompted for an Atlassian license key. For the purposes of this workshop, we'll be generating a new trial license [[https://my.atlassian.com/license/evaluation][here]].
 | 
						|
 | 
						|
Copy the ~Server ID~ into the Bitbucket setup screen and click ~Generate License~.
 | 
						|
 | 
						|
Copy the generated license key into the text box for the Bitbucket license key and click ~Next~.
 | 
						|
 | 
						|
On the Bitbucket setup screen enter details for your administrative user and click ~Go to Bitbucket~.
 | 
						|
 | 
						|
 | 
						|
* 3 - Configure Bitbucket
 | 
						|
 | 
						|
With our Bitbucket server successfully deployed, let's configure it for the workshop.
 | 
						|
 | 
						|
First step is to create additional users.
 | 
						|
 | 
						|
#+begin_src bash :results none
 | 
						|
source .env
 | 
						|
bitbucket_route=$(oc get route --namespace bitbucket | awk '{print $2}'  | tail -n 1)
 | 
						|
for user in {1..30}; do
 | 
						|
 | 
						|
  echo curl --user "admin:${bitbucket_password}" \
 | 
						|
            --header "'Content-Type: application/json'" \
 | 
						|
            --header "'X-Atlassian-Token: nocheck'" \
 | 
						|
            --request "POST" \
 | 
						|
            "\"https://${bitbucket_route}/rest/api/latest/admin/users?name=user${user}&displayName=user${user}&emailAddress=user${user}%40example.com&password=${bitbucket_user_password}\"" >> users.sh
 | 
						|
 | 
						|
done
 | 
						|
chmod +x users.sh && ./users.sh && rm users.sh
 | 
						|
#+end_src
 | 
						|
 | 
						|
 | 
						|
Each of these users will be forking a copy of a Ruby on Rails codebase, so let's now create that codebase now.
 | 
						|
 | 
						|
#+begin_src bash :results none
 | 
						|
source .env
 | 
						|
bitbucket_route=$(oc get route --namespace bitbucket | awk '{print $2}'  | tail -n 1)
 | 
						|
echo curl --user "admin:${bitbucket_password}" \
 | 
						|
          --header "'Content-Type: application/json'" \
 | 
						|
          --data "'{ \"key\": \"MSD\", \"name\": \"Rails Team\", \"description\": \"Rails!\"}'" \
 | 
						|
          "https://${bitbucket_route}/rest/api/latest/projects" > project.sh
 | 
						|
 | 
						|
echo curl --user "admin:${bitbucket_password}" \
 | 
						|
          --header "'Content-Type: application/json'" \
 | 
						|
          --data "'{\"name\": \"rails-example\",\"scmId\": \"git\", \"forkable\": true, \"public\": true }'" \
 | 
						|
          "https://${bitbucket_route}/rest/api/latest/projects/${project_key}/repos" >> project.sh
 | 
						|
 | 
						|
chmod +x project.sh && ./project.sh && rm project.sh
 | 
						|
 | 
						|
git clone https://github.com/sclorg/rails-ex.git
 | 
						|
cd rails-ex
 | 
						|
git remote set-url origin "https://admin:${bitbucket_password}@${bitbucket_route}/scm/msd/rails-example.git"
 | 
						|
git push -u origin HEAD:master && cd ../ && rm -rf rails-ex
 | 
						|
#+end_src
 | 
						|
 | 
						|
 | 
						|
* 4 - Install openshift pipelines operator
 | 
						|
 | 
						|
Once bitbucket is installed and is setup with the users and codebase our workshop will use lets install the [[https://docs.openshift.com/container-platform/4.10/cicd/pipelines/understanding-openshift-pipelines.html][OpenShift Pipelines]] operator so our workshop participants will be able to create and run Tekton CI/CD pipelines during the workshop.
 | 
						|
 | 
						|
The first step for installing the operator  is to create a subscription
 | 
						|
 | 
						|
#+begin_src bash :results output
 | 
						|
cat << EOF | oc apply --filename -
 | 
						|
apiVersion: operators.coreos.com/v1alpha1
 | 
						|
kind: Subscription
 | 
						|
metadata:
 | 
						|
  name: openshift-pipelines-operator
 | 
						|
  namespace: openshift-operators
 | 
						|
spec:
 | 
						|
  channel: latest
 | 
						|
  name: openshift-pipelines-operator-rh
 | 
						|
  source: redhat-operators
 | 
						|
  sourceNamespace: openshift-marketplace
 | 
						|
EOF
 | 
						|
#+end_src
 | 
						|
 | 
						|
#+RESULTS:
 | 
						|
: subscription.operators.coreos.com/openshift-pipelines-operator configured
 | 
						|
 | 
						|
 | 
						|
* 5 - Install openshift web terminal operator
 | 
						|
 | 
						|
Another helpful operator that we will use during the workshop is the [[https://cloud.redhat.com/blog/a-deeper-look-at-the-web-terminal-operator-1][OpenShift Web Terminal]]. This is a handy way to access a terminal directly within the OpenShift Web Console.
 | 
						|
 | 
						|
#+begin_src bash :results output
 | 
						|
cat << EOF | oc apply --filename -
 | 
						|
apiVersion: operators.coreos.com/v1alpha1
 | 
						|
kind: Subscription
 | 
						|
metadata:
 | 
						|
  name: web-terminal
 | 
						|
  namespace: openshift-operators
 | 
						|
spec:
 | 
						|
  channel: fast
 | 
						|
  installPlanApproval: Automatic
 | 
						|
  name: web-terminal
 | 
						|
  source: redhat-operators
 | 
						|
  sourceNamespace: openshift-marketplace
 | 
						|
EOF
 | 
						|
#+end_src
 | 
						|
 | 
						|
#+RESULTS:
 | 
						|
: subscription.operators.coreos.com/web-terminal created
 | 
						|
 | 
						|
 | 
						|
* 6 - Install openshift serverless operator
 | 
						|
 | 
						|
For our final cluster setup task we will install the [[https://www.redhat.com/en/technologies/cloud-computing/openshift/serverless][OpenShift Serverless]] operator. We'll use this during the workshop to show just how easy it is to convert a traditional Ruby application deployment into a serverless scale to zero application.
 | 
						|
 | 
						|
#+begin_src bash :results output
 | 
						|
cat << EOF | oc apply --filename -
 | 
						|
apiVersion: operators.coreos.com/v1alpha1
 | 
						|
kind: Subscription
 | 
						|
metadata:
 | 
						|
  name: serverless-operator
 | 
						|
  namespace: openshift-operators
 | 
						|
spec:
 | 
						|
  channel: stable
 | 
						|
  name: serverless-operator
 | 
						|
  source: redhat-operators
 | 
						|
  sourceNamespace: openshift-marketplace
 | 
						|
EOF
 | 
						|
#+end_src
 | 
						|
 | 
						|
#+RESULTS:
 | 
						|
: subscription.operators.coreos.com/serverless-operator created
 | 
						|
 | 
						|
 | 
						|
Once the operator is installed we just need to enable ~knative~ serving.
 | 
						|
 | 
						|
#+begin_src bash :results output
 | 
						|
cat << EOF | oc apply --filename -
 | 
						|
apiVersion: operator.knative.dev/v1beta1
 | 
						|
kind: KnativeServing
 | 
						|
metadata:
 | 
						|
    name: knative-serving
 | 
						|
    namespace: knative-serving
 | 
						|
EOF
 | 
						|
#+end_src
 | 
						|
 | 
						|
#+RESULTS:
 | 
						|
: knativeserving.operator.knative.dev/knative-serving created
 |