manheim / terraform-pipeline

A reusable pipeline library to apply terraform configuration serially across multiple environments, using Jenkins and a Jenkinsfile.
Apache License 2.0
66 stars 52 forks source link

Restrict state modifications outside of originRepo #356

Open kmanning opened 3 years ago

kmanning commented 3 years ago
jantman commented 3 years ago

The way my team works with infrastructure-as-code and peer review, we have a number of "rules". Among them:

This all works fine if everyone is sharing the same repository and working on branches, but it becomes problematic if people fork the repo. Specifically, let's take the following scenario:

  1. My team's GitHub Org is set up on a Jenkins via the GitHub Org Folder plugin, which automatically creates Jenkins multibranch pipelines for every repo in the Org with a Jenkinsfile.
  2. My personal GitHub User (Jason-Antman) is also set up via the GitHub Org Folder plugin on some Jenkins (maybe the same one, maybe a different one), with the same behavior.
  3. I fork one of my team's repos... and my fork is now automatically building under Jason-Antman/myrepo as well as MyTeam/myrepo.

So, that becomes a bit of an issue in a few (admittedly maybe edge) cases:

kmanning commented 3 years ago

I'm going to focus on the example above for this particular posting. I'm saying this to acknowledge that there might be other UseCases that should also be discussed as part of this Issue, but in a separate post.

To reiterate the assumptions, to ensure that I understand the problem correctly:

  1. You have a project, and you want state changes to only be made on the master branch of that project. (To ensure that changes are made in one place)
  2. If you fork that project, the project's master branch enables a secondary place where changes can be applied (which subverts your goal of making state changes in one and only one place).

In the situations in which you're having problems, the above problem descriptions seem to suggests some corollary statements:

  1. Your fork Github Org Folder has access/permission to the same resources (eg: the same AWS Accounts/resources)
  2. Your fork has access to the same shared state, AND the configuration for that state is hardcoded in your source code.

If the above 2 corollary statements are true, then preventing changes outside of the origin/master branch doesn't seem possible, and in fact, seems outside the scope of terraform-pipeline.

One question: What's your workflow for your fork with in your Git Org Folder? I also use forks in a similar fashion, but I don't have a Git Org Folder in Jenkins to build my forks. I rely on my change being built locally as I code, and then being verified when I open my PR against the origin project. To rephrase the question - what builds are you expecting in your GitHub Org Folder containing your fork, that motivated you to make a Github Org Folder for your fork?

That said, let's step back a bit, and let's ignore the statement that this problem, "seems outside the scope of terraform-pipeline". If I wanted to put myself in your shoes, and wanted to solve the problem anyhow, I think I'd attack the two corollary statements.

  1. Your fork Github Org Folder has access/permission to the same resources. <-- Is there a way to solve this problem outside of terraform-pipeline?

  2. Your fork has access to the same shared state, AND the configuration for that state is hardcoded in your source code. <-- I'm making a number of assumptions here, based on the symptoms of your problem. By default, terraform state is a local file. That would mean that a fork does not have access to that local file in the origin/master repo. That leads me to believe that your state is remote, and that the configuration to that remote state is hardcoded in your terraform code. Are those assumptions true? If so, I would approach the problem by separating your code and state configuration. Once the state configuration is separated, the fork would no longer have access to the state. Would that solve your problem? This notion is in fact built into some of the Backend Plugins (Eg: S3BackendPlugin - which uses the Git Org to construct the path to the S3 state file. Which means if you fork, the fork gets its own state, which potentially solves your problem.)