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

Add support for run triggers #132

Merged
merged 4 commits into from Feb 20, 2020
Merged

Add support for run triggers #132

merged 4 commits into from Feb 20, 2020

Conversation

lafentres
Copy link
Contributor

@lafentres lafentres commented Feb 13, 2020

Description

This PR adds support and documentation for creating, destroying, and importing run triggers.

Run trigger resources require:

  1. workspace_external_id - external id of the workspace that owns the run trigger. This is the workspace where runs will be triggered.
  2. sourceable_id - id of the sourceable. The sourceable must be a workspace.

Updating workspace_external_id or sourceable_id will force the creation of a new run trigger resource.

Testing plan

  1. Build the provider by running make build
  2. Move it to your Terraform plugins directory
    mv $GOPATH/bin/terraform-provider-tfe ~/.terraform.d/plugins
    
  3. Copy this config, replace hostname and email values, and save it as main.tf. You'll be modifying it in the steps below. Make sure you have a user token added to your ~/.terraformrc file for your TFC hostname.
    provider "tfe" {
      hostname = "<YOUR_TFC_HERE>"
    }
    
    resource "tfe_organization" "run-triggers-organization" {
      name  = "run-triggers-provider-test"
      email = "<YOUR_EMAIL_HERE>"
    }
    
    resource "tfe_workspace" "workspace1" {
      name         = "workspace-test1"
      organization = tfe_organization.run-triggers-organization.id
    }
    
    resource "tfe_workspace" "workspace2" {
      name         = "workspace-test2"
      organization = tfe_organization.run-triggers-organization.id
    }
    
    resource "tfe_workspace" "workspace3" {
      name         = "workspace-test3"
      organization = tfe_organization.run-triggers-organization.id
    }
    
    resource "tfe_run_trigger" "run-trigger1" {
      workspace_external_id = tfe_workspace.workspace2.external_id
      sourceable_id         = tfe_workspace.workspace1.external_id
    }
    
    resource "tfe_run_trigger" "run-trigger2" {
      workspace_external_id = tfe_workspace.workspace3.external_id
      sourceable_id         = tfe_workspace.workspace2.external_id
    }
    
  4. Run terraform init.

Happy path:

  1. Run terraform apply. This should succeed. Check that a run trigger has been created on workspace2 with a source workspace of workspace1. Check that a run trigger has been created on workspace3 with a source workspace of workspace2.

Loops:

  1. Add the following to the end of your config:
    resource "tfe_run_trigger" "run-trigger3" {
      workspace_external_id = tfe_workspace.workspace1.external_id
      sourceable_id         = tfe_workspace.workspace3.external_id
    }
    
  2. Run terraform apply. This should fail with an error like the following:
    Error: Error creating run trigger on workspace ws-iAKEX2trrWtU4VjU with sourceable ws-Vtm7pFiZ4UNTKN8K: Invalid Attribute
    
    Run Trigger must not create a loop
    

Workspace and sourceable using same workspace

  1. Change your run-trigger3 resource block and make workspace_external_id and sourceable_id both point to workspace1:
    resource "tfe_run_trigger" "run-trigger3" {
      workspace_external_id = tfe_workspace.workspace1.external_id
      sourceable_id         = tfe_workspace.workspace1.external_id
    }
    
  2. Run terraform apply. This should fail with an error like the following:
    Error: Error creating run trigger on workspace ws-iAKEX2trrWtU4VjU with sourceable ws-iAKEX2trrWtU4VjU: Invalid Attribute
    
    Sourceable can't be the same as workspace
    
  3. Remove the run-trigger3 resource block from your config before moving on to the next section.

Destroying run trigger

  1. Remove the run-trigger2 resource block from your config.
  2. Run terraform apply. This should succeed and should destroy run-trigger2. Check that the run trigger on workspace3 with a source workspace of workspace2 was destroyed.

Changing workspace_external_id forces new run trigger:

  1. Change your run-trigger1 resource block and make workspace_external_id to point to workspace3
    resource "tfe_run_trigger" "run-trigger1" {
      workspace_external_id = tfe_workspace.workspace3.external_id
      sourceable_id         = tfe_workspace.workspace1.external_id
    }
    
  2. Run terraform apply. The output should show that one resource was added and 1 was destroyed.
    Terraform will perform the following actions:
    
      # tfe_run_trigger.run-trigger1 must be replaced
    -/+ resource "tfe_run_trigger" "run-trigger1" {
          ~ id                    = "OLD_RUN_TRIGGER_ID" -> (known after apply)
            sourceable_id         = "WORKSPACE1_ID"
          ~ workspace_external_id = "WORKSPACE2_ID" -> "WORKSPACE3_ID" # forces replacement
        }
    
    Plan: 1 to add, 0 to change, 1 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    tfe_run_trigger.run-trigger1: Destroying... [id=OLD_RUN_TRIGGER_ID]
    tfe_run_trigger.run-trigger1: Destruction complete after 0s
    tfe_run_trigger.run-trigger1: Creating...
    tfe_run_trigger.run-trigger1: Creation complete after 1s [id=NEW_RUN_TRIGGER_ID]
    
    Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
    

