diff --git a/internal/provider/resource_tfe_project_test.go b/internal/provider/resource_tfe_project_test.go index 7854f2815..23b77a45d 100644 --- a/internal/provider/resource_tfe_project_test.go +++ b/internal/provider/resource_tfe_project_test.go @@ -37,8 +37,6 @@ func TestAccTFEProject_basic(t *testing.T) { "tfe_project.foobar", "description", "project description"), resource.TestCheckResourceAttr( "tfe_project.foobar", "organization", fmt.Sprintf("tst-terraform-%d", rInt)), - resource.TestCheckResourceAttr( - "tfe_project.foobar", "auto_destroy_activity_duration", "3d"), ), }, }, @@ -131,6 +129,43 @@ func TestAccTFEProject_import(t *testing.T) { }) } +func TestAccTFEProject_withAutoDestroy(t *testing.T) { + project := &tfe.Project{} + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEProject_basicWithAutoDestroy(rInt, "3d"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEProjectExists( + "tfe_project.foobar", project), + testAccCheckTFEProjectAttributes(project), + resource.TestCheckResourceAttr( + "tfe_project.foobar", "auto_destroy_activity_duration", "3d"), + ), + }, + { + Config: testAccTFEProject_basicWithAutoDestroy(rInt, "10m"), + ExpectError: regexp.MustCompile(`must be 1-4 digits followed by d or h`), + }, + { + Config: testAccTFEProject_basic(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEProjectExists( + "tfe_project.foobar", project), + testAccCheckTFEProjectAttributes(project), + resource.TestCheckResourceAttr( + "tfe_project.foobar", "auto_destroy_activity_duration", ""), + ), + }, + }, + }) +} + func testAccTFEProject_update(rInt int) string { return fmt.Sprintf(` resource "tfe_organization" "foobar" { @@ -184,6 +219,20 @@ resource "tfe_project" "foobar" { }`, rInt) } +func testAccTFEProject_basicWithAutoDestroy(rInt int, duration string) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tst-terraform-%d" + email = "admin@company.com" +} + +resource "tfe_project" "foobar" { + organization = tfe_organization.foobar.name + name = "projecttest" + auto_destroy_activity_duration = "%s" +}`, rInt, duration) +} + func testAccCheckTFEProjectDestroy(s *terraform.State) error { config := testAccProvider.Meta().(ConfiguredClient) diff --git a/internal/provider/resource_tfe_workspace.go b/internal/provider/resource_tfe_workspace.go index 77d942759..12986e263 100644 --- a/internal/provider/resource_tfe_workspace.go +++ b/internal/provider/resource_tfe_workspace.go @@ -370,7 +370,7 @@ func resourceTFEWorkspaceCreate(d *schema.ResourceData, meta interface{}) error } } - if v, ok := d.GetOk("inherits_project_auto_destroy"); ok { + if v, ok := d.GetOkExists("inherits_project_auto_destroy"); ok { options.InheritsProjectAutoDestroy = tfe.Bool(v.(bool)) } @@ -702,6 +702,12 @@ func resourceTFEWorkspaceUpdate(d *schema.ResourceData, meta interface{}) error } } + if d.HasChange("inherits_project_auto_destroy") { + if v, ok := d.GetOkExists("inherits_project_auto_destroy"); ok { + options.InheritsProjectAutoDestroy = tfe.Bool(v.(bool)) + } + } + if hasAutoDestroyAtChange(d) { autoDestroyAt, err := expandAutoDestroyAt(d) if err != nil { @@ -719,12 +725,6 @@ func resourceTFEWorkspaceUpdate(d *schema.ResourceData, meta interface{}) error } } - if d.HasChange("inherits_project_auto_destroy") { - if v, ok := d.GetOkExists("inherits_project_auto_destroy"); ok { - options.InheritsProjectAutoDestroy = tfe.Bool(v.(bool)) - } - } - if d.HasChange("execution_mode") { if v, ok := d.GetOk("execution_mode"); ok { options.ExecutionMode = tfe.String(v.(string)) diff --git a/internal/provider/resource_tfe_workspace_test.go b/internal/provider/resource_tfe_workspace_test.go index 7d8a23526..5178f56c4 100644 --- a/internal/provider/resource_tfe_workspace_test.go +++ b/internal/provider/resource_tfe_workspace_test.go @@ -2815,6 +2815,126 @@ func TestAccTFEWorkspace_validationAutoDestroyDuration(t *testing.T) { }) } +func TestAccTFEWorkspace_createWithAutoDestroyDurationInProject(t *testing.T) { + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEWorkspaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEWorkspace_basicWithAutoDestroyDurationInProject(rInt, "1d", "3d"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_activity_duration", "3d"), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "false"), + ), + }, + }, + }) +} + +func TestAccTFEWorkspace_updateWithAutoDestroyDurationInProject(t *testing.T) { + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEWorkspaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEWorkspace_basicWithAutoDestroyDurationInProject(rInt, "1d", "3d"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_activity_duration", "3d"), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "false"), + ), + }, + { + Config: testAccTFEWorkspace_basicWithAutoDestroyDurationInProject(rInt, "2d", "5d"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_activity_duration", "5d"), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "false"), + ), + }, + { + Config: testAccTFEWorkspace_basicWithAutoDestroyDuration(rInt, "1d"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_activity_duration", "1d"), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "false"), + ), + }, + { + Config: testAccTFEWorkspace_basicInProject(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_activity_duration", ""), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "true"), + ), + }, + }, + }) +} + +func TestAccTFEWorkspace_createWithAutoDestroyAtInProject(t *testing.T) { + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEWorkspaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEWorkspace_basicWithAutoDestroyAtInProject(rInt, "1d"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_at", "2100-01-01T00:00:00Z"), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "false"), + ), + }, + }, + }) +} + +func TestAccTFEWorkspace_updateWithAutoDestroyAtInProject(t *testing.T) { + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEWorkspaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEWorkspace_basicWithAutoDestroyAtInProject(rInt, "1d"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_at", "2100-01-01T00:00:00Z"), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "false"), + ), + }, + { + Config: testAccTFEWorkspace_basicWithAutoDestroyAt(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_at", "2100-01-01T00:00:00Z"), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "false"), + ), + }, + { + Config: testAccTFEWorkspace_basicInProject(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEWorkspaceExists("tfe_workspace.foobar", &tfe.Workspace{}, testAccProvider), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "auto_destroy_at", ""), + resource.TestCheckResourceAttr("tfe_workspace.foobar", "inherits_project_auto_destroy", "true"), + ), + }, + }, + }) +} + func TestAccTFEWorkspace_createWithSourceURL(t *testing.T) { rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() @@ -3136,15 +3256,45 @@ resource "tfe_organization" "foobar" { email = "admin@company.com" } +resource "tfe_project" "new_project" { + name = "testproject" + organization = tfe_organization.foobar.id +} + resource "tfe_workspace" "foobar" { - name = "workspace-test" - organization = tfe_organization.foobar.id - auto_apply = true - file_triggers_enabled = false - auto_destroy_at = "2100-01-01T00:00:00Z" + name = "workspace-test" + organization = tfe_organization.foobar.id + project_id = tfe_project.new_project.id + auto_apply = true + file_triggers_enabled = false + auto_destroy_at = "2100-01-01T00:00:00Z" + inherits_project_auto_destroy = false }`, rInt) } +func testAccTFEWorkspace_basicWithAutoDestroyAtInProject(rInt int, projectDuration string) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tst-terraform-%d" + email = "admin@company.com" +} + +resource "tfe_project" "new_project" { + name = "testproject" + organization = tfe_organization.foobar.id + auto_destroy_activity_duration = "%s" +} + +resource "tfe_workspace" "foobar" { + name = "workspace-test" + organization = tfe_organization.foobar.id + project_id = tfe_project.new_project.id + auto_apply = true + auto_destroy_at = "2100-01-01T00:00:00Z" + inherits_project_auto_destroy = false +}`, rInt, projectDuration) +} + func testAccTFEWorkspace_basicWithAutoDestroyDuration(rInt int, value string) string { return fmt.Sprintf(` resource "tfe_organization" "foobar" { @@ -3152,15 +3302,65 @@ resource "tfe_organization" "foobar" { email = "admin@company.com" } +resource "tfe_project" "new_project" { + name = "testproject" + organization = tfe_organization.foobar.id +} + resource "tfe_workspace" "foobar" { name = "workspace-test" organization = tfe_organization.foobar.id + project_id = tfe_project.new_project.id auto_apply = true - file_triggers_enabled = false + file_triggers_enabled = false auto_destroy_activity_duration = "%s" + inherits_project_auto_destroy = false }`, rInt, value) } +func testAccTFEWorkspace_basicWithAutoDestroyDurationInProject(rInt int, projectDuration string, workspaceDuration string) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tst-terraform-%d" + email = "admin@company.com" +} + +resource "tfe_project" "new_project" { + name = "testproject" + organization = tfe_organization.foobar.id + auto_destroy_activity_duration = "%s" +} + +resource "tfe_workspace" "foobar" { + name = "workspace-test" + organization = tfe_organization.foobar.id + project_id = tfe_project.new_project.id + auto_apply = true + auto_destroy_activity_duration = "%s" + inherits_project_auto_destroy = false +}`, rInt, projectDuration, workspaceDuration) +} + +func testAccTFEWorkspace_basicInProject(rInt int) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tst-terraform-%d" + email = "admin@company.com" +} + +resource "tfe_project" "new_project" { + name = "testproject" + organization = tfe_organization.foobar.id +} + +resource "tfe_workspace" "foobar" { + name = "workspace-test" + project_id = tfe_project.new_project.id + organization = tfe_organization.foobar.id + auto_apply = true +}`, rInt) +} + func testAccTFEWorkspace_operationsTrue(organization string) string { return fmt.Sprintf(` resource "tfe_workspace" "foobar" {