OPENSHIFT

Security Pipelines in OpenShift Container Platform

#security , #platform , #containers

Security Pipelines in OpenShift Container Platform

These are random notes for work in progress coded at https://github.com/briantward/container-pipelines/tree/parallel-spring-boot

- two OCP clusters: nonprod (dev, test, etc) and prod (prod, stage)
- allow nonprod cluster to continue pulling image updates automatically to registry
- have separate registries between nonprod and prod
- new builds only happen in nonprod, never in prod
- existing dev pipeline must be aware of possible update to deployed container by alternative parallel pipeline route and keep base image in sync

- new security pipeline, parallel to existing dev pipeline:
-- poll for updates to images in nonprod cluster
--- polling will check similar to what happens when the nonprod cluster syncs from RH Registry
--- can we capture a log of the updates from RH registry and just act on them? - prob not a good idea
--- or perform a diff between nonprod and prod registries?
--- "I am app A, need access to container X, Y, Z latest builds"
--- Define: latest build
-- run any application specific tests (?), i.e. smoke tests
--- this requires the process to be built independently for EVERY application, and effectively must be a CI pipeline
-- queue for manual verification by users before pushing to production cluster
--- this would allow scheduling of the final push to the prod cluster (scheduling could be automatic based on programmed times/behaviors, send an email to notify admins what is happening)
--- the prod cluster would have DC set to update/rollout on ImageChange, or would have to change the tag in the DC.  If going to a stage env inside prod cluster first, may need to change tags instead of rely on ImageChange (which would kick off both stage and prod at same time).
--- users will want to know what running containers are affected
--- users schedule a time the push to prod cluster happens
--- or alternatively, users push immediately
--- users will want a status update (email?) by each image update


- new security pipeline, parallel to existing dev pipeline:
-- poll for updates to core images from RHCC (--scheduled=true)
--- Application with tag "app-v1.2.3" updates to "app-v1.2.3" (no change in tag) based on seeing a change in underlying image, kicks off build trigger, then kicks off deploy trigger
-- poll for updates to images in nonprod cluster (check existing image sha256 in dev registry "app-v1.2.3" and compares it to prod registry "app-v1.2.3-0001"
--- Define: latest build. Application with tag "app-v1.2.3-0001" updates to "app-v1.2.3-0002" based on dev environment change to sha256 and
-- run any application specific tests (?), i.e. smoke tests
--- this requires the process to be built independently for EVERY application, and effectively must be a CI pipeline
-- queue for manual verification by users before pushing to production cluster
--- this would allow manual scheduling of the final push to the prod cluster
--- change the dc to match with latest build tag, or keep same build tag and just do a rollout?
--- users will want to know what running containers are affected
--- users schedule a time the push to prod cluster happens
--- or alternatively, users push immediately
--- users will want a status update (email?) by each image update


app-dev
- dc app-v1.0.0-indev
- dc app-v1.0.1-secup
app-stage
- dc app-v1.0.0-indev
- dc app-v1.0.1-secup
- dc app-v1.0.0-live
app-prod
- dc app-v1.0.0-live
- dc app-v1.0.1-secup

app-dev
- bc app-indev (v1.1.0)
- bc app-secup (v1.0.1) (BC updated with latest dev @ end of Dev Pipeline, after Dev Image pushed to Prod)
- dc app-indev (v1.1.0) (No Build/Deploy Triggers, relies on Jenkins Pipelines)
- dc app-secup (v1.0.1) (Build/Deploy Trigger)
- route http://app-indev.dev.example.com
- route http://app-secup.dev.example.com
app-stage
- dc app-indev (v1.1.0)
- dc app-secup (v1.0.1) (Build/Deploy Trigger)
- dc app-live (v1.0.0)
- route http://app-indev.stage.example.com
- route http://app-secup.stage.example.com
- route http://app-live.stage.example.com
app-prod
- dc app-live (v1.0.0)
- dc app-secup (v1.0.1)
- route http://app.example.com
- switch using Blue/Green or A/B deployment strategy, controlled manually or by Pipelines
oc run -i -t tool-box-test --image=quay.io/redhat-cop/tool-box --rm bash
git clone -b ab-secup https://github.com/briantward/container-pipelines
cd container-pipelines/basic-spring-boot/
ansible-galaxy install -r requirements.yml --roles-path=galaxy
oc login -u developer -p any https://192.168.42.56:8443
ansible-playbook -i ./.applier/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml

if security updates are critical or important, move forward, otherwise, do not update if dev work not current, then kick off on schedule

kick off security pipeline - something notices a new container from RHCC (automatic sync is in progress) - comparing the base image from BuildConfig of original project to results from RHCC automation - send email to team with review and manual approval gate (to make them aware), optional remove this is easy

install a buildconfig with a trigger of image change on whatever is the base buildconfig

swap A/B in pipeline (either original or secup) - checks to see which service name is currently present - deploys to prod immediately, with the not-current service name used - waits on switching the route from service current to not-current

def currentState = 'green'
def newState = 'blue'


openshift.withCluster() {
            openshift.withProject(PROD) {
              def activeService = openshift.selector("route/${APP_NAME}").object().spec.to.name
              if (activeService == "${APP_NAME}-blue") {
                newState = 'green'
                currentState = 'blue'
              }
              def dc = openshift.selector("dc/${APP_NAME}-${newState}").object()
              def trigger_patch =  [
                ["type":"ImageChange",
                 "imageChangeParams":[
                   "automatic": true,
                   "containerNames": ["${APP_NAME}-${newState}"],
                   "from":[
                     "kind":"ImageStreamTag",
                     "namespace":PROD,
                     "name":"${APP_NAME}-${newState}:${version}"
                   ]
                 ]
                ],
                ["type":"ConfigChange"]
              ]
              dc.spec.triggers = trigger_patch
              openshift.apply(dc)
            }
          }

security gate is one time switch need it to be many make regular service-A on start Pipeline must always check service to deploy to and update DC.