Changing sourceable_id forces new run trigger:

  1. Change your run-trigger1 resource block and make sourceable_id to point to workspace2
    resource "tfe_run_trigger" "run-trigger1" {
      workspace_external_id = tfe_workspace.workspace3.external_id
      sourceable_id         = tfe_workspace.workspace2.external_id
    }
    
  2. Run terraform apply. The output should show that one resource was added and 1 was destroyed.
    Terraform will perform the following actions:
    
      # tfe_run_trigger.run-trigger1 must be replaced
    -/+ resource "tfe_run_trigger" "run-trigger1" {
          ~ id                    = "OLD_RUN_TRIGGER_ID" -> (known after apply)
          ~ sourceable_id         = "WORKSPACE1_ID" -> "WORKSPACE2_ID" # forces replacement
            workspace_external_id = "WORKSPACE3_ID"
        }
    
    Plan: 1 to add, 0 to change, 1 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    tfe_run_trigger.run-trigger1: Destroying... [id=OLD_RUN_TRIGGER_ID]
    tfe_run_trigger.run-trigger1: Destruction complete after 1s
    tfe_run_trigger.run-trigger1: Creating...
    tfe_run_trigger.run-trigger1: Creation complete after 0s [id=NEW_RUN_TRIGGER_ID]
    
    Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
    

External links

Output from acceptance tests

$ envchain terraform-provider-tfe make testacc
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test $(go list ./... |grep -v 'vendor') -v  -timeout 15m
?       github.com/terraform-providers/terraform-provider-tfe   [no test files]
=== RUN   TestAccTFESSHKeyDataSource_basic
--- PASS: TestAccTFESSHKeyDataSource_basic (8.68s)
=== RUN   TestAccTFETeamAccessDataSource_basic
--- PASS: TestAccTFETeamAccessDataSource_basic (13.35s)
=== RUN   TestAccTFETeamDataSource_basic
--- PASS: TestAccTFETeamDataSource_basic (7.86s)
=== RUN   TestAccTFEWorkspaceIDsDataSource_basic
--- PASS: TestAccTFEWorkspaceIDsDataSource_basic (12.19s)
=== RUN   TestAccTFEWorkspaceIDsDataSource_wildcard
--- PASS: TestAccTFEWorkspaceIDsDataSource_wildcard (12.65s)
=== RUN   TestAccTFEWorkspaceDataSource_basic
--- PASS: TestAccTFEWorkspaceDataSource_basic (8.29s)
=== RUN   TestProvider
--- PASS: TestProvider (0.00s)
=== RUN   TestProvider_impl
--- PASS: TestProvider_impl (0.00s)
=== RUN   TestProvider_versionConstraints
--- PASS: TestProvider_versionConstraints (0.00s)
=== RUN   TestAccTFENotificationConfiguration_basic
--- PASS: TestAccTFENotificationConfiguration_basic (8.19s)
=== RUN   TestAccTFENotificationConfiguration_update
--- PASS: TestAccTFENotificationConfiguration_update (13.32s)
=== RUN   TestAccTFENotificationConfiguration_slackWithToken
--- PASS: TestAccTFENotificationConfiguration_slackWithToken (4.43s)
=== RUN   TestAccTFENotificationConfiguration_duplicateTriggers
--- PASS: TestAccTFENotificationConfiguration_duplicateTriggers (7.96s)
=== RUN   TestAccTFENotificationConfigurationImport
--- PASS: TestAccTFENotificationConfigurationImport (8.25s)
=== RUN   TestAccTFEOAuthClient_basic
--- PASS: TestAccTFEOAuthClient_basic (7.21s)
=== RUN   TestAccTFEOrganization_basic
--- PASS: TestAccTFEOrganization_basic (9.99s)
=== RUN   TestAccTFEOrganization_update
--- PASS: TestAccTFEOrganization_update (8.23s)
=== RUN   TestAccTFEOrganization_import
--- PASS: TestAccTFEOrganization_import (5.28s)
=== RUN   TestAccTFEOrganizationToken_basic
--- PASS: TestAccTFEOrganizationToken_basic (6.77s)
=== RUN   TestAccTFEOrganizationToken_existsWithoutForce
--- PASS: TestAccTFEOrganizationToken_existsWithoutForce (8.77s)
=== RUN   TestAccTFEOrganizationToken_existsWithForce
--- PASS: TestAccTFEOrganizationToken_existsWithForce (12.17s)
=== RUN   TestAccTFEOrganizationToken_import
--- PASS: TestAccTFEOrganizationToken_import (7.46s)
=== RUN   TestAccTFEPolicySetParameter_basic
--- PASS: TestAccTFEPolicySetParameter_basic (9.76s)
=== RUN   TestAccTFEPolicySetParameter_update
--- PASS: TestAccTFEPolicySetParameter_update (20.24s)
=== RUN   TestAccTFEPolicySetParameter_import
--- PASS: TestAccTFEPolicySetParameter_import (9.85s)
=== RUN   TestAccTFEPolicySet_basic
--- PASS: TestAccTFEPolicySet_basic (10.53s)
=== RUN   TestAccTFEPolicySet_update
--- PASS: TestAccTFEPolicySet_update (18.49s)
=== RUN   TestAccTFEPolicySet_updateEmpty
--- PASS: TestAccTFEPolicySet_updateEmpty (14.50s)
=== RUN   TestAccTFEPolicySet_updatePopulated
--- PASS: TestAccTFEPolicySet_updatePopulated (25.96s)
=== RUN   TestAccTFEPolicySet_updateToGlobal
--- PASS: TestAccTFEPolicySet_updateToGlobal (17.75s)
=== RUN   TestAccTFEPolicySet_updateToWorkspace
--- PASS: TestAccTFEPolicySet_updateToWorkspace (18.24s)
=== RUN   TestAccTFEPolicySet_vcs
--- PASS: TestAccTFEPolicySet_vcs (13.83s)
=== RUN   TestAccTFEPolicySetImport
--- PASS: TestAccTFEPolicySetImport (15.38s)
=== RUN   TestAccTFERunTrigger_basic
--- PASS: TestAccTFERunTrigger_basic (9.23s)
=== RUN   TestAccTFERunTriggerImport
--- PASS: TestAccTFERunTriggerImport (9.16s)
=== RUN   TestAccTFESentinelPolicy_basic
--- PASS: TestAccTFESentinelPolicy_basic (9.35s)
=== RUN   TestAccTFESentinelPolicy_update
--- PASS: TestAccTFESentinelPolicy_update (19.17s)
=== RUN   TestAccTFESentinelPolicy_import
--- PASS: TestAccTFESentinelPolicy_import (10.35s)
=== RUN   TestAccTFESSHKey_basic
--- PASS: TestAccTFESSHKey_basic (11.71s)
=== RUN   TestAccTFESSHKey_update
--- PASS: TestAccTFESSHKey_update (11.13s)
=== RUN   TestAccTFETeamAccess_basic
--- PASS: TestAccTFETeamAccess_basic (9.64s)
=== RUN   TestAccTFETeamAccess_import
--- PASS: TestAccTFETeamAccess_import (10.19s)
=== RUN   TestPackTeamMemberID
--- PASS: TestPackTeamMemberID (0.00s)
=== RUN   TestUnpackTeamMemberID
--- PASS: TestUnpackTeamMemberID (0.00s)
=== RUN   TestAccTFETeamMember_basic
--- FAIL: TestAccTFETeamMember_basic (4.77s)
    testing.go:569: Step 0 error: errors during apply:
        
        Error: Error adding user "admin" to team team-7KzHoyQ1m7YrZu6v: bad request
        
        admin is not a member of the organization
        
          on /var/folders/jq/kcfxsqpd5hz_2cg_w9c_2hf40000gp/T/tf-test951146631/main.tf line 12:
          (source code not available)
        
        
=== RUN   TestAccTFETeamMember_import
--- FAIL: TestAccTFETeamMember_import (4.71s)
    testing.go:569: Step 0 error: errors during apply:
        
        Error: Error adding user "admin" to team team-J6M5hSneXQhotdtD: bad request
        
        admin is not a member of the organization
        
          on /var/folders/jq/kcfxsqpd5hz_2cg_w9c_2hf40000gp/T/tf-test112199761/main.tf line 12:
          (source code not available)
        
        
