Skip to content

Commit

Permalink
Create support for KMS Ekmconnection resource (GoogleCloudPlatform#10094
Browse files Browse the repository at this point in the history
)
  • Loading branch information
rishamchokshi authored and balanaguharsha committed May 2, 2024
1 parent 919f523 commit d19a6d9
Show file tree
Hide file tree
Showing 3 changed files with 317 additions and 0 deletions.
166 changes: 166 additions & 0 deletions mmv1/products/kms/EkmConnection.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Copyright 2023 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Api::Resource
name: 'EkmConnection'
base_url: 'projects/{{project}}/locations/{{location}}/ekmConnections'
create_url: 'projects/{{project}}/locations/{{location}}/ekmConnections?ekmConnectionId={{name}}'
self_link: 'projects/{{project}}/locations/{{location}}/ekmConnections/{{name}}'
update_verb: :PATCH
update_mask: true
description: |
`Ekm Connections` are used to control the connection settings for an `EXTERNAL_VPC` CryptoKey.
It is used to connect customer's external key manager to Google Cloud EKM.
~> **Note:** Ekm Connections cannot be deleted from Google Cloud Platform.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Creating a Ekm Connection': 'https://cloud.google.com/kms/docs/create-ekm-connection'
api: 'https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.ekmConnections'
id_format: 'projects/{{project}}/locations/{{location}}/ekmConnections/{{name}}'
import_format: ['projects/{{project}}/locations/{{location}}/ekmConnections/{{name}}']
skip_delete: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: 'kms_ekm_connection_basic'
primary_resource_id:
'example-ekmconnection'
skip_test: true
vars:
ekmconnection_name: 'ekmconnection_example'
parameters:
- !ruby/object:Api::Type::String
name: 'location'
description: |
The location for the EkmConnection.
A full list of valid locations can be found by running `gcloud kms locations list`.
required: true
ignore_read: true
url_param_only: true
immutable: true
properties:
- !ruby/object:Api::Type::String
name: 'name'
description: |
The resource name for the EkmConnection.
required: true
immutable: true
diff_suppress_func: 'tpgresource.CompareResourceNames'
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
- !ruby/object:Api::Type::Array
name: 'serviceResolvers'
description: |
A list of ServiceResolvers where the EKM can be reached. There should be one ServiceResolver per EKM replica. Currently, only a single ServiceResolver is supported
required: true
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: 'serviceDirectoryService'
description: |
Required. The resource name of the Service Directory service pointing to an EKM replica, in the format projects/*/locations/*/namespaces/*/services/*
required: true
- !ruby/object:Api::Type::String
name: 'hostname'
description: |
Required. The hostname of the EKM replica used at TLS and HTTP layers.
required: true
- !ruby/object:Api::Type::Array
name: 'serverCertificates'
description: |
Required. A list of leaf server certificates used to authenticate HTTPS connections to the EKM replica. Currently, a maximum of 10 Certificate is supported.
required: true
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: 'rawDer'
description: |
Required. The raw certificate bytes in DER format. A base64-encoded string.
required: true
- !ruby/object:Api::Type::Boolean
name: 'parsed'
description: |
Output only. True if the certificate was parsed successfully.
output: true
- !ruby/object:Api::Type::String
name: 'issuer'
description: |
Output only. The issuer distinguished name in RFC 2253 format. Only present if parsed is true.
output: true
- !ruby/object:Api::Type::String
name: 'subject'
description: |
Output only. The subject distinguished name in RFC 2253 format. Only present if parsed is true.
output: true
- !ruby/object:Api::Type::String
name: 'notBeforeTime'
description: |
Output only. The certificate is not valid before this time. Only present if parsed is true.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
output: true
- !ruby/object:Api::Type::String
name: 'notAfterTime'
description: |
Output only. The certificate is not valid after this time. Only present if parsed is true.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
output: true
- !ruby/object:Api::Type::String
name: 'sha256Fingerprint'
description: |
Output only. The SHA-256 certificate fingerprint as a hex string. Only present if parsed is true.
output: true
- !ruby/object:Api::Type::String
name: 'serialNumber'
description: |
Output only. The certificate serial number as a hex string. Only present if parsed is true.
output: true
- !ruby/object:Api::Type::Array
name: 'subjectAlternativeDnsNames'
description: |
Output only. The subject Alternative DNS names. Only present if parsed is true.
output: true
default_from_api: true
item_type: Api::Type::String
- !ruby/object:Api::Type::String
name: 'endpointFilter'
description: |
Optional. The filter applied to the endpoints of the resolved service. If no filter is specified, all endpoints will be considered. An endpoint will be chosen arbitrarily from the filtered list for each request. For endpoint filter syntax and examples, see https://cloud.google.com/service-directory/docs/reference/rpc/google.cloud.servicedirectory.v1#resolveservicerequest.
required: false
default_from_api: true
- !ruby/object:Api::Type::Enum
name: 'keyManagementMode'
description: |
Optional. Describes who can perform control plane operations on the EKM. If unset, this defaults to MANUAL
required: false
default_value: :MANUAL
values:
- :MANUAL
- :CLOUD_KMS
- !ruby/object:Api::Type::String
name: 'etag'
required: false
default_from_api: true
description: |
Optional. Etag of the currently stored EkmConnection.
- !ruby/object:Api::Type::String
name: 'cryptoSpacePath'
description: |
Optional. Identifies the EKM Crypto Space that this EkmConnection maps to. Note: This field is required if KeyManagementMode is CLOUD_KMS.
required: false
default_from_api: true
- !ruby/object:Api::Type::String
name: 'createTime'
description: |
Output only. The time at which the EkmConnection was created.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
output: true
12 changes: 12 additions & 0 deletions mmv1/templates/terraform/examples/kms_ekm_connection_basic.tf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resource "google_kms_ekm_connection" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['ekmconnection_name'] %>"
location = "us-central1"
key_management_mode = "MANUAL"
service_resolvers {
service_directory_service = "projects/project_id/locations/us-central1/namespaces/namespace_name/services/service_name"
hostname = "example-ekm.goog"
server_certificates {
raw_der = "==HAwIBCCAr6gAwIBAgIUWR+EV4lqiV7Ql12VY=="
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package kms_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

"github.com/hashicorp/terraform-provider-google/google/acctest"
)

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

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccKMSEkmConnection_kmsEkmConnectionBasicExample_full(context),
},
{
ResourceName: "google_kms_ekm_connection.example-ekmconnection",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location", "name"},
},
{
Config: testAccKMSEkmConnection_kmsEkmConnectionBasicExample_update(context),
},
{
ResourceName: "google_kms_ekm_connection.example-ekmconnection",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location", "name"},
},
},
})
}

func testAccKMSEkmConnection_kmsEkmConnectionBasicExample_full(context map[string]interface{}) string {
return acctest.Nprintf(`
data "google_secret_manager_secret_version" "raw_der" {
secret = "playground-cert"
project = "315636579862"
}
data "google_secret_manager_secret_version" "hostname" {
secret = "external-uri"
project = "315636579862"
}
data "google_secret_manager_secret_version" "servicedirectoryservice" {
secret = "external-servicedirectoryservice"
project = "315636579862"
}
data "google_project" "vpc-project" {
project_id = "cloud-ekm-refekm-playground"
}
data "google_project" "project" {
}
resource "google_project_iam_member" "add_sdviewer" {
project = data.google_project.vpc-project.number
role = "roles/servicedirectory.viewer"
member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-ekms.iam.gserviceaccount.com"
}
resource "google_project_iam_member" "add_pscAuthorizedService" {
project = data.google_project.vpc-project.number
role = "roles/servicedirectory.pscAuthorizedService"
member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-ekms.iam.gserviceaccount.com"
}
resource "google_kms_ekm_connection" "example-ekmconnection" {
name = "tf_test_ekmconnection_example%{random_suffix}"
location = "us-central1"
key_management_mode = "MANUAL"
service_resolvers {
service_directory_service = data.google_secret_manager_secret_version.servicedirectoryservice.secret_data
hostname = data.google_secret_manager_secret_version.hostname.secret_data
server_certificates {
raw_der = data.google_secret_manager_secret_version.raw_der.secret_data
}
}
depends_on = [
google_project_iam_member.add_pscAuthorizedService,
google_project_iam_member.add_sdviewer
]
}
`, context)
}

func testAccKMSEkmConnection_kmsEkmConnectionBasicExample_update(context map[string]interface{}) string {
return acctest.Nprintf(`
data "google_project" "vpc-project" {
project_id = "cloud-ekm-refekm-playground"
}
data "google_project" "project" {
}
data "google_secret_manager_secret_version" "raw_der" {
secret = "playground-cert"
project = "315636579862"
}
data "google_secret_manager_secret_version" "hostname" {
secret = "external-uri"
project = "315636579862"
}
data "google_secret_manager_secret_version" "servicedirectoryservice" {
secret = "external-servicedirectoryservice"
project = "315636579862"
}
resource "google_project_iam_member" "add_sdviewer_updateekmconnection" {
project = data.google_project.vpc-project.number
role = "roles/servicedirectory.viewer"
member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-ekms.iam.gserviceaccount.com"
}
resource "google_project_iam_member" "add_pscAuthorizedService_updateekmconnection" {
project = data.google_project.vpc-project.number
role = "roles/servicedirectory.pscAuthorizedService"
member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-ekms.iam.gserviceaccount.com"
}
resource "google_kms_ekm_connection" "example-ekmconnection" {
name = "tf_test_ekmconnection_example%{random_suffix}"
location = "us-central1"
key_management_mode = "CLOUD_KMS"
crypto_space_path = "v0/longlived/crypto-space-placeholder"
service_resolvers {
service_directory_service = data.google_secret_manager_secret_version.servicedirectoryservice.secret_data
hostname = data.google_secret_manager_secret_version.hostname.secret_data
server_certificates {
raw_der = data.google_secret_manager_secret_version.raw_der.secret_data
}
}
depends_on = [
google_project_iam_member.add_pscAuthorizedService_updateekmconnection,
google_project_iam_member.add_sdviewer_updateekmconnection
]
}
`, context)
}

0 comments on commit d19a6d9

Please sign in to comment.