GitHub
03/05/2025, 9:38 PMhttps://github.com/cncf/toc/raw/main/process/project-stages.png▾
DD
is Due Diligence
There are so many examples of successful projects in CNCF such as kubernetes, argocd, helm, flux, etcd, prometheus, etc. Let's make atlantis part of that list!
---
The current license for atlantis is Apache Licence 2.0 and there is no CLA for this repo.
https://github.com/runatlantis/atlantis/blob/main/LICENSE
References
• https://www.cncf.io/projects/
• https://github.com/cncf/toc/blob/main/process/project_proposals.md
• https://github.com/cncf/toc/blob/main/process/sandbox.md
• https://enrollment.lfx.linuxfoundation.org/?project=cncf
• https://www.reddit.com/r/kubernetes/comments/tqhdr2/reasons_not_to_donate_an_opensource_project_to/
runatlantis/atlantisGitHub
03/06/2025, 11:52 AMatlantis-server.yaml
file:
repos:
- id: github.com/xxxx/monorepo
apply_requirements: [mergeable]
allowed_overrides: [workflow]
Atlantis server flags:
ATLANTIS_SILENCE_VCS_STATUS_NO_PLANS = true
ATLANTIS_SILENCE_VCS_STATUS_NO_PROJECTS = true
ATLANTIS_SILENCE_NO_PROJECTS = true
ATLANTIS_HIDE_PREV_PLAN_COMMENTS = true
ATLANTIS_HIDE_UNCHANGED_PLAN_COMMENTS = true
atlantis.yaml
file:
version: 3
projects:
- name: 6-app-test-sandbox
dir: infrastructure-gcp/6-app-test/environments/sandbox
autoplan:
when_modified:
- '*.tf'
- ../../modules/**/*.tf
- ../../6-app-modules/**/*.tf
- '**/*.tfvars'
- ../../config/**/*.yaml
- ../../modules/**/*.yaml
workspace: default
workflow: default
terraform_version: v1.6.3
runatlantis/atlantisGitHub
03/07/2025, 9:22 AMGitHub
03/07/2025, 11:39 PMATLANTIS_DATA_DIR
should default to /home/atlantis/.atlantis
as per the FAQ
https://www.runatlantis.io/docs/faq
Atlantis, by default, stores all locking and Terraform plans locally on disk under the --data-dir directory (defaults to ~/.atlantis).This becomes an issue if the value is unset if you have yaml configuration file that references the env var instead of the hard coded value. The workaround is to always set the value so it can be references in the workflows yaml configs. ### Reproduction Steps Use ATLANTIS_DATA_DIR without setting it and it will throw an error because the env var is empty. ### Logs N/A ### Environment details N/A ### Additional Context N/A runatlantis/atlantis
GitHub
03/11/2025, 12:04 AMGitHub
03/11/2025, 1:06 AMfunc (checker *ExternalTeamAllowlistChecker) buildCommandString(ctx models.TeamAllowlistCheckerContext, teams []string, command string) string {
cmdArr := append([]string{checker.Command}, checker.ExtraArgs...)
orgTeams := make([]string, len(teams))
for i, team := range teams {
// Properly quote the team name
orgTeams[i] = fmt.Sprintf("%q", fmt.Sprintf("%s/%s", ctx.BaseRepo.Owner, team))
}
teamStr := strings.Join(orgTeams, " ")
return strings.Join(append(cmdArr, command, ctx.BaseRepo.FullName, teamStr), " ")
}
### Reproduction Steps
### Logs
### Environment details
### Additional Context
runatlantis/atlantisGitHub
03/13/2025, 10:21 PMatlantis apply
command.
Describe the solution you'd like
I'd love to be able to set the automerge method alongside the automerge enabled/disabled flag in atlantis.yaml
An ideal configuration in the atlantis.yaml
would look like:
version: 3
automerge: true
automerge-method: squash
projects:
...
---
Right now it's possible to set the --auto-merge-method
flag on an atlantis apply
command when automerge: true
. It would be awesome to be able to set the automerge-method
in the repo file so every atlantis apply
uses that method. Our use case here is enforcing squash commits to our main branch, but atlantis automerging currently fails because the default merge method isn't allowed. This results in this error:
Automerging failed:
merging pull request: PUT <https://api.github.com/repos/FigureTechnologies/figure-infra/pulls/530/merge>: 405 Merge commits are not allowed on this repository. []
runatlantis/atlantisGitHub
03/18/2025, 6:24 PM--tf-download-url
but it would be nice to have this officially documented so people can start using opentf instead of terraform for future releases.
https://www.runatlantis.io/docs/server-configuration.html#tf-download-url
Describe the solution you'd like
See above
Describe the drawbacks of your solution
N/A
Describe alternatives you've considered
N/A
---
• epic #3741
• Previous ticket #3727
• #1776
• https://github.com/warrensbox/terraform-switcher
• warrensbox/terraform-switcher#315
---
atlantis/cmd/server.go
Line 173 in</runatlantis/atlantis/commit/a793620475519d19c86caa01242a8bc6a125045e|a793620>
| DefaultTFDownloadURL = "https://releases.hashicorp.com" |
| ------------------------------------------------------- |
atlantis/server/server.go
Line 405 in</runatlantis/atlantis/commit/a793620475519d19c86caa01242a8bc6a125045e|a793620>
| terraformClient, err := terraform.NewClient( |
| -------------------------------------------- |
atlantis/server/core/terraform/terraform_client.go
Lines 239 to 253 in</runatlantis/atlantis/commit/a793620475519d19c86caa01242a8bc6a125045e|a793620>
| func NewClient( |
| --------------------------------------------------------- |
| log logging.SimpleLogging, |
| binDir string, |
| cacheDir string, |
| tfeToken string, |
| tfeHostname string, |
| defaultVersionStr string, |
| defaultVersionFlagName string, |
| tfDownloadURL string, |
| tfDownloader Downloader, |
| tfDownloadAllowed bool, |
| usePluginCache bool, |
| projectCmdOutputHandler jobs.ProjectCommandOutputHandler, |
| ) (*DefaultClient, error) { |
| return NewClientWithDefaultVersion( |
atlantis/server/core/terraform/terraform_client.go
Line 379 in</runatlantis/atlantis/commit/3ea2914e1637066f336f64984c41f62391632223|3ea2914>
| _, err = ensureVersion(log, c.downloader, c.versions, v, c.binDir, c.downloadBaseURL, c.downloadAllowed) |
| -------------------------------------------------------------------------------------------------------- |
atlantis/server/core/terraform/terraform_client.go
Lines 555 to 562 in</runatlantis/atlantis/commit/3ea2914e1637066f336f64984c41f62391632223|3ea2914>
| log.Info("Could not find terraform version %s in PATH or %s, downloading from %s", v.String(), binDir, downloadURL) |
| ------------------------------------------------------------------------------------------------------------------- |
| urlPrefix := fmt.Sprintf("%s/terraform/%s/terraform_%s", downloadURL, v.String(), v.String()) |
| binURL := fmt.Sprintf("%s_%s_%s.zip", urlPrefix, runtime.GOOS, runtime.GOARCH) |
| checksumURL := fmt.Sprintf("%s_SHA256SUMS", urlPrefix) |
| fullSrcURL := fmt.Sprintf("%s?checksum=file:%s", binURL, checksumURL) |
| if err := dl.GetFile(dest, fullSrcURL); err != nil { |
| return "", errors.Wrapf(err, "downloading terraform version %s at %q", v.String(), fullSrcURL) |
| } |
atlantis/server/core/terraform/terraform_client.go
Line 538 in</runatlantis/atlantis/commit/3ea2914e1637066f336f64984c41f62391632223|3ea2914>
| binFile := "terraform" + v.String() |
| ----------------------------------- |
Listing versions
atlantis/server/core/terraform/terraform_client.go
Line 304 in</runatlantis/atlantis/commit/3ea2914e1637066f336f64984c41f62391632223|3ea2914>
| versions, err := lib.GetTFList(url, true) |
| ----------------------------------------- |
---
The terraform url is constructed
• url = <https://releases.hashicorp.com>
• format string = %s/terraform/%s/terraform_%s
, prefix, version, version
• %s_%s_%s.zip
, prefix, os, arch
• full url <https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_darwin_amd64.zip>
Opentofu
• url = <https://github.com/opentofu/opentofu/releases>
• format string = %s/download/%s/tofu_%s
, prefix, version, version
• %s_%s_%s.zip
, prefix, os, arch
• full url <https://github.com/opentofu/opentofu/releases/download/v1.6.0-alpha4/tofu_1.6.0-alpha4_darwin_amd64.zip>
Seems like the following changes are needed
• overriding the url string
• this can be done already
• overriding the format string with a new flag
• simplifying default format string to use %[2]s
to remove redundant argument
• a way to search opentf versions to know which version to download
• https://releases-page.opentofu-get.pages.dev/tofu/
• opentofu/opentofu#928
• opentofu/get.opentofu.org#16
• #4339
• opentofu/get.opentofu.org#22
• opentofu-enabled flag
• change the name of the binary downloaded
• allow a required_version block at …
runatlantis/atlantisGitHub
03/18/2025, 6:24 PMGitHub
03/18/2025, 11:39 PMplan
and apply
fails the same way, with page 11 already freed
. It fails whether or not I specify -p
. The actual terraform plan
and apply
operations run fine - the problem is with posting a summary in GH and marking the "parent" GH check as successful - the check stays in e.g. atlantis/plan Plan in progress...
.
### Reproduction Steps
Just need to run a plan
.
### Logs
2025-03-18T23:24:52.2671106Z {"level":"info","ts":"2025-03-18T23:24:52.266Z","caller":"models/shell_command_runner.go:181","msg":"successfully ran 'sh -c' '/home/atlantis/.atlantis/bin/terraform1.7.5 plan -input=false -refresh -out \"/home/atlantis/.atlantis/repos/*redacted*/*redacted*/535/*redacted*/environment/environment-*redacted*-*redacted*.tfplan\" -var-file variables/common.tfvars -var-file variables/$WORKSPACE.tfvars' in '/home/atlantis/.atlantis/repos/*redacted*/*redacted*/535/*redacted*/environment'","json":{"repo":"*redacted*/*redacted*","pull":"535","duration":73.903894794}}
2025-03-18T23:24:52.2807116Z {"level":"info","ts":"2025-03-18T23:24:52.280Z","caller":"vcs/github_client.go:923","msg":"Updating GitHub Check status for 'atlantis/plan: environment-*redacted*' to 'success'","json":{"repo":"*redacted*/*redacted*","pull":"535"}}
2025-03-18T23:24:52.7857766Z {"level":"info","ts":"2025-03-18T23:24:52.785Z","caller":"events/instrumented_project_command_runner.go:88","msg":"plan success. output available at: <https://github.com/*redacted*/*redacted*/pull/535%22,%22json%22:{%22repo%22:%22*redacted*/*redacted*%22,%22pull%22:%22535%22}}|https://github.com/*redacted*/*redacted*/pull/535","json":{"repo":"*redacted*/*redacted*","pull":"535"}}>
2025-03-18T23:24:53.6045913Z {"level":"error","ts":"2025-03-18T23:24:53.604Z","caller":"events/command_runner.go:555","msg":"PANIC: page 11 already freed\<http://ngo.etcd.io/bbolt@v1.3.11/freelist.go:175|ngo.etcd.io/bbolt@v1.3.11/freelist.go:175> (0xb649f3)\<http://ngo.etcd.io/bbolt@v1.3.11/node.go:363|ngo.etcd.io/bbolt@v1.3.11/node.go:363> (0xb68871)\<http://ngo.etcd.io/bbolt@v1.3.11/node.go:350|ngo.etcd.io/bbolt@v1.3.11/node.go:350> (0xb6877d)\<http://ngo.etcd.io/bbolt@v1.3.11/bucket.go:592|ngo.etcd.io/bbolt@v1.3.11/bucket.go:592> (0xb5cea4)\<http://ngo.etcd.io/bbolt@v1.3.11/bucket.go:559|ngo.etcd.io/bbolt@v1.3.11/bucket.go:559> (0xb5cc44)\<http://ngo.etcd.io/bbolt@v1.3.11/tx.go:164|ngo.etcd.io/bbolt@v1.3.11/tx.go:164> (0xb6b398)\<http://ngo.etcd.io/bbolt@v1.3.11/db.go:893|ngo.etcd.io/bbolt@v1.3.11/db.go:893> (0xb62109)\<http://ngithub.com/runatlantis/atlantis/server/core/db/boltdb.go:323|ngithub.com/runatlantis/atlantis/server/core/db/boltdb.go:323> (0xb73129)\<http://ngithub.com/runatlantis/atlantis/server/events/db_updater.go:26|ngithub.com/runatlantis/atlantis/server/events/db_updater.go:26> (0x115e057)\<http://ngithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:268|ngithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:268> (0x1171a25)\<http://ngithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:298|ngithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:298> (0x1172164)\<http://ngithub.com/runatlantis/atlantis/server/events/command_runner.go:401|ngithub.com/runatlantis/atlantis/server/events/command_runner.go:401> (0x115478c)\nruntime/asm_amd64.s:1700 (0x478960)\n","json":{"repo":"*redacted*/*redacted*","pull":"535"},"stacktrace":"<http://github.com/runatlantis/atlantis/server/events.(*DefaultCommandRunner).logPanics|github.com/runatlantis/atlantis/server/events.(*DefaultCommandRunner).logPanics>\n\tgithub.com/runatlantis/atlantis/server/events/command_runner.go:555\nruntime.gopanic\n\truntime/panic.go:785\ngo.etcd.io/bbolt.(*freelist).free\n\tgo.etcd.io/bbolt@v1.3.11/freelist.go:175\ngo.etcd.io/bbolt.(*node).spill\n\tgo.etcd.io/bbolt@v1.3.11/node.go:363\ngo.etcd.io/bbolt.(*node).spill\n\tgo.etcd.io/bbolt@v1.3.11/node.go:350\ngo.etcd.io/bbolt.(*Bucket).spill\n\tgo.etcd.io/bbolt@v1.3.11/bucket.go:592\ngo.etcd.io/bbolt.(*Bucket).spill\n\tgo.etcd.io/bbolt@v1.3.11/bucket.go:559\ngo.etcd.io/bbolt.(*Tx).Commit\n\tgo.etcd.io/bbolt@v1.3.11/tx.go:164\ngo.etcd.io/bbolt.(*DB).Update\n\tgo.etcd.io/bbolt@v1.3.11/db.go:893\ngithub.com/runatlantis/atlantis/server/core/db.(*BoltDB).UpdatePullWithResults\n\tgithub.com/runatlantis/atlantis/server/core/db/boltdb.go:323\ngithub.com/runatlantis/atlantis/server/events.(*DBUpdater).updateDB\n\tgithub.com/runatlantis/atlantis/server/events/db_updater.go:26\ngithub.com/runatlantis/atlantis/server/events.(*PlanCommandRunner).run\n\tgithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:268\ngithub.com/runatlantis/atlantis/server/events.(*PlanCommandRunner).Run\n\tgithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:298\ngithub.com/runatlantis/atlantis/server/events.(*DefaultCommandRunner).RunCommentCommand\n\tgithub.com/runatlantis/atlantis/server/events/command_runner.go:401"}
### Environment details
We run Atlantis on Azure App Service, as a Web App.
Atlantis version: v0.33.0 (commit: 618d5ac) (build date: 2025-02-03T202138.676Z)
Deployment method: Terraform.
### Additional Context
This appears to have started happening on December 6, while we were on v0.30.0. We then tried v0.31.0, v0.32.0 and v0.33.0 - the issue persists.
The last PR that was fine was actually us removing two repos from the allowlist and leaving just one repo in there. Following the change, we have: ATLANTIS_REPO_ALLOWLIST=<http://github.com/*redacted*/azure-*redacted*|github.com/*redacted*/azure-*redacted*>
runatlantis/atlantisGitHub
03/21/2025, 1:49 AM110. dir: vpc/us_west_2 workspace: default
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
Plan Summary
110 projects, 2 with changes, 107 with no changes, 1 failed
it would be great that the output also indicate which project is changed. otherwise we have to go over the whole output of each project and it's kind of cumbersome. the reason why we have so many projects planned is because the PR is created by renovate to upgrade the version of some provider.
Describe the solution you'd like
the output be something like this:
Plan Summary
110 projects, 1 with changes, 109 with no changes, 0 failed
changed projects:
2. dir: iam/us_west_2 workspace: default
56. dir: iam/us_west_1 workspace: default
failed projects:
101. dir: s3/us_west_1 workspace: default
Describe the drawbacks of your solution
I don't see too much of a drawback. when atlantis runs, it would save the output list in the memory anyway.
Describe alternatives you've considered
I understand there were similar issues and efforts before, e.g.
#1267
https://github.com/runatlantis/atlantis/pull/2983/files
but these changes are for single dir, not the whole plan summary
runatlantis/atlantisGitHub
03/25/2025, 5:49 PMredis-db-type
.
Describe the drawbacks of your solution
Additional config complexity if this was to be accepted, and down the road folks want to add more redis settings that are only specific to certain redis-db-types.
Describe alternatives you've considered
• Adding a new locking db type that targets a database other than redis, such as postgres.
• Adding a new locking db type that targets object storage implementation like s3.
• Instead of an atlantis change, adding a file sync tool on the server I'm using to deploy atlantis.
runatlantis/atlantisGitHub
03/27/2025, 6:17 AMGitHub
03/28/2025, 3:43 PMGitHub
03/29/2025, 6:38 PMtofu
. However, inspecting the container for v0.31.0 (commit: 245044c) (build date: 2024-11-22T175820.688Z) shows multiple versions of Terraform preinstalled, but not for OpenTofu.
See this terminal transcript for evidence:
/ # tofu --version
OpenTofu v1.8.5
on linux_amd64
/ # tofu
tofu tofu1.8.5
/ # which tofu
/usr/local/bin/tofu
/ # ls -l /usr/local/bin/tofu*
-rwxr-xr-x 1 root root 82448384 Nov 4 20:16 /usr/local/bin/tofu
-rwxr-xr-x 1 root root 82448384 Nov 4 20:16 /usr/local/bin/tofu1.8.5
/ # ls /usr/local/bin
atlantis terraform terraform1.8.5 tofu1.8.5
conftest terraform1.6.6 terraform1.9.8
docker-entrypoint.sh terraform1.7.5 tofu
/ #
(See also Dockerfile#L121-L130 - fixing this would be really, really easy)
atlantis/Dockerfile
Lines 121 to 130 in</runatlantis/atlantis/commit/b5b95a7edf8491c178ec2bd7cec333e2eb214105|b5b95a7>
| RUN ./download-release.sh \ |
| -------------------------------------------------- |
| "terraform" \ |
| "${TARGETPLATFORM}" \ |
| "${DEFAULT_TERRAFORM_VERSION}" \ |
| "1.6.6 1.7.5 1.8.5 ${DEFAULT_TERRAFORM_VERSION}" \ |
| && ./download-release.sh \ |
| "tofu" \ |
| "${TARGETPLATFORM}" \ |
| "${DEFAULT_OPENTOFU_VERSION}" \ |
| "${DEFAULT_OPENTOFU_VERSION}" |
Describe the solution you'd like
I'd like it if Atlantis pre-installed these versions per the migration instructions for migrating from various versions of Terraform to OpenTofu:
1. 1.6.2 for Migrating from Terraform 1.5.x or lower and Migrating from Terraform 1.6.x
2. 1.7.1 for Migrating from Terraform 1.7.x
3. 1.8.2 for Migrating from Terraform 1.8.x
Describe the drawbacks of your solution
This would make the Dockerfile slightly more complicated, and would bloat the container image size by a couple hundred megabytes.
Describe alternatives you've considered
• Maybe installing the latest minor version of OpenTofu would be sufficient, but I haven't tested the migration instructions with different versions yet.
• If #5167 gets merged, and if it solves #4339 this could be a non-issue.
runatlantis/atlantisGitHub
03/31/2025, 4:51 PMPull request must be mergeable before running plan
When I look at the PR in the GitHub UI, the Merge
button is available, which leaves me confused about why Atlantis has a different opinion on the matter.
I believe the underlying issue here is a merge happening around the same time means the github mergeability state temporarily at unknown, which results in Atlantis deciding the PR is not mergeable.
It takes a while before the various plans all come back as a failure, and I can try again.
Describe the solution you'd like
If Atlantis gets back an unknown
value, I'd like it to have a small amount of exponential backoff/retry here. This would mean that if the mergeability is computed shortly (which is normally the case), Atlantis can proceed, instead of forcing the user to wait and retry the command.
Describe the drawbacks of your solution
This might mean a slightly longer time to wait for the result - but this should be mitigated by the fact that the retries are only happening on unknown
, so it should get a result shortly, and this is better than making the user wait much longer to do a full command retry.
Describe alternatives you've considered
This could also be done by checking the documented mergeable attribute, which is null
if mergeability is currently being calculated.
runatlantis/atlantisGitHub
04/07/2025, 3:17 PMGitHub
04/09/2025, 10:46 AM--gh-team-allowlist
flag accepts both team names and team slugs in its rules. Sources: docs and code.
This is for historical reasons: first it used just names, then slug support was added and names were never dropped.
This could become a security concern if someone who's not supposed to be allowed to run a given command, has permissions to create a GitHub team within your organization, since they could configure the name (which need not be unique) to the that of the team that's configured in the allowlist. Slugs, on the other hand, are unique across a GitHub organization.
This is also a problem even if you use slugs in your allowlist. The underlying logic that matches teams to rules does a logical OR of name and slug, meaning a would-be intruder could just name their new team with the slug of the allowed team to escalate their privilege into running restricted Atlantis commands.
The --gitlab-group-allowlist
flag is not affected. Its group matching logic is slugs only. Sources: docs and code.
At the time of writing, no other supported VCS provider supports command allowlisting. Sources: Azure DevOps, BitBucket Cloud and Server, Gitea,
### Reproduction Steps
1. Run Atlantis with --gh-team-allowlist='*:plan, Appliers:apply'
.
2. Create a GitHub team with slug appliers
and name Appliers
. Don't add yourself to it.
3. Create another team with slug intruders
and name Appliers
. Add yourself to this one.
4. Trigger atlantis apply
on an open PR.
### Additional Context
This issue has been previously discussed in Slack and the preferred solution is to drop GitHub team names support from the --gh-team-allowlist
flag, allowing only slugs to be used.
runatlantis/atlantisGitHub
04/10/2025, 7:03 PMparent/*.tf
2. Create a new directory within that directory parent/subdir
3. Move the contents of parent/*.tf
to parent/subdir
4. Create a PR
Atlantis will try to plan both parent/
and parent/subdir
. The latter will succeed and the former will fail because there are no terraform files here.
### Logs
### Environment details
### Additional Context
• Must be a bug in auto discovery. The directory shouldn't even show up if there aren't any terraform files in there. See #3038
runatlantis/atlantisGitHub
04/11/2025, 1:02 AMGitHub
04/12/2025, 2:26 PMGitHub
04/13/2025, 2:16 AMGitHub
04/15/2025, 11:58 AMGitHub
04/23/2025, 4:39 AM--tf-download-url
flag is no longer respected.
### Reproduction Steps
Configure custom terraform download URL
- server
- --tf-download-url="<https://artifactory.company.com/artifactory/hashicorp-remote>"
Trigger the Atlantis plan for the version which needs to be downloaded.
### Logs
atlantis-0 atlantis {"level":"debug","ts":"2025-04-23T04:34:06.361Z","caller":"tfclient/terraform_client.go:306","msg":"Found required_version setting of \"1.11.4\"","json":{"repo":"Org/repo","pull":"105"}}
atlantis-0 atlantis {"level":"error","ts":"2025-04-23T04:34:16.363Z","caller":"tfclient/terraform_client.go:326","msg":"error listing available versions: Get \"<https://releases.hashicorp.com/terraform/index.json\>": context deadline exceeded","json":{"repo":"Org/repo","pull":"105"},"stacktrace":"<http://github.com/runatlantis/atlantis/server/core/terraform/tfclient.(*DefaultClient).DetectVersion|github.com/runatlantis/atlantis/server/core/terraform/tfclient.(*DefaultClient).DetectVersion>\n\tgithub.com/runatlantis/atlantis/server/core/terraform/tfclient/terraform_client.go:326\ngithub.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandContextBuilder).BuildProjectContext\n\tgithub.com/runatlantis/atlantis/server/events/project_command_context_builder.go:127\ngithub.com/runatlantis/atlantis/server/events.(*CommandScopedStatsProjectCommandContextBuilder).BuildProjectContext\n\tgithub.com/runatlantis/atlantis/server/events/project_command_context_builder.go:66\ngithub.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandBuilder).buildAllCommandsByCfg\n\tgithub.com/runatlantis/atlantis/server/events/project_command_builder.go:542\ngithub.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandBuilder).BuildPlanCommands\n\tgithub.com/runatlantis/atlantis/server/events/project_command_builder.go:276\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandBuilder).BuildPlanCommands.func1\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_builder.go:38\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandBuilder).buildAndEmitStats\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_builder.go:71\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandBuilder).BuildPlanCommands\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_builder.go:35\ngithub.com/runatlantis/atlantis/server/events.(*PlanCommandRunner).run\n\tgithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:186\ngithub.com/runatlantis/atlantis/server/events.(*PlanCommandRunner).Run\n\tgithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:299\ngithub.com/runatlantis/atlantis/server/events.(*DefaultCommandRunner).RunCommentCommand\n\tgithub.com/runatlantis/atlantis/server/events/command_runner.go:401"}
### Environment details
### Additional Context
I tracked it down to this call stack, which uses the default URL.
https://github.com/runatlantis/atlantis/blob/main/server/core/terraform/distribution.go#L128
https://github.com/hashicorp/hc-install/blob/main/releases/versions.go#L61
https://github.com/hashicorp/hc-install/blob/main/internal/releasesjson/releases.go#L59
runatlantis/atlantisGitHub
04/23/2025, 6:12 PMautoplan: true|false
for specific project paths/directories in the YAML config, but we can only turn automerge on or off completely. Can we be able to disable automerge for a specific project directory?
Describe the solution you'd like
version: 3
automerge: true
parallel_plan: true
parallel_apply: true
projects:
- dir: project/i/dont/want/automerge
automerge: false
- dir: project/i/want/automerge
- dir: ...
Describe the drawbacks of your solution
If autoplan can be set per-project, why can't automerge?
Describe alternatives you've considered
runatlantis/atlantisGitHub
04/29/2025, 7:41 PMthe default workspace is currently locked by another command that is running for this pull request–wait until the previous command is complete and try againHowever, I'm noticing that, with my configuration, at least, Atlantis appears to be pulling the rug out from under commit 1's workflow, because the
.terraform/
dir is being deleted for the autoplan started by commit 2's workflow, prior to initialization. I'm reasonably confident it's happening here during command building. So, really, it's not just .terraform/
, but the entire working dir that's being deleted:
{
"level": "debug",
"ts": "2025-04-29T185419.093Z",
"caller": "events/working_dir.go:136",
"msg": "repo was already cloned but is not at correct commit, wanted 'XYZ' got 'ZYX'",
"json": {
"repo": "...",
"pull": "999"
}
}
The effect, is that commit 1's workflow invariably dies due to a Terraform dependency (provider or module) going missing. Commit 2's workflow posts the aforementioned comment, and then commit 1's workflow comes back with something like:
│ Error: Failed to install provider
│
│ Error while installing hashicorp/aws v5.96.0: failed to make target path
│ .terraform/providers/registry.terraform.io/hashicorp/aws/5.96.0/linux_amd64
│ absolute: getwd: no such file or directory
or
│ Error: Invalid function argument
│
│ on .terraform/modules/loki-aws.eks-loki.loki_datasource/main.tf line 106, in locals:
│ 106: yaml_file = templatefile("${path.module}/templates/datasource.yml", local.datasource_vars)
│ ├────────────────
│ │ while calling templatefile(path, vars)
│ │ path.module is ".terraform/modules/loki-aws.eks-loki.loki_datasource"
│
│ Invalid value for "path" parameter: no file exists at
│ ".terraform/modules/loki-aws.eks-loki.loki_datasource/templates/datasource.yml";
│ this function works only with files that are distributed as part of the
│ configuration source code, so if this file will be created by a resource in
│ this configuration you must instead obtain this result from an attribute of
│ that resource.
Those are just a couple examples. The exact outcome and error message depends on where Terraform was in the plan. IMO, both are side effects of the working dir being refreshed. I've confirmed this by watching the filesystem during quick, successive commits to a PR.
I expected the lock notice in the PR, but didn't expect commit 1's workflow to fail. I couldn't find another issue where this particular behaviour was identified, but because these circumstances don't seem particularly difficult to stumble into, I'm suspicious there's something I'm doing with my configuration that's causing the issue.
So, I guess my questions are:
1. Is this expected behaviour, given my configuration? I get the cloning logic needs to resync with remote when it's out of sync -- which is what happens when a new commit rolls in -- but I would have thought that a working dir lock would be obtained by commit 1's workflow and that commit 2's workflow would respect that lock before it refreshed the working directory and attempted to execute the plans. FWIW, this log message is what makes me think commit 2's workflow gets all the way to command execution before the working dir lock is found:
{
"level": "error",
"ts": "2025-04-28T193518.756Z",
"caller": "events/instrumented_project_command_runner.go:78",
"msg": "Error running plan operation: the default workspace at path ... is currently locked by another command that is running for this pull request...",
"json": {
"repo": "...",
"pull": "999"
},
"stacktrace": "github.com/runatlantis/atlantis/server/events.RunAndEmitStats..."
}
2. If the above is expected, is there a known configuration strategy to avoid this behaviour? I'm not seeing anything obvious.
Admittedly, there's more debugging I could do, but at this point, I feel like there's either an issue or something more obvious I'm missing.
Thanks very much for your time, and I appreciate any guidance you can offer. Also let me know if more information is needed, and/or if this is more appropriate for discussion. As it stands, it seems like a potential bug.
### Reproduction Steps
1. Configure v0.34.0
server per provided config (policy checks probably aren't necessary).
2. Open a PR or push a commit on an existing one.
3. Before the plan from step 2 can finish, push another commit.
### Logs
See overview
### Environment details
• Atlantis version: v0.34.0
• Deployment method: https://registry.terraform.io/modules/terraform-aws-modules/atlantis/aws/latest (ECS + fargate)
• If not running the latest Atlantis version have you tried to reproduce this issue on the latest version: NA
• Atlantis flags: nothing custom
Atlantis server-side config file:
repos:
- id: /.*/
apply_requirements: [approved, mergeable]
workflow: custom
allowed_overrides: [workflow]
allow_custom_workflows: true
policies:
owners:
users: ["someonerelevant"]
policy_sets:
- name: all_standard_policies
path: policy/
source: local
workflows:
custom:
plan:
steps:
- init
- plan
- run: |
# some tending to a git cache...
policy_check:
steps:
- run: |
# policy check prep...
- show
- policy_check:
extra_args: ["--all-namespaces"]
Repo atlantis.yaml
file:
version: 3
- name: myproject
dir: path/to/project
terraform_version: v1.10.5
### Additional Context
runatlantis/atlantisGitHub
04/30/2025, 11:59 AMrun
command to run policy_check againts source files.
However, when doing so, atlantis is not able to marshal stdout output resulting in check error in the PR.
__Policy Check Error__
unable to unmarshal conftest output
To fix the output, I set custom_policy_check: true
which worked and policy check exited sucessfuly:
Policy Check Failed: Some policy sets did not pass.
Policy Set: Custom
1 test, 1 passed, 0 warnings, 0 failures, 0 exceptions
❗ but, policy was incorrectly interpreted as failing because it checks only for "fail" string in 0 failures
.
https://github.com/runatlantis/atlantis/blob/main/server/events/project_command_runner.go#L531
### Reproduction Steps
1.) run atlantis with attached server config
2.) run atlantis plan
4.) policy check fails because of invalid output
5.) set custom_policy_check to true in server config
6.) run atlantis again
7.) output will be parsed but policy result will be treated incorectly
### Environment details
Atlantis server-side config file:
repos:
- id: /.*/
workflow: custom
delete_source_branch_on_merge: true
custom_policy_check: false
policy_check: true
workflows:
custom:
plan:
steps:
- init
- plan
policy_check:
steps:
- run: conftest test --no-fail *.tf
# or is this one to avoid creating policy files
# - run: conftest test --update git::github.com/kirecek/policy-test?ref=main --no-fail main.tf
policies:
policy_sets:
- name: policy-test
path: /var/run/atlantis/policies
source: local
Repo atlantis.yaml
file:
version: 3
automerge: true
projects:
- name: main
dir: atlantis-tests
workspace: default
autoplan:
enabled: true
when_modified: ["*.tf", "*.tf*", ".hcl", "atlantis.yaml"]
execution_order_group: 1
### Additional Context
To be honest I am not sure if this is user error and we should handle conftest outputs somehow ourselves or if atlantis output parser should be more flexible. WDYT?
runatlantis/atlantisGitHub
04/30/2025, 1:45 PMGitHub
05/01/2025, 6:32 PMRan Plan for 0 projects
in the GitHub comment; you have to go to Atlantis logs to find out about the syntax error.
### Reproduction Steps
My apologies: I have not created a detailed reproduction.
I added a syntax error (adding a git merge conflict market such as <<<<<<< HEAD
to a random line). We enable autoplan with ATLANTIS_AUTOPLAN_MODULES=true
on our Atlantis.
Atlantis posts a comment saying Ran Plan for 0 projects:
and the GitHub status checks atlantis/apply and atlantis/plan are resolved successfully (0/0 projects).
This reproduces with v0.34.0 as well as older versions.
See logs for the error stack trace which comes from autoplan.
### Logs
Logs
{
"level": "warn",
"ts": "2025-05-01T18:24:42.150Z",
"caller": "events/project_command_builder.go:387",
"msg": "error(s) loading project module dependencies: infrastructure/saf.tf:13 - Invalid expression: Expected the start of an expression, but found an invalid expression token.",
"json": {
"repo": "mdg-private/apollo-terraform",
"pull": "1123"
},
"stacktrace": "<http://github.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandBuilder).getMergedProjectCfgs|github.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandBuilder).getMergedProjectCfgs>\n\tgithub.com/runatlantis/atlantis/server/events/project_command_builder.go:387\ngithub.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandBuilder).buildAllCommandsByCfg\n\tgithub.com/runatlantis/atlantis/server/events/project_command_builder.go:518\ngithub.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandBuilder).BuildAutoplanCommands\n\tgithub.com/runatlantis/atlantis/server/events/project_command_builder.go:257\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandBuilder).BuildAutoplanCommands.func1\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_builder.go:29\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandBuilder).buildAndEmitStats\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_builder.go:71\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandBuilder).BuildAutoplanCommands\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_builder.go:26\ngithub.com/runatlantis/atlantis/server/events.(*PlanCommandRunner).runAutoplan\n\tgithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:86\ngithub.com/runatlantis/atlantis/server/events.(*PlanCommandRunner).Run\n\tgithub.com/runatlantis/atlantis/server/events/plan_command_runner.go:297\ngithub.com/runatlantis/atlantis/server/events.(*DefaultCommandRunner).RunAutoplanCommand\n\tgithub.com/runatlantis/atlantis/server/events/command_runner.go:237"
}
### Environment details
I don't have a full minimized config here. We are running v0.34.0 via Helm.
### Additional Context
As a workaround, we've added a non-Atlantis CI check as a GH action (a TF formatter https://github.com/devops-infra/action-format-hcl) which means that something will fail on our PR when there are syntax issues.
runatlantis/atlantisGitHub
05/02/2025, 9:19 PMv0.33.0
is deployed against a GitHub Enterprise Server (GHES) instance, it repeatedly fails to post comments on pull requests with:
401 Must authenticate to access this API
Despite:
1. Generating and validating a GitHub App JWT (returns HTTP 200 from /api/v3/app).
2. Exchanging that JWT for an installation access token (manually via curl).
3. Confirming the App has Read & Write permissions on Issues and Pull Requests and is installed on the target repo.
4. Mounting the private key and webhook secret correctly via a Kubernetes Secret.
5. Setting both ATLANTIS_GH_APP_KEY_FILE and ATLANTIS_GH_WEBHOOK_SECRET in the pod environment.
Restarting the StatefulSet after every configuration change.
#### What does work
I’ve verified that posting an atlantis help comment on a PR in the allowed repository successfully appears in the pod’s logs.
### Reproduction Steps
1. Deploy Atlantis via kubectl apply
2. Bootstraped the GitHub App via Atlantis gtihub-app/setup
URL
3. Store credentials in Kubernetes secrets encoding them via base64 (including app-key file contents)
4. Confirmed Github Enterprise server can ping atlantis
5. Create a PR in the allowed repo and create a comment atlantis help
### Logs
### Environment details
• Atlantis version: v0.33.0
• Deployment method: Kustomization via GKE
• Atlantis flags: None
• Env Vars:
- name: ATLANTIS_DATA_DIR
value: /atlantis
- name: ATLANTIS_PORT
value: "4141"
- name: ATLANTIS_GH_USER
value: fake # recommended by Atlantis docs: https://www.runatlantis.io/docs/access-credentials.html#github-app
- name: ATLANTIS_GH_TOKEN
value: fake # recommended by Atlantis docs: https://www.runatlantis.io/docs/access-credentials.html#github-app
- name: ATLANTIS_GH_ORG
value: readacted_org
- name: ATLANTIS_ATLANTIS_URL
value: https://<ATLANTIS_URL>
- name: ATLANTIS_LOG_LEVEL
value: debug
- name: ATLANTIS_REPO_ALLOWLIST
value: URL/REPO
- name: ATLANTIS_GH_HOSTNAME
value: "HOSTNAME"
- name: ATLANTIS_GH_APP_ID
value: "redacted"
- name: ATLANTIS_GH_APP_KEY_FILE
value: /etc/atlantis/gh-app-key.pem
- name: ATLANTIS_GH_WEBHOOK_SECRET
valueFrom:
secretKeyRef:
name: atlantis-vcs
key: webhook-secret # must generate this with base64 encode
### Additional Context
Decided to use an ATLANTIS_GH_APP_KEY_FILE
but I also tried just passing the value for ATLANTIS_GH_APP_KEY
directly from the Kubernetes secret. That failed to authenticate as well.
runatlantis/atlantis