=== RUN   TestAccTFETeamMembers_basic
--- FAIL: TestAccTFETeamMembers_basic (4.56s)
    testing.go:569: Step 0 error: errors during apply:
        
        Error: Error adding users to team team-G3uDLdVTdx7TN8o8: bad request
        
        tfe_provider_1 is not a member of the organization
        
          on /var/folders/jq/kcfxsqpd5hz_2cg_w9c_2hf40000gp/T/tf-test922885291/main.tf line 12:
          (source code not available)
        
        
=== RUN   TestAccTFETeamMembers_update
--- FAIL: TestAccTFETeamMembers_update (4.76s)
    testing.go:569: Step 0 error: errors during apply:
        
        Error: Error adding users to team team-oB6hsA1GKWNwM6yw: bad request
        
        tfe_provider_1 is not a member of the organization
        
          on /var/folders/jq/kcfxsqpd5hz_2cg_w9c_2hf40000gp/T/tf-test234840597/main.tf line 12:
          (source code not available)
        
        
=== RUN   TestAccTFETeamMembers_import
--- FAIL: TestAccTFETeamMembers_import (4.67s)
    testing.go:569: Step 0 error: errors during apply:
        
        Error: Error adding users to team team-Z4MaL3yDkk1c3YQw: bad request
        
        tfe_provider_1 is not a member of the organization
        
          on /var/folders/jq/kcfxsqpd5hz_2cg_w9c_2hf40000gp/T/tf-test255988495/main.tf line 12:
          (source code not available)
        
        
=== RUN   TestAccTFETeam_basic
--- PASS: TestAccTFETeam_basic (7.17s)
=== RUN   TestAccTFETeam_import
--- PASS: TestAccTFETeam_import (12.07s)
=== RUN   TestAccTFETeamToken_basic
--- PASS: TestAccTFETeamToken_basic (8.42s)
=== RUN   TestAccTFETeamToken_existsWithoutForce
--- PASS: TestAccTFETeamToken_existsWithoutForce (11.27s)
=== RUN   TestAccTFETeamToken_existsWithForce
--- PASS: TestAccTFETeamToken_existsWithForce (14.56s)
=== RUN   TestAccTFETeamToken_import
--- PASS: TestAccTFETeamToken_import (8.55s)
=== RUN   TestAccTFEVariable_basic
--- PASS: TestAccTFEVariable_basic (10.04s)
=== RUN   TestAccTFEVariable_update
--- PASS: TestAccTFEVariable_update (21.51s)
=== RUN   TestAccTFEVariable_import
--- PASS: TestAccTFEVariable_import (10.21s)
=== RUN   TestPackWorkspaceID
--- PASS: TestPackWorkspaceID (0.00s)
=== RUN   TestUnpackWorkspaceID
--- PASS: TestUnpackWorkspaceID (0.00s)
=== RUN   TestAccTFEWorkspace_basic
--- PASS: TestAccTFEWorkspace_basic (6.56s)
=== RUN   TestAccTFEWorkspace_monorepo
--- PASS: TestAccTFEWorkspace_monorepo (6.63s)
=== RUN   TestAccTFEWorkspace_renamed
--- PASS: TestAccTFEWorkspace_renamed (10.08s)
=== RUN   TestAccTFEWorkspace_update
--- FAIL: TestAccTFEWorkspace_update (9.35s)
    testing.go:569: Step 1 error: Check failed: Check 2/12 error: Bad operations: true
=== RUN   TestAccTFEWorkspace_updateFileTriggers
--- PASS: TestAccTFEWorkspace_updateFileTriggers (10.80s)
=== RUN   TestAccTFEWorkspace_sshKey
--- PASS: TestAccTFEWorkspace_sshKey (21.97s)
=== RUN   TestAccTFEWorkspace_import
--- PASS: TestAccTFEWorkspace_import (7.17s)
FAIL
FAIL    github.com/terraform-providers/terraform-provider-tfe/tfe       646.696s
?       github.com/terraform-providers/terraform-provider-tfe/version   [no test files]
make: *** [testacc] Error 1

@ghost ghost added size/XL dependencies and removed size/L labels Feb 18, 2020
@lafentres lafentres changed the title [DRAFT] Add support for run triggers Add support for run triggers Feb 18, 2020
@lafentres lafentres marked this pull request as ready for review February 18, 2020 22:08
@lafentres lafentres requested a review from a team February 18, 2020 22:09
Copy link

@stasquatch stasquatch left a comment

Choose a reason for hiding this comment

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

LGTM. Tested locally and everything ran as expected. Thank you for such a detailed test plan!

@lafentres lafentres merged commit 52ba7ca into master Feb 20, 2020
@lafentres lafentres deleted the lafentres/run-triggers branch February 20, 2020 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants