a. Shared functionality
Reusable scripts and templates
I reused the Helm deployment script across SIT, UAT and production. HPB also provided shared scripts for tasks such as image scanning, which I integrated into the pipelines.
Technical deep dive · Health Promotion Board · CI/CD
Rebuilding delivery around environment-specific runners, reusable scripts and the checks required for an AKS deployment.
I was the main engineer for this migration at Health Promotion Board, Singapore, during my Thoughtworks engagement. This page explains the implementation behind the HPB case study .
01 / Environment preparation
The migration began with access and runner-host preparation. Each environment had one runner VM in a designated network segment, managed through VPN and a bastion host.
Manage the designated hosts
02 / Script structure
I reviewed the Bamboo steps, their dependencies and their expected results. This established which tasks had to remain when the workflow moved to GitLab CI/CD.
Some inherited scripts mixed several responsibilities. I rewrote most of them, separating common functionality from task-specific work and building reusable GitLab steps around those boundaries.
a. Shared functionality
I reused the Helm deployment script across SIT, UAT and production. HPB also provided shared scripts for tasks such as image scanning, which I integrated into the pipelines.
b. Specific responsibilities
Work specific to a particular task stayed separate, making the script structure clearer and easier to follow.
I also adapted the environment automation and security-scanning integration. The pipeline, its scripts and the hosts running them needed to work together in the migrated environment.
03 / SIT pipeline
Creating a pull request triggered the SIT pipeline automatically. The deployment counted as successful after every stage passed, including the checks after the Helm deployment.
Check source and build the package
Build, check and publish the image
Deploy and check the running application
All stages pass
Fortify on Demand (FOD) provided the SAST/DAST integration. The workflow also used other scanning tools, including SonarQube. Code, dependency and image checks had separate places in the sequence; DAST followed deployment and application-status checks.
04 / Environment differences
Access between environments was strictly restricted. SIT, UAT and PRD each built and deployed from the same code for a given release version. We did not promote one immutable package or image through all three environments.
Build and deploy separately
Automatic deploymentBuild and deploy separately
Manual confirmationBuild and deploy separately
Manual confirmationMigration order: I completed and validated the SIT/UAT migration work before progressing PRD, reusing the work already prepared. This migration sequence was separate from the release controls shown above.
05 / Validation & outcome
All stages had to pass for a SIT deployment to count as successful. The wider migration was completed after the environment, access and scanning dependencies were resolved and the required validation passed.
Delivery responsibilities and cross-team coordination06 / Technical questions
The questions below clarify the release model and deployment checks, then explore how I would separate shared deployment logic from environment settings. Further questions focus on script behaviour, repeatable builds and failure handling.
Build and deployment model
My answer
Each environment built and deployed separately from the same code for a release version. The environment model shows these separate paths and the automatic or manual release controls.
Post-deployment checks
My answer
No. Application liveness and status checks followed Helm deployment, then DAST ran against the deployed application. Every stage in the SIT sequence had to pass.
Design discussion / Reusable deployment logic
My proposed design
I would put the common deployment steps in one shared script. I would pass in each environment’s settings, such as the cluster, namespace and Helm values. Non-secret settings could come from GitLab variables or configuration files. I would read credentials from the CI/CD variables configured in GitLab.
Each environment’s pipeline would mainly control the job order and deployment rules. This would let me reuse the deployment logic while keeping environment settings separate.
This is my current design approach. The project example confirms shared Helm deployment scripts; it does not establish their original configuration or credential-loading mechanism.
The next topics will examine the mechanisms behind the workflow.
The engineering judgment discussion explores script responsibilities, environment constraints and migration ownership, with further challenges to develop.
Prepared on from my project account and retained working notes. AI assisted with editing and visual presentation.
HPB case study