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 available_secrets to google_cloudbuild_trigger #10714

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/4977.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
cloudbuild: added support for available_secrets to google_cloudbuild_trigger
```
136 changes: 136 additions & 0 deletions google/resource_cloudbuild_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,37 @@ nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:2
},
},
},
"available_secrets": {
Type: schema.TypeList,
Optional: true,
Description: `Secrets and secret environment variables.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"secret_manager": {
Type: schema.TypeList,
Required: true,
Description: `Pairs a secret environment variable with a SecretVersion in Secret Manager.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"env": {
Type: schema.TypeString,
Required: true,
Description: `Environment variable name to associate with the secret. Secret environment
variables must be unique across all of a build's secrets, and must be used
by at least one build step.`,
},
"version_name": {
Type: schema.TypeString,
Required: true,
Description: `Resource name of the SecretVersion. In format: projects/*/secrets/*/versions/*`,
},
},
},
},
},
},
},
"images": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -1615,6 +1646,8 @@ func flattenCloudBuildTriggerBuild(v interface{}, d *schema.ResourceData, config
flattenCloudBuildTriggerBuildTimeout(original["timeout"], d, config)
transformed["secret"] =
flattenCloudBuildTriggerBuildSecret(original["secrets"], d, config)
transformed["available_secrets"] =
flattenCloudBuildTriggerBuildAvailableSecrets(original["availableSecrets"], d, config)
transformed["step"] =
flattenCloudBuildTriggerBuildStep(original["steps"], d, config)
transformed["artifacts"] =
Expand Down Expand Up @@ -1777,6 +1810,46 @@ func flattenCloudBuildTriggerBuildSecretSecretEnv(v interface{}, d *schema.Resou
return v
}

func flattenCloudBuildTriggerBuildAvailableSecrets(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["secret_manager"] =
flattenCloudBuildTriggerBuildAvailableSecretsSecretManager(original["secretManager"], d, config)
return []interface{}{transformed}
}
func flattenCloudBuildTriggerBuildAvailableSecretsSecretManager(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return v
}
l := v.([]interface{})
transformed := make([]interface{}, 0, len(l))
for _, raw := range l {
original := raw.(map[string]interface{})
if len(original) < 1 {
// Do not include empty json objects coming back from the api
continue
}
transformed = append(transformed, map[string]interface{}{
"version_name": flattenCloudBuildTriggerBuildAvailableSecretsSecretManagerVersionName(original["versionName"], d, config),
"env": flattenCloudBuildTriggerBuildAvailableSecretsSecretManagerEnv(original["env"], d, config),
})
}
return transformed
}
func flattenCloudBuildTriggerBuildAvailableSecretsSecretManagerVersionName(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenCloudBuildTriggerBuildAvailableSecretsSecretManagerEnv(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenCloudBuildTriggerBuildStep(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return v
Expand Down Expand Up @@ -2483,6 +2556,13 @@ func expandCloudBuildTriggerBuild(v interface{}, d TerraformResourceData, config
transformed["secrets"] = transformedSecret
}

transformedAvailableSecrets, err := expandCloudBuildTriggerBuildAvailableSecrets(original["available_secrets"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAvailableSecrets); val.IsValid() && !isEmptyValue(val) {
transformed["availableSecrets"] = transformedAvailableSecrets
}

transformedStep, err := expandCloudBuildTriggerBuildStep(original["step"], d, config)
if err != nil {
return nil, err
Expand Down Expand Up @@ -2760,6 +2840,62 @@ func expandCloudBuildTriggerBuildSecretSecretEnv(v interface{}, d TerraformResou
return m, nil
}

func expandCloudBuildTriggerBuildAvailableSecrets(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedSecretManager, err := expandCloudBuildTriggerBuildAvailableSecretsSecretManager(original["secret_manager"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedSecretManager); val.IsValid() && !isEmptyValue(val) {
transformed["secretManager"] = transformedSecretManager
}

return transformed, nil
}

func expandCloudBuildTriggerBuildAvailableSecretsSecretManager(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
for _, raw := range l {
if raw == nil {
continue
}
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedVersionName, err := expandCloudBuildTriggerBuildAvailableSecretsSecretManagerVersionName(original["version_name"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedVersionName); val.IsValid() && !isEmptyValue(val) {
transformed["versionName"] = transformedVersionName
}

transformedEnv, err := expandCloudBuildTriggerBuildAvailableSecretsSecretManagerEnv(original["env"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedEnv); val.IsValid() && !isEmptyValue(val) {
transformed["env"] = transformedEnv
}

req = append(req, transformed)
}
return req, nil
}

func expandCloudBuildTriggerBuildAvailableSecretsSecretManagerVersionName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandCloudBuildTriggerBuildAvailableSecretsSecretManagerEnv(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandCloudBuildTriggerBuildStep(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
Expand Down
11 changes: 9 additions & 2 deletions google/resource_cloudbuild_trigger_generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,13 @@ resource "google_cloudbuild_trigger" "build-trigger" {
branch_name = "master"
repo_name = "my-repo"
}

build {
step {
name = "gcr.io/cloud-builders/gsutil"
args = ["cp", "gs://mybucket/remotefile.zip", "localfile.zip"]
timeout = "120s"
secret_env = ["MY_SECRET"]
}

source {
Expand All @@ -123,6 +124,12 @@ resource "google_cloudbuild_trigger" "build-trigger" {
PASSWORD = "ZW5jcnlwdGVkLXBhc3N3b3JkCg=="
}
}
available_secrets {
secret_manager {
env = "MY_SECRET"
version_name = "projects/myProject/secrets/mySecret/versions/latest"
}
}
artifacts {
images = ["gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA"]
objects {
Expand All @@ -147,7 +154,7 @@ resource "google_cloudbuild_trigger" "build-trigger" {
path = "v1"
}
}
}
}
}
`, context)
}
Expand Down
79 changes: 79 additions & 0 deletions google/resource_cloudbuild_trigger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,35 @@ func TestAccCloudBuildTrigger_basic(t *testing.T) {
})
}

func TestAccCloudBuildTrigger_available_secrets_config(t *testing.T) {
t.Parallel()
name := fmt.Sprintf("tf-test-%d", randInt(t))

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudBuildTriggerDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccCloudBuildTrigger_available_secrets_config(name),
},
{
ResourceName: "google_cloudbuild_trigger.build_trigger",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccCloudBuildTrigger_available_secrets_config_update(name),
},
{
ResourceName: "google_cloudbuild_trigger.build_trigger",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccCloudBuildTrigger_pubsub_config(t *testing.T) {
t.Parallel()
name := fmt.Sprintf("tf-test-%d", randInt(t))
Expand Down Expand Up @@ -339,6 +368,56 @@ resource "google_cloudbuild_trigger" "build_trigger" {
`, name)
}

func testAccCloudBuildTrigger_available_secrets_config(name string) string {
return fmt.Sprintf(`
resource "google_cloudbuild_trigger" "build_trigger" {
name = "%s"
description = "acceptance test build trigger"
trigger_template {
branch_name = "master"
repo_name = "some-repo"
}
build {
tags = ["team-a", "service-b"]
timeout = "1800s"
step {
name = "gcr.io/cloud-builders/gsutil"
args = ["cp", "gs://mybucket/remotefile.zip", "localfile.zip"]
timeout = "300s"
}
available_secrets {
secret_manager {
env = "MY_SECRET"
version_name = "projects/myProject/secrets/mySecret/versions/latest"
}
}
}
}
`, name)
}

func testAccCloudBuildTrigger_available_secrets_config_update(name string) string {
return fmt.Sprintf(`
resource "google_cloudbuild_trigger" "build_trigger" {
name = "%s"
description = "acceptance test build trigger updated"
trigger_template {
branch_name = "master"
repo_name = "some-repo"
}
build {
tags = ["team-a", "service-b"]
timeout = "1800s"
step {
name = "gcr.io/cloud-builders/gsutil"
args = ["cp", "gs://mybucket/remotefile.zip", "localfile.zip"]
timeout = "300s"
}
}
}
`, name)
}

func testAccCloudBuildTrigger_pubsub_config(name string) string {
return fmt.Sprintf(`
resource "google_pubsub_topic" "build-trigger" {
Expand Down
36 changes: 34 additions & 2 deletions website/docs/r/cloudbuild_trigger.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ resource "google_cloudbuild_trigger" "build-trigger" {
branch_name = "master"
repo_name = "my-repo"
}

build {
step {
name = "gcr.io/cloud-builders/gsutil"
args = ["cp", "gs://mybucket/remotefile.zip", "localfile.zip"]
timeout = "120s"
secret_env = ["MY_SECRET"]
}

source {
Expand All @@ -97,6 +98,12 @@ resource "google_cloudbuild_trigger" "build-trigger" {
PASSWORD = "ZW5jcnlwdGVkLXBhc3N3b3JkCg=="
}
}
available_secrets {
secret_manager {
env = "MY_SECRET"
version_name = "projects/myProject/secrets/mySecret/versions/latest"
}
}
artifacts {
images = ["gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA"]
objects {
Expand All @@ -121,7 +128,7 @@ resource "google_cloudbuild_trigger" "build-trigger" {
path = "v1"
}
}
}
}
}
```
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
Expand Down Expand Up @@ -430,6 +437,11 @@ The following arguments are supported:
Secrets to decrypt using Cloud Key Management Service.
Structure is [documented below](#nested_secret).

* `available_secrets` -
(Optional)
Secrets and secret environment variables.
Structure is [documented below](#nested_available_secrets).

* `step` -
(Required)
The operations to be performed on the workspace.
Expand Down Expand Up @@ -529,6 +541,26 @@ The following arguments are supported:
and must be used by at least one build step. Values can be at most 64 KB in size.
There can be at most 100 secret values across all of a build's secrets.

<a name="nested_available_secrets"></a>The `available_secrets` block supports:

* `secret_manager` -
(Required)
Pairs a secret environment variable with a SecretVersion in Secret Manager.
Structure is [documented below](#nested_secret_manager).


<a name="nested_secret_manager"></a>The `secret_manager` block supports:

* `version_name` -
(Required)
Resource name of the SecretVersion. In format: projects/*/secrets/*/versions/*

* `env` -
(Required)
Environment variable name to associate with the secret. Secret environment
variables must be unique across all of a build's secrets, and must be used
by at least one build step.

<a name="nested_step"></a>The `step` block supports:

* `name` -
Expand Down