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

Cloud run tasks (post-plan only) CLI integration #30141

Merged
merged 17 commits into from Feb 25, 2022

Conversation

uturunku1
Copy link
Contributor

@uturunku1 uturunku1 commented Dec 10, 2021

Integration with Terraform Cloud Run Tasks (post-plan stage). Run tasks is a beta feature implemented on Terraform Cloud that will display results after a plan like so:

Screen Shot 2021-12-10 at 11 30 52 AM

These results are currently not being displayed or consumed by Terraform CLI, so with this PR (as well as some changes made to go-tfe hashicorp/go-tfe#286), is implementing the necessary changes to display the output of Run Tasks' result in the CLI:

Screen Shot 2021-12-10 at 11 14 50 AM

IMPLEMENTATION

All changes in this PR are being applied through the op.plan because we want the user to see results of Run Tasks after a plan has found changes to infrastructure and right before the apply operation (so what we call the pre-apply stage).

These changes are also scope to the cloud package. This is to be determined, but we think that the CLI will not offer support for Run Tasks prior to version 1.2

This PR also adds an abstraction when interacting with Cloud Integrations such as Run Tasks, Policy Checks and Cost estimation. The abstraction is not yet applied to Policy Checks and Cost Estimation. But if we were to use it for all three Cloud Integrations, it would simplify and unify output during the pre-apply stage.

TESTING

  1. Ensure your organization has access to the Run Tasks beta. You may have to request access for staging and prod. However, if you are running Atlas on dev mode, you'll have Run Task feature enabled by default.
  2. Follow these steps to add run tasks to the workspace you'll be testing with: https://www.terraform.io/docs/cloud/workspaces/run-tasks.html
  3. We have a go server running on a EC2 instance available for test event hooks. This are the URLs you can add to your run tasks:

http://54.167.177.151/success
http://54.167.177.151/failed
http://54.167.177.151/success?timeout=630 to force a timeout. But you can change the value of timeout to as many seconds you want the server to wait before firing off the webhook back to TFC

  1. Create some config using a cloud config
terraform {
  cloud {
    hostname = "app.staging.terraform.io"
    organization = "test"
    workspaces {
      name = "project"
    }
  }
}

variable "replicas" {
  type = number
  default = 7
}

output "hello_there" {
  value = var.replicas
}

  1. Using a testing workspace, run ./terraform apply to see Run Tasks output right after Cost Estimation output. If you have no tasks added to your workspace in the platform, you should see no output related to Run Tasks.

Screenshots

Task results
Screen Shot 2021-12-15 at 9 53 53 AM

No run tasks defined
Screen Shot 2021-12-15 at 9 59 56 AM

No infrastructure changes (unreachable tasks)
Screen Shot 2021-12-15 at 10 00 05 AM

NOTE: Once this PR has being approved, we will squash the commits.

@chrisarcand chrisarcand added the cloud Related to Terraform Cloud's integration with Terraform label Dec 10, 2021
@brandonc brandonc marked this pull request as ready for review December 15, 2021 17:50
@brandonc brandonc changed the title Work In Progress: Preapply runtasks clioutput Cloud run tasks (pre-apply only) CLI integration Dec 15, 2021
Copy link
Contributor

@barrettclark barrettclark left a comment

Choose a reason for hiding this comment

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

This all looks good to me. I left 1 nit. The PR also has a merge conflict that will need to be resolved.

type taskStageReadFunc func(b *Cloud, stopCtx context.Context) (*tfe.TaskStage, error)

func summarizeTaskResults(taskResults []*tfe.TaskResult) *taskResultSummary {
var pe, er, erm, pa int
Copy link
Contributor

Choose a reason for hiding this comment

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

I like to error on the side of more descriptive variable names. pa appears to be the count of tasks that are passed, so perhaps passedCount. This is not a deal-breaker for the PR, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I totally agree with this change. I guess I was trying to stick a bit to the "Go way" of naming variable, which usually is one letter or very few letters (like "p", "ret", "r", more on that topic: https://blog.devgenius.io/write-better-go-code-by-keeping-your-variable-names-short-13f404ac515c), which I actually find a bit annoying because, like you, I prefer descriptive names. Also, I have noticed that this project does not care much for that type of naming conventions, so I think is best for me to stay away from single letters :) @barrettclark

Copy link
Contributor

Choose a reason for hiding this comment

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

It's wild to me that the Go way would favor terse over descriptive variables. When future me drops into old code and see something like xzz I have to spend more time trying to remember what the heck that means and why. I will try to not swim against the current if our style guide favors brevity, but very much appreciate more verbose and meaningful names in the meantime. Thank you for making this change.

Copy link
Contributor

@nfagerlund nfagerlund left a comment

Choose a reason for hiding this comment

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

I did some manual testing, and it looks pretty sweet! One question about the status of the go-tfe work, but otherwise this seems good.

go.mod Outdated
@@ -41,7 +41,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-plugin v1.4.3
github.com/hashicorp/go-retryablehttp v0.7.0
github.com/hashicorp/go-tfe v0.21.0
github.com/hashicorp/go-tfe v0.20.1-0.20211215223223-3057a43c4f5c
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a gut-check -- are we thinking to wait to merge this PR until the go-tfe changes have merged? Or will we treat this more like the run-up to 1.1.0, when we were building against a WIP branch for a while?

If it's the latter, we should probably rebase the WIP branch and make sure we don't lose any features compared to what were previously at. It looks like with the current status, we might lose run variables?

Copy link
Contributor

Choose a reason for hiding this comment

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

We need to have a slightly better process I think for pre-release go-tfe. I think we are going to wait on the go-tfe merge and depend directly on a branch until the next release of terraform that includes run tasks, similar to what we did in the run up to 1.1. Reason being, we want to make sure the API doesn't shift before releasing in go-tfe. This shouldn't compile if run variables weren't in the base, so it must be based on a run variables pre-release. I take your point and will make sure to rebase this to v0.22.0.

@brandonc
Copy link
Contributor

brandonc commented Jan 6, 2022

Updated go-tfe (using branch run-tasks-integration)

// fetching task_stages.
if strings.HasSuffix(err.Error(), "Invalid include parameter") {
r, err = b.client.Runs.Read(stopCtx, runID)
}
Copy link
Member

Choose a reason for hiding this comment

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

This feels brittle to me. Although it's not ideal, the 'proper' way to do this would be to use the TFP-API-Version header information (exposed in the client here) to conditionally make a single request if the host (TFC or TFE) supports the necessary API version for it; the same as any other addition we've made in the past.

Copy link
Contributor

Choose a reason for hiding this comment

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

That is my intention! Once this is merged I can supplant the next version with run tasks. Feels bad though because I know run tasks will squat on that version for a long time. https://github.com/hashicorp/atlas/pull/11572

Copy link
Contributor Author

@uturunku1 uturunku1 Jan 13, 2022

Choose a reason for hiding this comment

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

If we hit line 335, and err is nil, and TFE or TFC have Run Tasks defined for that workspace, then the CLI would not display anything about run tasks' results but the platform would still show run tasks' results, which is the discrepancy/problem we were trying to solve to begin with. I wasn't sure if that's the behavior we want, but I want to bring that up just in case. I understand these changes are temporary. @brandonc @chrisarcand

Copy link
Contributor

Choose a reason for hiding this comment

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

If we hit line 335, run tasks won't be defined for the workspace because we'll be working against a version of TFE that doesn't support them -- that's what "invalid include parameter" would indicate... But it's not a great feature detection strategy and I'd like to rely on the API version instead.

@sebasslash sebasslash changed the title Cloud run tasks (pre-apply only) CLI integration Cloud run tasks (post-plan only) CLI integration Feb 1, 2022
@@ -335,6 +346,22 @@ in order to capture the filesystem context the remote workspace expects:
// status of the run will be "errored", but there is still policy
// information which should be shown.

// Await pre-apply run tasks
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
// Await pre-apply run tasks
// Await post-plan run tasks

😄

Copy link
Contributor

Choose a reason for hiding this comment

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

Silly me!

uturunku1 and others added 17 commits February 24, 2022 14:02
This change will await the completion of pre-apply run tasks if they
exist on a run and then report the results.

It also adds an abstraction when interacting with cloud integrations such
as policy checking and cost estimation that simplify and unify output,
although I did not go so far as to refactor those callers to use it yet.
go-tfe is pinned to branch run-tasks-integration pending API changes until run tasks support in the CLI is closer to release
Older versions of TFE will not allow "task_stages" as an include parameter. In this case, fall back to reading the Run without additional options.
This commit stems from the change to make post plan the default run task stage, at the
time of this commit's writing! Since pre apply is under internal revision, we have removed
the block that polls the pre apply stage until the team decides to re-add support for pre apply
run tasks.
@sebasslash sebasslash merged commit afb956d into main Feb 25, 2022
@github-actions
Copy link

Reminder for the merging maintainer: if this is a user-visible change, please update the changelog on the appropriate release branch.

@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cloud Related to Terraform Cloud's integration with Terraform
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants