Skip to content

Commit

Permalink
Pub/Sub Topic CMEK/KMS support
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
drebes authored and modular-magician committed Jun 25, 2019
1 parent 7a53a61 commit 9077963
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 0 deletions.
22 changes: 22 additions & 0 deletions google/resource_pubsub_topic.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ func resourcePubsubTopic() *schema.Resource {
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
},
"kms_key_name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"labels": {
Type: schema.TypeMap,
Optional: true,
Expand All @@ -73,6 +78,12 @@ func resourcePubsubTopicCreate(d *schema.ResourceData, meta interface{}) error {
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
obj["name"] = nameProp
}
kmsKeyNameProp, err := expandPubsubTopicKmsKeyName(d.Get("kms_key_name"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("kms_key_name"); !isEmptyValue(reflect.ValueOf(kmsKeyNameProp)) && (ok || !reflect.DeepEqual(v, kmsKeyNameProp)) {
obj["kmsKeyName"] = kmsKeyNameProp
}
labelsProp, err := expandPubsubTopicLabels(d.Get("labels"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -132,6 +143,9 @@ func resourcePubsubTopicRead(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("name", flattenPubsubTopicName(res["name"], d)); err != nil {
return fmt.Errorf("Error reading Topic: %s", err)
}
if err := d.Set("kms_key_name", flattenPubsubTopicKmsKeyName(res["kmsKeyName"], d)); err != nil {
return fmt.Errorf("Error reading Topic: %s", err)
}
if err := d.Set("labels", flattenPubsubTopicLabels(res["labels"], d)); err != nil {
return fmt.Errorf("Error reading Topic: %s", err)
}
Expand Down Expand Up @@ -223,6 +237,10 @@ func flattenPubsubTopicName(v interface{}, d *schema.ResourceData) interface{} {
return NameFromSelfLinkStateFunc(v)
}

func flattenPubsubTopicKmsKeyName(v interface{}, d *schema.ResourceData) interface{} {
return v
}

func flattenPubsubTopicLabels(v interface{}, d *schema.ResourceData) interface{} {
return v
}
Expand All @@ -231,6 +249,10 @@ func expandPubsubTopicName(v interface{}, d TerraformResourceData, config *Confi
return GetResourceNameFromSelfLink(v.(string)), nil
}

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

func expandPubsubTopicLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) {
if v == nil {
return map[string]string{}, nil
Expand Down
126 changes: 126 additions & 0 deletions google/resource_pubsub_topic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccPubsubTopic_update(t *testing.T) {
Expand Down Expand Up @@ -40,6 +41,37 @@ func TestAccPubsubTopic_update(t *testing.T) {
})
}

func TestAccPubsubTopic_cmek(t *testing.T) {
t.Parallel()

projectId := "terraform-" + acctest.RandString(10)
projectOrg := getTestOrgFromEnv(t)
projectBillingAccount := getTestBillingAccountFromEnv(t)
keyRingName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
cryptoKeyName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
topicName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccPubsubTopic_cmek(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, topicName),
},
{
ResourceName: "google_pubsub_topic.topic",
ImportState: true,
ImportStateVerify: true,
},
// Use a separate TestStep rather than a CheckDestroy because we need the project to still exist.
{
Config: testAccPubsubTopic_removed(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName),
Check: testAccCheckPubsubTopicWasRemovedFromState("google_pubsub_topic.topic"),
},
},
})
}

func testAccPubsubTopic_update(topic, key, value string) string {
return fmt.Sprintf(`
resource "google_pubsub_topic" "foo" {
Expand All @@ -50,3 +82,97 @@ resource "google_pubsub_topic" "foo" {
}
`, topic, key, value)
}

// This test runs in its own project, otherwise the test project would start to get filled
// with undeletable resources
func testAccPubsubTopic_cmek(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, topicName string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
name = "%s"
project_id = "%s"
org_id = "%s"
billing_account = "%s"
}
resource "google_project_services" "acceptance" {
project = "${google_project.acceptance.project_id}"
services = [
"cloudkms.googleapis.com",
"pubsub.googleapis.com",
]
}
resource "google_kms_key_ring" "key_ring" {
project = "${google_project_services.acceptance.project}"
name = "%s"
location = "global"
}
resource "google_kms_crypto_key" "crypto_key" {
name = "%s"
key_ring = "${google_kms_key_ring.key_ring.self_link}"
}
resource "google_project_iam_member" "svc-acct" {
project = "${google_project_services.acceptance.project}"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:service-${google_project.acceptance.number}@gcp-sa-pubsub.iam.gserviceaccount.com"
}
resource "google_pubsub_topic" "topic" {
name = "%s"
project = "${google_project_iam_member.svc-acct.project}"
kms_key_name = "${google_kms_crypto_key.crypto_key.self_link}"
}
`, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, topicName)
}

func testAccPubsubTopic_removed(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
name = "%s"
project_id = "%s"
org_id = "%s"
billing_account = "%s"
}
resource "google_project_services" "acceptance" {
project = "${google_project.acceptance.project_id}"
services = [
"cloudkms.googleapis.com",
"pubsub.googleapis.com",
]
}
resource "google_kms_key_ring" "key_ring" {
project = "${google_project_services.acceptance.project}"
name = "%s"
location = "global"
}
resource "google_kms_crypto_key" "crypto_key" {
name = "%s"
key_ring = "${google_kms_key_ring.key_ring.self_link}"
}
resource "google_project_iam_member" "svc-acct" {
project = "${google_project_services.acceptance.project}"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:service-${google_project.acceptance.number}@gcp-sa-pubsub.iam.gserviceaccount.com"
}
`, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName)
}

func testAccCheckPubsubTopicWasRemovedFromState(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
_, ok := s.RootModule().Resources[resourceName]

if ok {
return fmt.Errorf("Resource was not removed from state: %s", resourceName)
}

return nil
}
}
25 changes: 25 additions & 0 deletions website/docs/r/pubsub_topic.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,25 @@ resource "google_pubsub_topic" "example" {
}
}
```
## Example Usage - Pubsub Topic Cmek


```hcl
resource "google_pubsub_topic" "example" {
name = "example-topic"
kms_key_name = "${google_kms_crypto_key.crypto_key.self_link}"
}
resource "google_kms_crypto_key" "crypto_key" {
name = "example-key"
key_ring = "${google_kms_key_ring.key_ring.self_link}"
}
resource "google_kms_key_ring" "key_ring" {
name = "example-keyring"
location = "global"
}
```

## Argument Reference

Expand All @@ -61,6 +80,12 @@ The following arguments are supported:
- - -


* `kms_key_name` -
(Optional)
The resource name of the Cloud KMS CryptoKey to be used to protect access
to messsages published on this topic.
The expected format is `projects/*/locations/*/keyRings/*/cryptoKeys/*`

* `labels` -
(Optional)
A set of key/value label pairs to assign to this Topic.
Expand Down

0 comments on commit 9077963

Please sign in to comment.