Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support project-level Terraform distribution selection #5167

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

abborg
Copy link

@abborg abborg commented Dec 15, 2024

what

  • Add terraform_distribution project config value
  • Project-level terraform_distribution config value overrides server default
  • Refactor terraform client to avoid cyclic dependencies

why

  • Enable Atlantis to manage multiple stacks or repos with different TF distributions
  • Supports migration from Terraform to OpenTofu project-by-project to de-risk migration

tests

  • I have tested my changes by running unit tests
  • I have tested my changes by creating a test PR that exercises the new functionality

references

Supports #3741

@abborg abborg requested review from a team as code owners December 15, 2024 22:13
@abborg abborg requested review from chenrui333, lukemassa and nitrocode and removed request for a team December 15, 2024 22:13
@github-actions github-actions bot added the go Pull requests that update Go code label Dec 15, 2024
@dosubot dosubot bot added the feature New functionality/enhancement label Dec 15, 2024
@abborg abborg changed the title Support project-level Terraform distribution selection feat:Support project-level Terraform distribution selection Dec 15, 2024
@abborg abborg changed the title feat:Support project-level Terraform distribution selection feat: Support project-level Terraform distribution selection Dec 15, 2024
Add support for terraform_distribution config value in project config.
This config value behaves similarly to terraform_version whereby defaults
taken from the server config will be overridden by project-level values.

Also refactor to prevent terraform client slightly to prevent
cyclical dependencies.

Signed-off-by: Andrew Borg <[email protected]>
@jamengual
Copy link
Contributor

@abborg thanks for the contribution, please gives us some time to review.

@X-Guardian
Copy link
Contributor

@abborg, can you update the relevant documentation in the runatlantis.io directory with your changes.

@X-Guardian X-Guardian added the waiting-on-response Waiting for a response from the user label Dec 17, 2024
@github-actions github-actions bot added the docs Documentation label Dec 17, 2024
@abborg
Copy link
Author

abborg commented Dec 17, 2024

I've updated the relevant documentation. Please let me know if there's any further changes desired.

Copy link
Contributor

@X-Guardian X-Guardian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good @abborg. Just a few suggestions.

cmd/server.go Outdated
Comment on lines 145 to 160
// TFDistributionFlag is deprecated for DefaultTFDistributionFlag
TFDistributionFlag = "tf-distribution"
TFDownloadFlag = "tf-download"
TFDownloadURLFlag = "tf-download-url"
UseTFPluginCache = "use-tf-plugin-cache"
VarFileAllowlistFlag = "var-file-allowlist"
VCSStatusName = "vcs-status-name"
IgnoreVCSStatusNames = "ignore-vcs-status-names"
TFEHostnameFlag = "tfe-hostname"
TFELocalExecutionModeFlag = "tfe-local-execution-mode"
TFETokenFlag = "tfe-token"
WriteGitCredsFlag = "write-git-creds" // nolint: gosec
WebBasicAuthFlag = "web-basic-auth"
WebUsernameFlag = "web-username"
WebPasswordFlag = "web-password"
WebsocketCheckOrigin = "websocket-check-origin"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// TFDistributionFlag is deprecated for DefaultTFDistributionFlag
TFDistributionFlag = "tf-distribution"
TFDownloadFlag = "tf-download"
TFDownloadURLFlag = "tf-download-url"
UseTFPluginCache = "use-tf-plugin-cache"
VarFileAllowlistFlag = "var-file-allowlist"
VCSStatusName = "vcs-status-name"
IgnoreVCSStatusNames = "ignore-vcs-status-names"
TFEHostnameFlag = "tfe-hostname"
TFELocalExecutionModeFlag = "tfe-local-execution-mode"
TFETokenFlag = "tfe-token"
WriteGitCredsFlag = "write-git-creds" // nolint: gosec
WebBasicAuthFlag = "web-basic-auth"
WebUsernameFlag = "web-username"
WebPasswordFlag = "web-password"
WebsocketCheckOrigin = "websocket-check-origin"
TFDistributionFlag = "tf-distribution" // deprecated for DefaultTFDistributionFlag
TFDownloadFlag = "tf-download"
TFDownloadURLFlag = "tf-download-url"
UseTFPluginCache = "use-tf-plugin-cache"
VarFileAllowlistFlag = "var-file-allowlist"
VCSStatusName = "vcs-status-name"
IgnoreVCSStatusNames = "ignore-vcs-status-names"
TFEHostnameFlag = "tfe-hostname"
TFELocalExecutionModeFlag = "tfe-local-execution-mode"
TFETokenFlag = "tfe-token"
WriteGitCredsFlag = "write-git-creds" // nolint: gosec
WebBasicAuthFlag = "web-basic-auth"
WebUsernameFlag = "web-username"
WebPasswordFlag = "web-password"
WebsocketCheckOrigin = "websocket-check-origin"

Reduce the diff.

@@ -73,6 +73,7 @@ var testFlags = map[string]interface{}{
CheckoutStrategyFlag: CheckoutStrategyMerge,
CheckoutDepthFlag: 0,
DataDirFlag: "/path",
DefaultTFDistributionFlag: "terraform",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a ValidateDefaultTFDistribution test?

func validDistribution(value interface{}) error {
distribution := value.(*string)
if distribution != nil && *distribution != "terraform" && *distribution != "opentofu" {
return fmt.Errorf("%q is not a valid terraform_distribution, only %q and %q are supported", *distribution, "terraform", "opentofu")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return fmt.Errorf("%q is not a valid terraform_distribution, only %q and %q are supported", *distribution, "terraform", "opentofu")
return fmt.Errorf("'%s' is not a valid terraform_distribution, only '%s' and '%s' are supported", *distribution, "terraform", "opentofu")

%q produces a double quoted string which then needs to be escaped in the JSON log output. Single quoted strings are better as they don't have to be escaped.

@@ -39,19 +41,27 @@ func (a *ApplyStepRunner) Run(ctx command.ProjectContext, extraArgs []string, pa

ctx.Log.Info("starting apply")
var out string
tfDistribution := a.DefaultTFDistribution
if ctx.TerraformDistribution != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test that covers this condition? Same question for all runners.

@@ -14,7 +14,7 @@
// Modified hereafter by contributors to runatlantis/atlantis.
//
// Package terraform handles the actual running of terraform commands.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Package terraform handles the actual running of terraform commands.
// Package tfclient handles the actual running of terraform commands.

Comment on lines 35 to 36
"github.com/runatlantis/atlantis/server/core/terraform"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"github.com/runatlantis/atlantis/server/core/terraform"
"github.com/runatlantis/atlantis/server/core/terraform"

Remove blank line

Comment on lines 112 to 113
// TFDistribution is deprecated in favor of DefaultTFDistribution
TFDistribution string `mapstructure:"tf-distribution"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// TFDistribution is deprecated in favor of DefaultTFDistribution
TFDistribution string `mapstructure:"tf-distribution"`
TFDistribution string `mapstructure:"tf-distribution"` // deprecated in favor of DefaultTFDistribution

Reduce diff

@X-Guardian
Copy link
Contributor

@abborg
Copy link
Author

abborg commented Dec 18, 2024

There are some test failures too: https://github.com/runatlantis/atlantis/actions/runs/12394308257/job/34599029347?pr=5167

@X-Guardian I should be able to apply your suggestions and fix remaining test failures later today.

@github-actions github-actions bot added build Relating to how we build Atlantis github-actions labels Dec 20, 2024
@abborg
Copy link
Author

abborg commented Dec 20, 2024

@X-Guardian I made a mistake when attempting to correct a commit missing a signoff and it appears I mistakenly signed off some commits from the earlier merges of main. Please let me know how you'd like me to proceed.

Edit: I was able to checkout the previous head, make the correct signoff and then push the changes.

@obscurerichard
Copy link

obscurerichard commented Dec 21, 2024

It looks like this relates to the OpenTofu epic #3741 - does this also provide a resolution to Support OpenTofu auto download #4339?

(I'm not one of the Atlantis developers, just an interested Atlantis user starting to experiment with OpenTofu - and this is very exciting to see!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Relating to how we build Atlantis docs Documentation feature New functionality/enhancement github-actions go Pull requests that update Go code waiting-on-response Waiting for a response from the user
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants