We have one jenkins server that we use for deployments to non-prod and prod. The way we control where we deploy is via a variable (DEV/QA/PROD) in each project. We have a current requirements to only all certain people to deploy to PROD.
What is the best approach here? I am open to splitting/separating or reconfiguring any of the existing projects.
Depending on the level of separation you want to enforce, you have different solutions:
First level is to rely on different pipeline jobs on your Jenkins instance. The reusable code would be moved to a separated Pipeline Shared Library and you would create 1 job for prod and 1 job for the others, each one having a different Jenkinsfile specyifing a different parameter. Then you use the Jenkins ACL to restrict access to the jobs. The pipeline library shall be a function that accepts the environment to “deploy to” as a parameter defined by the calling pipeline.
Second level would be to ensure that the 2 jobs will never run on the same node agent: you might want to use ephemeral agents (containers, or cloud based VM) with 1 executor each to avoid concurent builds to run on the same location. If you cannot use ephemeral agents, then you should define 2 agents on the same machine, each one ith a different system user to ensure that builds could not see each other or could not access their respective workspaces. Of course, never run agent on the controller node.
Third level is credentials enforcing: you should make sure that each job has its credentials scope to itself, to ensure that other jobs can NOT access the credentials of others. The pipeline library should expect the credential id passed as parameter in this case.
Fourth level would be to enforce authorization in your pipeline shared library: the pipeline code should check which user executed the current pipeline and fails if they are not allowed with the input parameters.
Fifth level is “physical separation”: by running 2 separated Jenkins controllers on 2 different machine, you ensure that production is separated. If you continue using a pipeline shared library, then you can totally share the pipeline code (e.g. the deploy tasks as code) between both, and each controller would only have access to their restricted credentials and environment. This is what we do on the public Jenkins infra: GitHub - jenkins-infra/pipeline-library: Collection of custom steps and variables for our Jenkins instance(s)
Please note that Jenkins has many plugins or features that could be helpful in your case:
Calling a pipeline job from another pipeline job: Pipeline: Build Step (support single and multiple calls, sequentially or parallel, out of the box)