diff --git a/aws/resource_aws_codebuild_project.go b/aws/resource_aws_codebuild_project.go index 5642522f928..4703c73fdd9 100644 --- a/aws/resource_aws_codebuild_project.go +++ b/aws/resource_aws_codebuild_project.go @@ -197,6 +197,26 @@ func resourceAwsCodeBuildProject() *schema.Resource { Optional: true, ValidateFunc: validation.StringMatch(regexp.MustCompile(`\.(pem|zip)$`), "must end in .pem or .zip"), }, + "registry_credential": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "credential": { + Type: schema.TypeString, + Required: true, + }, + "credential_provider": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + codebuild.CredentialProviderTypeSecretsManager, + }, false), + }, + }, + }, + }, }, }, Set: resourceAwsCodeBuildProjectEnvironmentHash, @@ -659,6 +679,22 @@ func expandProjectEnvironment(d *schema.ResourceData) *codebuild.ProjectEnvironm projectEnv.ImagePullCredentialsType = aws.String(v.(string)) } + if v, ok := envConfig["registry_credential"]; ok && len(v.([]interface{})) > 0 { + config := v.([]interface{})[0].(map[string]interface{}) + + projectRegistryCredential := &codebuild.RegistryCredential{} + + if v, ok := config["credential"]; ok && v.(string) != "" { + projectRegistryCredential.Credential = aws.String(v.(string)) + } + + if v, ok := config["credential_provider"]; ok && v.(string) != "" { + projectRegistryCredential.CredentialProvider = aws.String(v.(string)) + } + + projectEnv.RegistryCredential = projectRegistryCredential + } + if v := envConfig["environment_variable"]; v != nil { envVariables := v.([]interface{}) if len(envVariables) > 0 { @@ -1027,12 +1063,26 @@ func flattenAwsCodeBuildProjectEnvironment(environment *codebuild.ProjectEnviron envConfig["privileged_mode"] = *environment.PrivilegedMode envConfig["image_pull_credentials_type"] = *environment.ImagePullCredentialsType + envConfig["registry_credential"] = flattenAwsCodebuildRegistryCredential(environment.RegistryCredential) + if environment.EnvironmentVariables != nil { envConfig["environment_variable"] = environmentVariablesToMap(environment.EnvironmentVariables) } return []interface{}{envConfig} +} + +func flattenAwsCodebuildRegistryCredential(registryCredential *codebuild.RegistryCredential) []interface{} { + if registryCredential == nil { + return []interface{}{} + } + values := map[string]interface{}{ + "credential": aws.StringValue(registryCredential.Credential), + "credential_provider": aws.StringValue(registryCredential.CredentialProvider), + } + + return []interface{}{values} } func flattenAwsCodeBuildProjectSecondarySources(sourceList []*codebuild.ProjectSource) []interface{} { diff --git a/aws/resource_aws_codebuild_project_test.go b/aws/resource_aws_codebuild_project_test.go index c8b8c6ffe17..93f477050e6 100644 --- a/aws/resource_aws_codebuild_project_test.go +++ b/aws/resource_aws_codebuild_project_test.go @@ -896,6 +896,31 @@ func TestAWSCodeBuildProject_nameValidation(t *testing.T) { } } +func TestAccAWSCodeBuildProject_Environment_RegistryCredential(t *testing.T) { + var project codebuild.Project + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codebuild_project.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCodeBuild(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCodeBuildProjectConfig_Environment_RegistryCredential(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckAWSCodeBuildProjectExists(n string, project *codebuild.Project) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -1399,6 +1424,46 @@ resource "aws_codebuild_project" "test" { `, oName, rName) } +func testAccAWSCodeBuildProjectConfig_Environment_RegistryCredential(rName string) string { + return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` + resource "aws_codebuild_project" "test" { + name = %[1]q + service_role = "${aws_iam_role.test.arn}" + + artifacts { + type = "NO_ARTIFACTS" + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "2" + type = "LINUX_CONTAINER" + image_pull_credentials_type = "SERVICE_ROLE" + + registry_credential { + credential = "${aws_secretsmanager_secret_version.test.arn}" + credential_provider = "SECRETS_MANAGER" + } + } + + source { + type = "GITHUB" + location = "https://github.com/hashicorp/packer.git" + } + } + + resource "aws_secretsmanager_secret" "test" { + name = "test" + recovery_window_in_days = 0 + } + + resource "aws_secretsmanager_secret_version" "test" { + secret_id = "${aws_secretsmanager_secret.test.id}" + secret_string = "${jsonencode(map("username", "user", "password", "pass"))}" + } +`, rName) +} + func testAccAWSCodeBuildProjectConfig_Source_Auth(rName, authResource, authType string) string { return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` resource "aws_codebuild_project" "test" { diff --git a/website/docs/r/codebuild_project.html.markdown b/website/docs/r/codebuild_project.html.markdown index 6c67463c51b..783705e6248 100644 --- a/website/docs/r/codebuild_project.html.markdown +++ b/website/docs/r/codebuild_project.html.markdown @@ -224,6 +224,7 @@ The following arguments are supported: * `environment_variable` - (Optional) A set of environment variables to make available to builds for this build project. * `privileged_mode` - (Optional) If set to true, enables running the Docker daemon inside a Docker container. Defaults to `false`. * `certificate` - (Optional) The ARN of the S3 bucket, path prefix and object key that contains the PEM-encoded certificate. +* `registry_credential` - (Optional) Information about credentials for access to a private Docker registry. Registry Credential config blocks are documented below. `environment_variable` supports the following: @@ -252,6 +253,10 @@ The following arguments are supported: * `subnets` - (Required) The subnet IDs within which to run builds. * `vpc_id` - (Required) The ID of the VPC within which to run builds. +`registry_credential` supports the following: + +* `credential` - (Required) The Amazon Resource Name (ARN) or name of credentials created using AWS Secrets Manager. +* `credential_provider` - (Required) The service that created the credentials to access a private Docker registry. The valid value, SECRETS_MANAGER, is for AWS Secrets Manager. `secondary_artifacts` supports the following: