Skip to content

Commit 70d2718

Browse files
feat!: Add import flags (#133)
1 parent f553b67 commit 70d2718

File tree

11 files changed

+226
-17
lines changed

11 files changed

+226
-17
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Functional examples are included in the
4747
| crypto\_key\_backend | (Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL\_VPC' keys. | `string` | `null` | no |
4848
| decrypters | List of comma-separated owners for each key declared in set\_decrypters\_for. | `list(string)` | `[]` | no |
4949
| encrypters | List of comma-separated owners for each key declared in set\_encrypters\_for. | `list(string)` | `[]` | no |
50+
| import\_only | Whether these keys may contain imported versions only. | `bool` | `false` | no |
5051
| key\_algorithm | The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs. | `string` | `"GOOGLE_SYMMETRIC_ENCRYPTION"` | no |
5152
| key\_destroy\_scheduled\_duration | Set the period of time that versions of keys spend in the DESTROY\_SCHEDULED state before transitioning to DESTROYED. | `string` | `null` | no |
5253
| key\_protection\_level | The protection level to use when creating a version based on this template. Default value: "SOFTWARE" Possible values: ["SOFTWARE", "HSM", "EXTERNAL", "EXTERNAL\_VPC"] | `string` | `"SOFTWARE"` | no |
@@ -58,10 +59,11 @@ Functional examples are included in the
5859
| owners | List of comma-separated owners for each key declared in set\_owners\_for. | `list(string)` | `[]` | no |
5960
| prevent\_destroy | Set the prevent\_destroy lifecycle attribute on keys. | `bool` | `true` | no |
6061
| project\_id | Project id where the keyring will be created. | `string` | n/a | yes |
61-
| purpose | The immutable purpose of the CryptoKey. Possible values are ENCRYPT\_DECRYPT, ASYMMETRIC\_SIGN, and ASYMMETRIC\_DECRYPT. | `string` | `"ENCRYPT_DECRYPT"` | no |
62+
| purpose | The immutable purpose of the CryptoKey. Default value is ENCRYPT\_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs. | `string` | `"ENCRYPT_DECRYPT"` | no |
6263
| set\_decrypters\_for | Name of keys for which decrypters will be set. | `list(string)` | `[]` | no |
6364
| set\_encrypters\_for | Name of keys for which encrypters will be set. | `list(string)` | `[]` | no |
6465
| set\_owners\_for | Name of keys for which owners will be set. | `list(string)` | `[]` | no |
66+
| skip\_initial\_version\_creation | If set to true, the request will create CryptoKeys without any CryptoKeyVersions. | `bool` | `false` | no |
6567

6668
## Outputs
6769

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Import Only Example
2+
3+
This example illustrates how to use the `kms` module when you want to create a CryptoKey with no CryptoKeyVersion in order to import the key material.
4+
5+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
6+
## Inputs
7+
8+
| Name | Description | Type | Default | Required |
9+
|------|-------------|------|---------|:--------:|
10+
| project\_id | The ID of the project in which to provision resources. | `string` | n/a | yes |
11+
12+
## Outputs
13+
14+
| Name | Description |
15+
|------|-------------|
16+
| keyring | The name of the keyring. |
17+
| keys | List of created kkey names. |
18+
| location | The location of the keyring. |
19+
| project\_id | The ID of the project in which resources are provisioned. |
20+
21+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
22+
23+
To provision this example, run the following from within this directory:
24+
- `terraform init` to get the plugins
25+
- `terraform plan` to see the infrastructure plan
26+
- `terraform apply` to apply the infrastructure build
27+
- `terraform destroy` to destroy the built infrastructure
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
resource "random_pet" "main" {
18+
length = 1
19+
prefix = "simple-example"
20+
separator = "-"
21+
}
22+
23+
module "kms" {
24+
source = "../.."
25+
26+
project_id = var.project_id
27+
keyring = random_pet.main.id
28+
location = "global"
29+
keys = ["one", "two"]
30+
# keys can be destroyed by Terraform
31+
prevent_destroy = false
32+
import_only = true
33+
skip_initial_version_creation = true
34+
key_rotation_period = ""
35+
purpose = "RAW_ENCRYPT_DECRYPT"
36+
key_algorithm = "AES_256_GCM"
37+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
output "keyring" {
18+
description = "The name of the keyring."
19+
value = module.kms.keyring_resource.name
20+
}
21+
22+
output "location" {
23+
description = "The location of the keyring."
24+
value = module.kms.keyring_resource.location
25+
}
26+
27+
output "keys" {
28+
description = "List of created kkey names."
29+
value = keys(module.kms.keys)
30+
}
31+
32+
output "project_id" {
33+
description = "The ID of the project in which resources are provisioned."
34+
value = var.project_id
35+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
variable "project_id" {
18+
description = "The ID of the project in which to provision resources."
19+
type = string
20+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
terraform {
18+
required_providers {
19+
google = {
20+
source = "hashicorp/google"
21+
}
22+
}
23+
required_version = ">= 0.13"
24+
}

main.tf

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ resource "google_kms_key_ring" "key_ring" {
2525
}
2626

2727
resource "google_kms_crypto_key" "key" {
28-
count = var.prevent_destroy ? length(var.keys) : 0
29-
name = var.keys[count.index]
30-
key_ring = google_kms_key_ring.key_ring.id
31-
rotation_period = var.key_rotation_period
32-
purpose = var.purpose
33-
crypto_key_backend = var.crypto_key_backend
28+
count = var.prevent_destroy ? length(var.keys) : 0
29+
name = var.keys[count.index]
30+
key_ring = google_kms_key_ring.key_ring.id
31+
rotation_period = var.key_rotation_period
32+
purpose = var.purpose
33+
import_only = var.import_only
34+
skip_initial_version_creation = var.skip_initial_version_creation
35+
crypto_key_backend = var.crypto_key_backend
3436

3537
lifecycle {
3638
prevent_destroy = true
@@ -47,12 +49,14 @@ resource "google_kms_crypto_key" "key" {
4749
}
4850

4951
resource "google_kms_crypto_key" "key_ephemeral" {
50-
count = var.prevent_destroy ? 0 : length(var.keys)
51-
name = var.keys[count.index]
52-
key_ring = google_kms_key_ring.key_ring.id
53-
rotation_period = var.key_rotation_period
54-
purpose = var.purpose
55-
crypto_key_backend = var.crypto_key_backend
52+
count = var.prevent_destroy ? 0 : length(var.keys)
53+
name = var.keys[count.index]
54+
key_ring = google_kms_key_ring.key_ring.id
55+
rotation_period = var.key_rotation_period
56+
purpose = var.purpose
57+
import_only = var.import_only
58+
skip_initial_version_creation = var.skip_initial_version_creation
59+
crypto_key_backend = var.crypto_key_backend
5660

5761
lifecycle {
5862
prevent_destroy = false
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package simple_example
16+
17+
import (
18+
"fmt"
19+
"testing"
20+
21+
"github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud"
22+
"github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft"
23+
"github.com/stretchr/testify/assert"
24+
)
25+
26+
func TestImportOnlyExample(t *testing.T) {
27+
bpt := tft.NewTFBlueprintTest(t)
28+
bpt.DefineVerify(func(assert *assert.Assertions) {
29+
bpt.DefaultVerify(assert)
30+
31+
projectId := bpt.GetStringOutput("project_id")
32+
keyring := bpt.GetStringOutput("keyring")
33+
location := bpt.GetStringOutput("location")
34+
keys := [2]string{"one", "two"}
35+
36+
op := gcloud.Runf(t, "--project=%s kms keyrings list --location %s --filter name:%s", projectId, location, keyring).Array()[0].Get("name")
37+
assert.Contains(op.String(), fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", projectId, location, keyring), "Contains KeyRing")
38+
39+
op1 := gcloud.Runf(t, "kms keys list --project=%s --keyring %s --location %s", projectId, keyring, location).Array()
40+
for index, element := range op1 {
41+
assert.Equal(element.Get("name").String(), fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", projectId, location, keyring, keys[index]), "Contains Keys")
42+
assert.True(element.Get("importOnly").Bool(), "ImportOnly flag")
43+
}
44+
})
45+
46+
bpt.Test()
47+
}

test/integration/simple_example/simple_example_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ func TestSimpleExample(t *testing.T) {
3333
location := bpt.GetStringOutput("location")
3434
keys := [2]string{"one", "two"}
3535

36-
op := gcloud.Runf(t, "--project=%s kms keyrings list --location %s", projectId, location).Array()[0].Get("name")
36+
op := gcloud.Runf(t, "--project=%s kms keyrings list --location %s --filter name:%s", projectId, location, keyring).Array()[0].Get("name")
3737
assert.Contains(op.String(), fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", projectId, location, keyring), "Contains KeyRing")
3838

3939
op1 := gcloud.Runf(t, "kms keys list --project=%s --keyring %s --location %s", projectId, keyring, location).Array()
4040
for index, element := range op1 {
41-
assert.Contains(element.Get("name").String(), fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", projectId, location, keyring, keys[index]), "Contains Keys")
41+
assert.Equal(element.Get("primary").Map()["name"].Str, fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/1", projectId, location, keyring, keys[index]), "Contains Keys")
42+
assert.False(element.Get("importOnly").Bool(), "ImportOnly flag")
4243
}
4344
})
4445

variables.tf

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ variable "key_destroy_scheduled_duration" {
5050

5151
variable "purpose" {
5252
type = string
53-
description = "The immutable purpose of the CryptoKey. Possible values are ENCRYPT_DECRYPT, ASYMMETRIC_SIGN, and ASYMMETRIC_DECRYPT."
53+
description = "The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."
5454
default = "ENCRYPT_DECRYPT"
5555
}
5656

@@ -114,6 +114,18 @@ variable "labels" {
114114
default = {}
115115
}
116116

117+
variable "import_only" {
118+
type = bool
119+
description = "Whether these keys may contain imported versions only."
120+
default = false
121+
}
122+
123+
variable "skip_initial_version_creation" {
124+
type = bool
125+
description = "If set to true, the request will create CryptoKeys without any CryptoKeyVersions."
126+
default = false
127+
}
128+
117129
variable "crypto_key_backend" {
118130
type = string
119131
description = "(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."

0 commit comments

Comments
 (0)