This message was deleted.
# atlantis-community
s
This message was deleted.
d
this is
repos.yaml
Copy code
repos:
- id: /.*/
  # branch is an regex matching pull requests by base branch
  # (the branch the pull request is getting merged into).
  # By default, all branches are matched
  branch: /.*/
  pre_workflow_hooks:
    - description: "Gate prod deployments within develop git branch"
      run: |
        if [ "${BASE_BRANCH_NAME}" = "develop" -a "${PROJECT_NAME}" = "prod" ]; then 
            echo "Can't run prod pipeline for develop branch"
            exit 1
        fi
  repo_config_file: ./atlantis.yaml
  apply_requirements: [approved, mergeable, undiverged]
  import_requirements: [approved, mergeable, undiverged]
  allowed_overrides: [workflow]
  allowed_workflows: [custom]
  allow_custom_workflows: true
# workflows lists server-side custom workflows
workflows:
  custom:
    plan:
      steps:
        - run:
            command: echo this is branch ${BASE_BRANCH_NAME} and the project is ${PROJECT_NAME}
            output: show
        - env: <--- (NOTE I have to do this to expose the PROJECT_NAME otherwise it wouldnt work by referencing directly in the extra_args key)
            name: ENVIRONMENT
            command: echo ${PROJECT_NAME}
        - init:
            extra_args:
              - -backend-config=environment/${ENVIRONMENT}/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/${ENVIRONMENT}/${ENVIRONMENT}.tfvars
atlantis.yaml
Copy code
# atlantis.yaml
version: 3
# repos lists the config for specific repos.
projects:
# If two or more projects have the same dir and workspace, they must also have
# a 'name' key to differentiate them.
- name: dev
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  dir: .
  workflow: custom
- name: prod
  dir: .
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  workflow: custom
I also tried specifying the base branch for each project in the
atlantis.yaml
config but it's not being honoured:
Copy code
# atlantis.yaml
version: 3
# repos lists the config for specific repos.
projects:
# If two or more projects have the same dir and workspace, they must also have
# a 'name' key to differentiate them.
- name: dev
  branch: /develop/
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  dir: .
  workflow: custom
- name: preprod
  branch: /develop/
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  dir: .
  workflow: custom
- name: prod
  branch: /main/
  dir: .
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  workflow: custom
when I run
atlantis plan -p prod
inside a PR from source branch:
feature/add_resource
to destination branch:
develop
it still executes the plan for prod. I would expect that to fail because its not matching the base branch
@PePe Amengual for viz. Apologies for tagging, but I wasn't sure if this was maybe missed. Hopefully it's something that's straightforward and not difficult to solve.
p
preworkflow hooks do not share the same ENV variables than workflows
you will need to check the docs or code
if that does not work you will have to run a custom run command on each workflow to do the test and call your script and exit with 1
and the branch….I thought it was just the name
like
branch: branchname
d
for the branch name are you saying
develop
instead of
/develop/
? didn't follow that sorry
Ok I checked the documentation here: https://www.runatlantis.io/docs/custom-workflows.html#step and it says that
Copy code
run steps in the main workflow are executed with the following environment variables:
note: these variables are not available to pre or post workflows
so it seems like {PROJECT_NAME} would probably not be captured. Not sure why {BASE_BRANCH_NAME} is though, because its included in that list
p
PRs are welcome to extend it
There is no reason why the whole payload could not be exposed
d
i can certainly look into it and add a PR later, but for short-term it sounds like I should be able to run a command inside the workflow to do an exit 1; which should stop the workflow correct?
Copy code
workflows:
  dev:
    plan:
      steps:
        # needed otherwise TF will complain that backend changed between diff commands
        - env:
            name: ENVI
            command: echo ${PROJECT_NAME}
        - run: rm -rf .terraform
        - run: 'if [ "${ENVI}" == "prod" ]; then exit 1;'
        - init:
            extra_args:
              - -backend-config=environment/${ENVI}/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/${ENVI}/${ENVI}.tfvars
  preprod:
    plan:
      steps:
        # needed otherwise TF will complain that backend changed between diff commands
        - env:
            name: ENVI
            command: echo ${PROJECT_NAME}
        - run: rm -rf .terraform
        - run: 'if [ "${ENVI}" == "prod" ]; then exit 1;'
        - init:
            extra_args:
              - -backend-config=environment/${ENVI}/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/${ENVI}/${ENVI}.tfvars
  prod:
    plan:
      steps:
        # needed otherwise TF will complain that backend changed between diff commands
        - env:
            name: ENVI
            command: echo ${PROJECT_NAME}
        - run: rm -rf .terraform
        - init:
            extra_args:
              - -backend-config=environment/${ENVI}/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/${ENVI}/${ENVI}.tfvars
I have added 3x workflows to represent the different environments, and i've added the following run in the preprod and dev:
Copy code
- run: 'if [ "${ENVI}" == "prod" ]; then exit 1;'
I will test shortly to see if it works
p
yes it should work
many people have done this before
d
Thank you @PePe Amengual .. ive split them like this and now when i try to run prod in develop branch i get the following: Plan Error
Copy code
no project with name "prod" is defined in ./atlantis.yaml
this is the atlantis.yml:
Copy code
# atlantis.yaml
version: 3
# repos lists the config for specific repos.
projects:
# If two or more projects have the same dir and workspace, they must also have
# a 'name' key to differentiate them.
- name: dev
  branch: /develop/
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  repo_locking: true
  dir: .
  workflow: dev
- name: preprod
  repo_locking: true
  branch: /develop/
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  dir: .
  workflow: preprod
- name: prod
  repo_locking: true
  branch: /main/
  dir: .
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  workflow: prod
I'm assuming this is expected. It runs fine if i try preprod or dev
p
mmmm that is interesting
The whole yaml is parsed at the beginning..
can you post your new atlantis.yaml?
d
for reference this is what im getting in the PR. (feature/add_resource -> develop)
the error for dev is expected, but it shows it goes to terraform
Copy code
# atlantis.yaml
version: 3
# repos lists the config for specific repos.
projects:
# If two or more projects have the same dir and workspace, they must also have
# a 'name' key to differentiate them.
- name: dev
  branch: /develop/
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  repo_locking: true
  dir: .
  workflow: dev
- name: preprod
  repo_locking: true
  branch: /develop/
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  dir: .
  workflow: preprod
- name: prod
  repo_locking: true
  branch: /main/
  dir: .
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  workflow: prod
this is the atlantis.yaml
and then repos.yaml;
Copy code
repos:
  # id can either be an exact repo ID or a regex.
  # If using a regex, it must start and end with a slash.
  # Repo ID's are of the form {VCS hostname}/{org}/{repo name}, ex.
  # <http://github.com/runatlantis/atlantis|github.com/runatlantis/atlantis>.
  # this can be used for project specific settings if there's ever a use case for.
- id: /.*/
  # branch is an regex matching pull requests by base branch
  # (the branch the pull request is getting merged into).
  # By default, all branches are matched
  branch: /.*/

  #pre_workflow_hooks:
 
    #- description: "Running some checks"
      #run: |
       # if [ "${BASE_BRANCH_NAME}" = "develop" -a "${PROJECT_NAME}" = "prod" ]; then 
           # echo "Can't run prod pipeline for develop branch"
           # exit 1
        #fi
  # repo_config_file specifies which repo config file to use for this repo.
  # By default, atlantis.yaml is used.
  repo_config_file: ./atlantis.yaml

# Meaning of different types of PR state
  # Approved - SCM approval e.g. reviewer approving a PR ( must be in the list of codeowners, protected branch things)
  # Mergeable - all checks must pass (defined in protected branch).
  # UnDiverged - PR must be ahead of base branch!

  # Requiring PR is approved before an applicable subcommand.
  apply_requirements: [approved, mergeable, undiverged]

  # Requiring PR is approved and mergeable (all checks are green e.g. CI) before an applicable subcommand.
  import_requirements: [approved, mergeable, undiverged]

  # workflow sets the workflow for all repos that match.
  # This workflow must be defined in the workflows section.
  # workflow: custom

  # allowed_overrides specifies which keys can be overridden by this repo in
  # its atlantis.yaml file.
  allowed_overrides: [workflow]

  # allowed_workflows specifies which workflows the repos that match 
  # are allowed to select.
  allowed_workflows: [prod, preprod, dev]

  # allow_custom_workflows defines whether this repo can define its own
  # workflows. If false (default), the repo can only use server-side defined
  # workflows.
  # allow_custom_workflows: true

  # delete_source_branch_on_merge defines whether the source branch would be deleted on merge
  # If false (default), the source branch won't be deleted on merge
  # delete_source_branch_on_merge: true

  # repo_locking defines whether lock repository when planning.
  # If true (default), atlantis try to get a lock.
  # repo_locking: true

  # custom_policy_check defines whether policy checking tools besides Conftest are enabled in checks
  # If false (default), only Conftest JSON output is allowed
  #custom_policy_check: false

  # pre_workflow_hooks defines arbitrary list of scripts to execute before workflow execution.
  #pre_workflow_hooks: 
    #- run: my-pre-workflow-hook-command arg1
  
  # post_workflow_hooks defines arbitrary list of scripts to execute after workflow execution.
  #post_workflow_hooks: 
    #- run: my-post-workflow-hook-command arg1

  # policy_check defines if policy checking should be enable on this repository.
  #policy_check: false


# workflows lists server-side custom workflows
workflows:
  dev:
    plan:
      steps:
        # needed otherwise TF will complain that backend changed between diff commands
        - env:
            name: ENVIRONMENT
            command: echo ${PROJECT_NAME}
        - run: rm -rf .terraform
        - run: 'echo Checking if there is an attempt to push to prod && if [ "${ENVIRONMENT}" == "prod" ]; then exit 1; fi;'
        - init:
            extra_args:
              - -backend-config=environment/dev/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/dev/dev.tfvars
  preprod:
    plan:
      steps:
        # needed otherwise TF will complain that backend changed between diff commands
        - env:
            name: ENVIRONMENT
            command: echo ${PROJECT_NAME}
        - run: rm -rf .terraform
        - run: 'echo Checking if there is an attempt to push to prod && if [ "${ENVIRONMENT}" == "prod" ]; then exit 1; fi;'
        - init:
            extra_args:
              - -backend-config=environment/preprod/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/preprod/preprod.tfvars
  prod:
    plan:
      steps:
        # needed otherwise TF will complain that backend changed between diff commands
        - run: rm -rf .terraform
        - init:
            extra_args:
              - -backend-config=environment/prod/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/prod/prod.tfvars
p
well, you are exiting on == prod
d
correct, i want to stop if someone is trying to do prod in develop branch
p
that will match when you call prod too, I wonder if that is evaluated
d
oh i see.. so technically we should not seee such failure, but we should see the exit 1 instead;
p
yes
d
mhmmm
I commented out that line and i still get same error
Copy code
# workflows lists server-side custom workflows
workflows:
  dev:
    plan:
      steps:
        # needed otherwise TF will complain that backend changed between diff commands
        - env:
            name: ENVIRONMENT
            command: echo ${PROJECT_NAME}
        - run: rm -rf .terraform
        # - run: 'echo Checking if there is an attempt to push to prod && if [ "${ENVIRONMENT}" == "prod" ]; then exit 1; fi;'
        - init:
            extra_args:
              - -backend-config=environment/dev/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/dev/dev.tfvars
  preprod:
    plan:
      steps:
        # needed otherwise TF will complain that backend changed between diff commands
        - env:
            name: ENVIRONMENT
            command: echo ${PROJECT_NAME}
        - run: rm -rf .terraform
        # - run: 'echo Checking if there is an attempt to push to prod && if [ "${ENVIRONMENT}" == "prod" ]; then exit 1; fi;'
        - init:
            extra_args:
              - -backend-config=environment/preprod/backend.tfvars
        - plan:
            extra_args:
              - -var-file=environment/preprod/preprod.tfvars
so i am not sure why it produces that error still.. because prod is defined in atlantis.yaml
ok @PePe Amengual I see the error
If I try to run
atlantis plan -p prod
inside a PR to develop then I get:
Copy code
no project with name "prod" is defined in ./atlantis.yaml
in atlantis.yaml I have prod project configured as such:
Copy code
- name: prod
  repo_locking: true
  branch: /main/
  dir: .
  autoplan:
    enabled: false
    when_modified: ['*.tf*']
  workflow: prod
as soon as I change from
branch: /main/
to
branch: /develop/
it works
so maybe we need to come up with a friendlier log to indicate that is the case? because this log is potentially misleading.
p
no, I could be wrong on the regex matching
so if you change to
/branchname/
everything works?
d
i didnt try without /, let me try
it has to be with that, without the forward slash I get the following error:
Copy code
{"level":"error","ts":"2023-11-15T20:13:08.976Z","caller":"events/pull_updater.go:17","msg":"projects: (0: (branch: regex must begin and end with a slash '/'.); 1: (branch: regex must begin and end with a slash '/'.); 2: (branch: regex must begin and end with a slash '/'.).).",
i dont think i explained myself very well on what I found above so i'll try again: with the following combination of project name and branch name:
Copy code
- name: dev
  repo_locking: true  
  branch: /develop/
- name: preprod
  repo_locking: true
  branch: /develop/
- name: prod
  repo_locking: true
  branch: /main/
as you can see dev is set to develop, and prod is set to main branch. if I try to run
atlantis plan -p prod
inside a PR to develop, then I get this error:
no project with name "prod" is defined in ./atlantis.yaml
If i change the combination of project name and branch name for prod to:
Copy code
- name: prod
  repo_locking: true
  branch: /develop/
then
atlantis plan -p prod
doesn't fail.
p
no no, I mean, when adding the
/
then it matches the branch?
d
oh yes correct
p
ok, so I was wrong on the branch name
d
but im trying to understand the above behavior now
in theory it makes sense because i dont want to run prod from develop because the branch for prod is set to main.
but i think the error message outputted in PR can be misleading
i dont know if its intentional or a bug
p
but the PR is against main, that is not the branch name that the PR is from
d
no here the PR is against develop
this is why im confused
p
you can’t match the branch:
/main/
that is never going to match on a PR
d
Copy code
Regex matching projects by the base branch of pull request (the branch the pull request is getting merged into). Only projects that match the PR's branch will be considered. By default, all branches are matched.
so its saying base branch
p
base branch of the PR <--- that is KEY
PRs can’t be created from main, they are created from a different branch
that is
based
on main
d
yeah in my example i have PR as: source: feature/add_resource destination: develop
p
you need a prod branch
so it looks like :
Copy code
- name: dev
  repo_locking: true  
  branch: /develop/
- name: preprod
  repo_locking: true
  branch: /develop/
- name: prod
  repo_locking: true
  branch: /prod/
d
im just trying to understand what the branch field would be in this example.
Copy code
source: feature/add_resource
destination: develop
would Atlantis set it to be feature/add_resource?
p
correct
d
oh ok
p
is whatever the branch name is
BUT just to confuse you a bit more
the
branch: /branchname/
is a regex
so you can do whatever you want on a regex
you could do
branch: /dev|preprod|testing/
d
sorry, i was getting confused with this ENV variable: •
BASE_BRANCH_NAME
- Name of the base branch of the pull request (the branch that the pull request is getting merged into)
p
ahhh yes that is different
d
that's why i thought branch was the same as that one
haha
ok i get it now
p
and you mention that at the beginning, sorry I should have pointed it out
d
i wonder if instead of doing multi branching for every single environment (maybe an app can have 3 or more) then I can just filter inside the run command for each workflow to check... for example extend this one from:
if [ "${ENVIRONMENT}" == "prod" ]; then exit 1; fi;
to
if [ "${ENVIRONMENT}" = "prod" -a "${BASE_BRANCH_NAME} = "develop" ]; then exit 1; fi;
what do you think?
the reason why im trying to keep just two branches is because we were thinking of it in the context of GIT approvals. we only want to require approvals for the main (or release) branch because we associate that with production. and then develop people can run whatever environment without needing an approval, but they can't just run prod from there.. hopefully that makes sense
p
but the base branch is always main
d
yeah we have a specific requirement where we only want to require approvals only for prod environment. if we have only base branch as main then approval would get invoked for dev environment
so i set a git protection rule where PRs to main need to respect the CODEOWNERS
because we only expect prod to be pushed there
p
look at the issues and slack history here https://www.linen.dev/s/atlantis/c/community there is people that have done this before
in different ways
d
but i see what you mean and I agree that's the only reason why i separated to two branches
otherwise i would've done one release branch
with feature branches PR in
i just have a hard requirement to make sure that only PROD runs are gated, and other runs such as DEV/STAGING/PREPROD are not
p
yes, pretty common requirement
d
so i am wondering if there's another way to gate just from one release branch
the problem is that you dont know what people are going to push until someone types atlantis apply -p {project}
For now I will use this
Copy code
if [ "${ENVIRONMENT}" = "prod" -a "${BASE_BRANCH_NAME}" = "develop" ]; then exit 1; fi;'
but i will look other alternatives, I just tested and the above worked. Thank you for your help!
p
no problem
d
I will take a look at creating a PR for the env variables as I think it would be cleaner to have that accessibility in pre workflow hook