diff --git a/aws/resource_aws_codebuild_webhook.go b/aws/resource_aws_codebuild_webhook.go index da015882f583..5cd9c6001a36 100644 --- a/aws/resource_aws_codebuild_webhook.go +++ b/aws/resource_aws_codebuild_webhook.go @@ -34,8 +34,9 @@ func resourceAwsCodeBuildWebhook() *schema.Resource { Computed: true, }, "secret": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Computed: true, + Sensitive: true, }, "url": { Type: schema.TypeString, @@ -48,7 +49,7 @@ func resourceAwsCodeBuildWebhook() *schema.Resource { func resourceAwsCodeBuildWebhookCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).codebuildconn - _, err := conn.CreateWebhook(&codebuild.CreateWebhookInput{ + resp, err := conn.CreateWebhook(&codebuild.CreateWebhookInput{ ProjectName: aws.String(d.Get("project_name").(string)), BranchFilter: aws.String(d.Get("branch_filter").(string)), }) @@ -56,6 +57,8 @@ func resourceAwsCodeBuildWebhookCreate(d *schema.ResourceData, meta interface{}) return err } + // Secret is only returned on create, so capture it at the start + d.Set("secret", resp.Webhook.Secret) d.SetId(d.Get("project_name").(string)) return resourceAwsCodeBuildWebhookRead(d, meta) @@ -84,8 +87,8 @@ func resourceAwsCodeBuildWebhookRead(d *schema.ResourceData, meta interface{}) e d.Set("branch_filter", project.Webhook.BranchFilter) d.Set("payload_url", project.Webhook.PayloadUrl) d.Set("project_name", project.Name) - d.Set("secret", project.Webhook.Secret) d.Set("url", project.Webhook.Url) + // The secret is never returned after creation, so don't set it here return nil } diff --git a/aws/resource_aws_codebuild_webhook_test.go b/aws/resource_aws_codebuild_webhook_test.go index bac817211106..4af84743f01a 100644 --- a/aws/resource_aws_codebuild_webhook_test.go +++ b/aws/resource_aws_codebuild_webhook_test.go @@ -29,15 +29,15 @@ func TestAccAWSCodeBuildWebhook_GitHub(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "branch_filter", ""), resource.TestCheckResourceAttr(resourceName, "project_name", rName), resource.TestMatchResourceAttr(resourceName, "payload_url", regexp.MustCompile(`^https://`)), - // Checking secret value can be flakey, we may need to wait for its generation - // resource.TestMatchResourceAttr(resourceName, "secret", regexp.MustCompile(`.+`)), + resource.TestCheckResourceAttr(resourceName, "secret", ""), resource.TestMatchResourceAttr(resourceName, "url", regexp.MustCompile(`^https://`)), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"secret"}, }, }, }) @@ -54,21 +54,38 @@ func TestAccAWSCodeBuildWebhook_GitHubEnterprise(t *testing.T) { CheckDestroy: testAccCheckAWSCodeBuildWebhookDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCodeBuildWebhookConfig_GitHubEnterprise(rName), + Config: testAccAWSCodeBuildWebhookConfig_GitHubEnterprise(rName, "dev"), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildWebhookExists(resourceName, &webhook), - resource.TestCheckResourceAttr(resourceName, "branch_filter", ""), + resource.TestCheckResourceAttr(resourceName, "branch_filter", "dev"), + resource.TestCheckResourceAttr(resourceName, "project_name", rName), + resource.TestMatchResourceAttr(resourceName, "payload_url", regexp.MustCompile(`^https://`)), + resource.TestMatchResourceAttr(resourceName, "secret", regexp.MustCompile(`.+`)), + resource.TestCheckResourceAttr(resourceName, "url", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"secret"}, + }, + { + Config: testAccAWSCodeBuildWebhookConfig_GitHubEnterprise(rName, "master"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildWebhookExists(resourceName, &webhook), + resource.TestCheckResourceAttr(resourceName, "branch_filter", "master"), resource.TestCheckResourceAttr(resourceName, "project_name", rName), resource.TestMatchResourceAttr(resourceName, "payload_url", regexp.MustCompile(`^https://`)), - // Checking secret value can be flakey, we may need to wait for its generation - // resource.TestMatchResourceAttr(resourceName, "secret", regexp.MustCompile(`.+`)), + resource.TestMatchResourceAttr(resourceName, "secret", regexp.MustCompile(`.+`)), resource.TestCheckResourceAttr(resourceName, "url", ""), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"secret"}, }, }, }) @@ -99,9 +116,10 @@ func TestAccAWSCodeBuildWebhook_BranchFilter(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"secret"}, }, }, }) @@ -179,7 +197,7 @@ resource "aws_codebuild_webhook" "test" { `) } -func testAccAWSCodeBuildWebhookConfig_GitHubEnterprise(rName string) string { +func testAccAWSCodeBuildWebhookConfig_GitHubEnterprise(rName string, branchFilter string) string { return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` resource "aws_codebuild_project" "test" { name = "%s" @@ -202,9 +220,10 @@ resource "aws_codebuild_project" "test" { } resource "aws_codebuild_webhook" "test" { - project_name = "${aws_codebuild_project.test.name}" + project_name = "${aws_codebuild_project.test.name}" + branch_filter = "%s" } -`, rName) +`, rName, branchFilter) } func testAccAWSCodeBuildWebhookConfig_BranchFilter(rName, branchFilter string) string { diff --git a/website/docs/r/codebuild_webhook.html.markdown b/website/docs/r/codebuild_webhook.html.markdown index e62820137ef2..9c7509741393 100644 --- a/website/docs/r/codebuild_webhook.html.markdown +++ b/website/docs/r/codebuild_webhook.html.markdown @@ -62,6 +62,8 @@ In addition to all arguments above, the following attributes are exported: * `secret` - The secret token of the associated repository. Not returned for all source types. * `url` - The URL to the webhook. +~> **Note:** The `secret` attribute is only set on resource creation, so if the secret is manually rotated, terraform will not pick up the change on subsequent runs. In that case, the webhook resource should be tainted and re-created to get the secret back in sync. + ## Import CodeBuild Webhooks can be imported using the CodeBuild Project name, e.g.