<p>I've just transitioned away from having Jenkins freestyle jobs and a separate job for each environment to using Jenkins pipelines (declarative syntax).</p>
<p>In Jenkins pipelines we have a single file (<code>Jenkinsfile</code>) and define different stages for our different environments (Dev/Staging/Prod) and in those stages we just define different behaviour for each environment. For example, our 'Deploy' stage we will deploy to a different kubernetes namespace/cluster depending on if it's the development or staging environment.</p>
<p>I like this approach as you only have one <code>Jenkinsfile</code> per project that exists on all branches.</p>

CC BY-SA 4.0
2019-11-11T17:20:49.093Z
How do you make it deploy a specific environment then? Or do you always deploy all of them together?
lkraider
CC BY-SA 4.0
2020-03-03T16:21:52.727Z
@lkraider the way we do this is using a good branching strategy in git and scripted Jenkins Pipeline. For example you can have all develop branch go to the dev environment and all master or any other branch go to stage or prod. Then in the your Jenkinsfile, you can use the "If" statement like "if (env.BRANCH_NAME == 'develop')" or "if (env.BRANCH_NAME == 'master')" in your pipeline stage. Take a look https://jenkins.io/doc/tutorials/build-a-multibranch-pipeline-project/
Toye
CC BY-SA 4.0
2018-08-01T12:01:03.433Z
2022-11-23T11:38:04.557Z
2022-11-23T11:38:04.557Z
Caledonia91
<p>The short answer to your question is no. Jenkins has no need to talk to your production environments but it can if you need it to. In other words, if Jenkins can reach these environments, it can likely interact with them.</p>

<p>From a best practices approach, typically I recommend using software that will make your deploy as simple and repeatable as possible (e.g. make, Ansible, Terraform, Cloud Formation or Kubernetes).</p>

<p>Pipelines are capable of handling parallel targets meaning you can build and deploy to all three environments at the same time if you choose to.</p>

<p>You might want to make your question more precise or detailed in order to garner more feedback.   </p>

CC BY-SA 4.0
2018-08-01T04:20:01.610Z
2018-08-01T04:20:01.610Z
casey vega
<p>We can use single Jenkinsfile for different environment. But we need something to differentiate between this environment, may be an environment variable or a parameter in a parameterised job to control what we need to do in each environment. May be we want to do build, test, perform e2e and push image into a repository in one environment. Then use the same image and deploy in the next ( staging, may be) and perform smoke test. Then use the same image to deploy into production.</p>

CC BY-SA 4.0
2020-02-05T09:18:39.803Z
2020-02-05T09:18:39.803Z
Davy Jones
<p>This is a very good question as it is a common anti-pattern to couple <code>ci/cd</code> tools with environments.</p>
<p>Jenkins is a build factory. As such, it should be totally agnostic of the notion of environment, or even delivery.</p>
<p>The best practice is to have some sort of staging process and / or interface (if you can afford it: a dedicated delivery software).</p>
<h3>Staging process</h3>
<p>You should try to create some sort of staging jobs for each environment, in which you'll define the configuration of the environment and bundle the final package with it.</p>
<p>Next you'll have delivery jobs for each environment.</p>
<h3>Delivery tools</h3>
<p>In order to do create the staging and delivery jobs, you may use very basic scripting tools, like <code>shell</code>, but there are more adapted scripting tools, like <code>Ansible</code>, <code>puppet</code>, <code>chef</code>...</p>
<p>If you can afford the expense, you may consider investing in a deployment software (I'll mention some that I worked with in the comments section).</p>
<p>Notice that those softwares manage some kind of environment staging process.</p>
<p>Obviously, it makes a lot of sense to combine deploy softwares and scripting.</p>
<h3>Beyond segregating tools and environment</h3>
<p>Since you asked for best practices, it appears to me that it is worth mentioning another commonly found anti-pattern: coupling SCM tools and delivery process.</p>
<p>It is a very <strong>good</strong> practice to store environment configuration (not passwords or confidential information, of course) and go live scripts in SCM tools (like <code>svn</code> or <code>git</code>...). It is however a very <strong>bad</strong> practice to check-out environment configuration and go live scripts DURING the go live. It might simply be unavailable when you need it.</p>
<p>This check-out phase should be part of the staging process that I mentioned before.</p>
<h3>Idempotence</h3>
<p>Another best practice is that your scripts should be <code>idempotent</code>: this means that you should be able to play your scripts once to perform the staging and delivery. Then you should be able to play them again and again, and they would not change the state of your system unless something chacked in the configuration.</p>
<h3>Scaling</h3>
<p>As a final best practice I shall share from direct experience is scaling Jenkins: different teams have different needs and uses of Jenkins. When too many teams share a common Jenkins, there might be issues with resources. The worst case is when a team requires to restart the Jenkins master while another needs to deliver.</p>
<p>The ideal would be to have one Jenkins per team or per group of teams that share the same goal and delivery planning.</p>

CC BY-SA 4.0
2022-11-17T11:31:56.573Z
Nice answer. However ("I'll mention some that I worked with in the comments section"), no comments over here. BTW, it is preferable to edit and add info to your answer rather than comments that are prone to be removed with time.
Ictus
CC BY-SA 4.0
2018-08-01T10:15:38.813Z
2022-11-17T15:02:39.593Z
2022-11-17T15:02:39.593Z
avi.elkharrat
<p>I have 3 environments, each on their own Virtual Network with their own configurations. Do I need to have 3 separate instances of Jenkins if I am to do Continuous Deployments on each of the environments? What are some best practices regrading deploying on a multi environment architecture?</p>

<jenkins>
Best Practices for a multi environment deployment using Jenkins
Syed Shamikh Shabbir
# Best Practices for a multi environment deployment using Jenkins

(Asked by: username_0 on 2018-07-31)

I have 3 environments, each on their own Virtual Network with their own configurations. Do I need to have 3 separate instances of Jenkins if I am to do Continuous Deployments on each of the environments? What are some best practices regrading deploying on a multi environment architecture?

**Tags:** jenkins


---

## 4 answers

### Answer by username_6 on 2018-08-01. Score: 10 | Accepted answer

This is a very good question as it is a common anti-pattern to couple `ci/cd` tools with environments.

Jenkins is a build factory. As such, it should be totally agnostic of the notion of environment, or even delivery.

The best practice is to have some sort of staging process and / or interface (if you can afford it: a dedicated delivery software).

### Staging process

You should try to create some sort of staging jobs for each environment, in which you'll define the configuration of the environment and bundle the final package with it.

Next you'll have delivery jobs for each environment.

### Delivery tools

In order to do create the staging and delivery jobs, you may use very basic scripting tools, like `shell`, but there are more adapted scripting tools, like `Ansible`, `puppet`, `chef`...

If you can afford the expense, you may consider investing in a deployment software (I'll mention some that I worked with in the comments section).

Notice that those softwares manage some kind of environment staging process.

Obviously, it makes a lot of sense to combine deploy softwares and scripting.

### Beyond segregating tools and environment

Since you asked for best practices, it appears to me that it is worth mentioning another commonly found anti-pattern: coupling SCM tools and delivery process.

It is a very **good** practice to store environment configuration (not passwords or confidential information, of course) and go live scripts in SCM tools (like `svn` or `git`...). It is however a very **bad** practice to check-out environment configuration and go live scripts DURING the go live. It might simply be unavailable when you need it.

This check-out phase should be part of the staging process that I mentioned before.

### Idempotence

Another best practice is that your scripts should be `idempotent`: this means that you should be able to play your scripts once to perform the staging and delivery. Then you should be able to play them again and again, and they would not change the state of your system unless something chacked in the configuration.

### Scaling

As a final best practice I shall share from direct experience is scaling Jenkins: different teams have different needs and uses of Jenkins. When too many teams share a common Jenkins, there might be issues with resources. The worst case is when a team requires to restart the Jenkins master while another needs to deliver.

The ideal would be to have one Jenkins per team or per group of teams that share the same goal and delivery planning.

> **Comments:**
> **username_7**: Nice answer. However ("I'll mention some that I worked with in the comments section"), no comments over here. BTW, it is preferable to edit and add info to your answer rather than comments that are prone to be removed with time.  

---

### Answer by username_1 on 2018-08-01. Score: 3

I've just transitioned away from having Jenkins freestyle jobs and a separate job for each environment to using Jenkins pipelines (declarative syntax).

In Jenkins pipelines we have a single file (`Jenkinsfile`) and define different stages for our different environments (Dev/Staging/Prod) and in those stages we just define different behaviour for each environment. For example, our 'Deploy' stage we will deploy to a different kubernetes namespace/cluster depending on if it's the development or staging environment.

I like this approach as you only have one `Jenkinsfile` per project that exists on all branches.

> **Comments:**
> **username_2**: How do you make it deploy a specific environment then? Or do you always deploy all of them together?  
> **username_3**: @username_2 the way we do this is using a good branching strategy in git and scripted Jenkins Pipeline. For example you can have all develop branch go to the dev environment and all master or any other branch go to stage or prod. Then in the your Jenkinsfile, you can use the "If" statement like "if (env.BRANCH_NAME == 'develop')" or "if (env.BRANCH_NAME == 'master')" in your pipeline stage. Take a look https://jenkins.io/doc/tutorials/build-a-multibranch-pipeline-project/  

---

### Answer by username_4 on 2018-08-01. Score: 2

The short answer to your question is no. Jenkins has no need to talk to your production environments but it can if you need it to. In other words, if Jenkins can reach these environments, it can likely interact with them.

From a best practices approach, typically I recommend using software that will make your deploy as simple and repeatable as possible (e.g. make, Ansible, Terraform, Cloud Formation or Kubernetes).

Pipelines are capable of handling parallel targets meaning you can build and deploy to all three environments at the same time if you choose to.

You might want to make your question more precise or detailed in order to garner more feedback.


---

### Answer by username_5 on 2020-02-05. Score: 0

We can use single Jenkinsfile for different environment. But we need something to differentiate between this environment, may be an environment variable or a parameter in a parameterised job to control what we need to do in each environment. May be we want to do build, test, perform e2e and push image into a repository in one environment. Then use the same image and deploy in the next ( staging, may be) and perform smoke test. Then use the same image to deploy into production.


---

