atlantis icon indicating copy to clipboard operation
atlantis copied to clipboard

feat: Add option to lock on apply instead of plan

Open peikk0 opened this issue 2 years ago • 13 comments

what

Add option lock_repo_on_apply to lock on apply instead of plan.

why

Use case:

At GitLab we want to use Atlantis in repositories where there can be dozens of Merge Requests being worked on simultaneously, and we want an autoplan on every push, so locking on plan would be very annoying very quickly. Non-locking draftplans would also not be a complete solution, as most often those MRs are not drafts and are just waiting for a review and approval, which can be for many hours. We also have Renovate opening new MRs for automatic updates every day.

Instead, the idea here would be to be able to lock only from the first apply in a MR and until it is fully applied and closed. Plans going stale and needing to be re-planned (even after review and approval) are expected and acceptable in this scenario.

tests

  • Deployed my build with lock_repo_on_apply: true set in the server-side repo config
  • In a MR, ran atlantis plan, verified in Redis that the lock wasn't set
  • Ran atlantis apply -p my_env, verified in Redis that the lock was set
  • Ran atlantis apply, verified in Redis that the lock was deleted after the MR was merged.

Also make test.

references

Alternative solution for https://github.com/runatlantis/atlantis/issues/1125, https://github.com/runatlantis/atlantis/issues/2237

peikk0 avatar Oct 20 '23 07:10 peikk0

This is beautiful, thank you. Exceptionally keen for this to land.

SimonBiggs avatar Nov 15 '23 05:11 SimonBiggs

Thanks @jamengual! 🙂

SimonBiggs avatar Nov 19 '23 22:11 SimonBiggs

I think that makes sense but it should break existing configurations, both server-side and in repos. 🤔

peikk0 avatar Dec 12 '23 01:12 peikk0

I think that makes sense but it should break existing configurations, both server-side and in repos. 🤔

Could use a new variable like repo_locks = off|plan|apply and deprecate the old repo_locking

nikolaik avatar Dec 12 '23 08:12 nikolaik

we have something similar here https://github.com/runatlantis/atlantis/pull/3895 with autoplan: mode

jamengual avatar Dec 13 '23 02:12 jamengual

I think that makes sense, but it should break existing server-side and repos configurations. 🤔

Could use a new variable like repo_locks = off|plan|apply and deprecate the old repo_locking

This could be a good compromise; Thank you, @nikolaik. Can you adjust the PR @ peikk0?

GenPage avatar Dec 13 '23 14:12 GenPage

Sounds good, I will add that.

peikk0 avatar Dec 14 '23 09:12 peikk0

Just a note that I'm now working on this after a holiday break, hoping to push the update some time next week. 🤞🏻

peikk0 avatar Jan 12 '24 09:01 peikk0

PR updated, the new config looks like:

repo_locks:
  mode: on_plan|on_apply|disabled

It can be overridden at the repo root and project levels in atlantis.yaml. repo_locking is deprecated in favor of it but still working.

I went with a struct because I initially copy/pasted from the autodiscover config and then I was too deep into it to bother changing it to a single key 😂, but I can still do it if that's preferable. It makes it extensible for the future though. Also I can't decide if there should be an enabled key instead of the disabled value or not.

My Go is still very rusty, so any feedback appreciated.

peikk0 avatar Feb 09 '24 11:02 peikk0

@peikk0 could you please fix the conflicts? Thanks.

jamengual avatar Mar 25 '24 21:03 jamengual

@jamengual conflicts fixed 👍🏻

peikk0 avatar Mar 26 '24 06:03 peikk0

@peikk0 can you look at the linter errors?

jamengual avatar Mar 27 '24 16:03 jamengual

@jamengual I've fixed the linting errors related to this change. The deprecation warning in server/events/vcs/github_client.go:93:17 is unrelated and fixing it is out of scope for this PR so I've just silenced it and added a TODO for it instead.

peikk0 avatar Mar 28 '24 00:03 peikk0

@peikk0 last one, could ou fix the conflicts so we can merge it?

jamengual avatar May 16 '24 16:05 jamengual

@jamengual conflicts fixed 👍🏻

peikk0 avatar May 17 '24 04:05 peikk0

thanks for the contribution @peikk0

jamengual avatar May 17 '24 04:05 jamengual

@jamengual I've amended my merge commit for some stuff I reverted by mistake in the docs, sorry about that 🙇🏻

peikk0 avatar May 17 '24 04:05 peikk0

Are these docs necessarily up to date following this PR? https://www.runatlantis.io/docs/locking

Also, now that locking can occur on_apply and parallel plans are allowed across the same project (for multiple PRs) this means there is no longer a no-op method of locking a project to a specific PR and disallowing applies without first running atlantis apply for the specific PR.

A way to mitigate this would be a manual atlantis lock command that creates the lock for the PR and projects associated.

Do y'all have other recommendations for this type of locking on 1 PR while also using repo_locks: mode: on_apply?

hjkatz avatar Aug 15 '24 18:08 hjkatz

Those docs are up to date with the default locking, if you use any other option then the docs are per flag in the repo config or server config.

if you do repo_locks: mode: on_apply, then you are going to have to change your workflow to be able to use lock only on apply.

jamengual avatar Aug 16 '24 05:08 jamengual

there is no longer a no-op method of locking a project to a specific PR and disallowing applies without first running atlantis apply for the specific PR.

@jamengual Do you think there's a no-op apply pattern that would work with atlantis to enable PR locks without applying changes to a root (or really a set of many many roots)?

hjkatz avatar Aug 16 '24 14:08 hjkatz

if understand correctly you could use draft pr to plan or a regular pr but I don't understand why you will have to apply instead of just closing the pr if the idea is not to apply the code.

if that is not what you mean please describe the user flow of what you are trying to do.

On Fri, Aug 16, 2024, 7:01 a.m. Harrison Katz @.***> wrote:

there is no longer a no-op method of locking a project to a specific PR and disallowing applies without first running atlantis apply for the specific PR.

@jamengual https://github.com/jamengual Do you think there's a no-op apply pattern that would work with atlantis to enable PR locks without applying changes to a root (or really a set of many many roots)?

— Reply to this email directly, view it on GitHub https://github.com/runatlantis/atlantis/pull/3879#issuecomment-2293567700, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQ3ERGFP3GEOWVF64HQ3FDZRYA3FAVCNFSM6AAAAAA6ISPQLCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEOJTGU3DONZQGA . You are receiving this because you were mentioned.Message ID: @.***>

jamengual avatar Aug 16 '24 18:08 jamengual

So the use-case we have had in the past is via mode: on_plan.

  1. Make changes to many many AWS roots (we're about to perform an upgrade)
  2. auto-plan, atlantis takes the lock on the PR, now nobody can plan (nor apply) while we're upgrading
  3. We make manual TF changes locally and apply via terraform apply (not using atlantis apply), here we are relying on the atlantis PR lock as a communication tactic informing other users that they can't touch TF right now because we are doing things out-of-band
  4. We finish the TF changes, now we atlantis plan and confirm there are no changes
  5. We atlantis apply (no-op)
  6. We merge the PR, atlantis drops the lock, now users can plan/apply on their own PRs

To make a similar process with mode: on_apply we need a way to tell atlantis that other PRs are not allowed to apply any of the roots touched in our PR. Normally this would be coordinated via the atlantis lock (on_plan) on our PR, but since we're using on_apply that atlantis lock no longer exists.

We would ideally still want a way to "claim" the projects via an atlantis lock command, or atlantis apply --no-op or something....

Am I making any sense?

hjkatz avatar Aug 16 '24 19:08 hjkatz