Skip to content
Closed
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
26 changes: 25 additions & 1 deletion mmv1/products/compute/Interconnect.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ async:
base_url: '{{op_id}}'
include_in_tgc_next: true
custom_code:
update_encoder: templates/terraform/update_encoder/compute_interconnect.go.tmpl
constants: templates/terraform/constants/interconnect.go.tmpl
post_create: templates/terraform/post_create/labels.tmpl
samples:
Expand Down Expand Up @@ -337,13 +338,13 @@ properties:
output: true
- name: macsec
type: NestedObject
custom_flatten: templates/terraform/custom_flatten/compute_interconnect_macsec.go.tmpl
description: |
Configuration that enables Media Access Control security (MACsec) on the Cloud
Interconnect connection between Google and your on-premises router.
properties:
- name: preSharedKeys
type: Array
required: true
description: |
A keychain placeholder describing a set of named key objects along with their
start times. A MACsec CKN/CAK is generated for each key in the key chain.
Expand Down Expand Up @@ -388,6 +389,29 @@ properties:
traffic if the MKA session cannot be established. By default, the Interconnect
connection is configured with a must-secure security policy that drops all traffic
if the MKA session cannot be established with your router.
- name: interconnectKeyGroup
type: String
min_version: beta
description: |
The InterconnectKeyGroup that provides customer-provided MACsec keys for this
Interconnect, in the format
`projects/{project}/locations/{region}/interconnectKeyGroups/{name}` (for example, the
`id` of a `google_network_connectivity_interconnect_key_group`). At least one of
`pre_shared_keys` or `interconnect_key_group` must be set.

The API enforces these rules:
* MACsec can't be enabled when the Interconnect is created. Create it with
`macsec_enabled = false` and no `macsec` block, then enable MACsec in a later apply.
* The key group can't be removed while MACsec is enabled. Set `macsec_enabled = false`
in the same apply that removes it.
* To switch to a different key group, remove the current one in one apply (with MACsec
disabled), then add the new one in a later apply.
* To migrate from pre-shared keys without downtime, add `interconnect_key_group` while
keeping one `pre_shared_keys` entry, then remove `pre_shared_keys` in a later apply.
diff_suppress_func: 'computeInterconnectKeyGroupDiffSuppress'
at_least_one_of:
- 'macsec.0.pre_shared_keys'
- 'macsec.0.interconnect_key_group'
- name: macsecEnabled
type: Boolean
description: |
Expand Down
160 changes: 160 additions & 0 deletions mmv1/products/networkconnectivity/InterconnectKeyGroup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Copyright 2026 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.

---
name: InterconnectKeyGroup
description: |
An InterconnectKeyGroup holds a set of customer-provided MACsec keys (CKN/CAK pairs) that one or
more Cloud Interconnect connections can use for MACsec ("bring your own key"). Link an
Interconnect to a key group with the `macsec.interconnect_key_group` field of
`google_compute_interconnect`.

Individual keys can't be changed in place. To rotate keys, add a new key (with a `start_time`
at least 6 hours in the future) and remove the old key once the new key is active. Keys can be
added and removed while the key group is attached to Interconnects; the changes are pushed to
every linked Interconnect without disabling MACsec.
min_version: beta
references:
guides:
MACsec for Cloud Interconnect: https://cloud.google.com/network-connectivity/docs/interconnect/concepts/macsec-overview
api: https://cloud.google.com/network-connectivity/docs/reference/networkconnectivity/rest/v1beta/projects.locations.interconnectKeyGroups
docs:
warning: |
`keys.cak_wo` is a write-only argument and requires Terraform 1.11 or later. The CAK is never
stored in Terraform state or plan files, and the API never returns it.
base_url: projects/{{project}}/locations/{{region}}/interconnectKeyGroups
self_link: projects/{{project}}/locations/{{region}}/interconnectKeyGroups/{{name}}
create_url: projects/{{project}}/locations/{{region}}/interconnectKeyGroups?interconnectKeyGroupId={{name}}
update_verb: PATCH
update_mask: true
timeouts:
insert_minutes: 20
update_minutes: 30
delete_minutes: 20
async:
type: OpAsync
operation:
base_url: '{{op_id}}'
actions: [create, update, delete]
result:
resource_inside_response: false
custom_code:
constants: templates/terraform/constants/network_connectivity_interconnect_key_group.go.tmpl
pre_update: templates/terraform/pre_update/network_connectivity_interconnect_key_group.go.tmpl
custom_diff:
- networkConnectivityInterconnectKeyGroupKeysCustomizeDiff
samples:
- name: network_connectivity_interconnect_key_group_basic
primary_resource_id: default
min_version: beta
steps:
- name: network_connectivity_interconnect_key_group_basic
resource_id_vars:
key_group_name: my-key-group
# The API never returns the CAK and cak_wo is write-only, so it can't be verified on import.
ignore_read_extra:
- keys.0.cak_wo
parameters:
- name: region
type: String
description: |
The region of the key group. Only Interconnects in this region can use it.
required: true
immutable: true
url_param_only: true
- name: name
type: String
description: |
The name of the key group.
required: true
immutable: true
url_param_only: true
properties:
- name: createTime
type: Time
description: |
The time the key group was created.
output: true
- name: updateTime
type: Time
description: |
The time the key group was last updated.
output: true
- name: labels
type: KeyValueLabels
description: |
Labels as key-value pairs.
- name: description
type: String
description: |
An optional description of the key group.
- name: keys
type: Array
description: |
The MACsec keys in this group. A key group can have at most 5 keys, and the start times of
any two keys must be at least 6 hours apart. When the key group is created, keys can have a
`start_time` in the past; keys added later must start at least 6 hours in the future.

The order of the keys doesn't matter. Keys can't be changed in place: to change a key, add a
key with a new name and remove the old one.
custom_expand: templates/terraform/custom_expand/network_connectivity_interconnect_key_group_keys.go.tmpl
custom_flatten: templates/terraform/custom_flatten/network_connectivity_interconnect_key_group_keys.go.tmpl
item_type:
type: NestedObject
properties:
- name: name
type: String
required: true
diff_suppress_func: 'interconnectKeyGroupKeysDiffSuppress'
description: |
A name for this key, unique within the key group: 1-255 lowercase letters and digits.
The API only accepts alphanumeric names; uppercase letters aren't allowed because the
provider uses the name as an update-mask path (`keys.<name>`), and mask paths are
case-converted.
validation:
regex: ^[a-z0-9]{1,255}$
- name: startTime
type: String
required: true
diff_suppress_func: 'interconnectKeyGroupKeysDiffSuppress'
description: |
The RFC3339 timestamp from which this key takes effect, for example
`2026-10-01T00:00:00Z`.
- name: ckn
type: String
required: true
diff_suppress_func: 'interconnectKeyGroupKeysDiffSuppress'
description: |
The MACsec connectivity association key name (CKN): a 64-character hexadecimal string.
validation:
regex: ^[0-9a-fA-F]{64}$
- name: cakWo
api_name: cak
type: String
write_only: true
description: |
The MACsec connectivity association key (CAK): a 64-character hexadecimal string.
Write-only (requires Terraform 1.11 or later): it is sent to the API but never stored in
state or plan files, and the API never returns it. Required for every key that is being
added. Changing only `cak_wo` of an existing key has no effect; to change a CAK, add a
new key and remove the old one.
validation:
regex: ^[0-9a-fA-F]{64}$
- name: interconnects
type: Array
description: |
The names of the Interconnects that use this key group.
output: true
custom_flatten: templates/terraform/custom_flatten/network_connectivity_interconnect_key_group_interconnects.go.tmpl
item_type:
type: String
32 changes: 31 additions & 1 deletion mmv1/templates/terraform/constants/interconnect.go.tmpl
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
func InterconnectTypeDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
return old == "IT_PRIVATE" && new == "DEDICATED"
}
}

// computeInterconnectKeyGroupDiffSuppress treats two InterconnectKeyGroup references as equal when
// they name the same key group: full URL vs relative name, and project number vs project ID.
func computeInterconnectKeyGroupDiffSuppress(_, old, new string, _ *schema.ResourceData) bool {
if old == new {
return true
}
parse := func(s string) []string {
if i := strings.Index(s, "projects/"); i >= 0 {
s = s[i:]
}
return strings.Split(strings.Trim(s, "/"), "/")
}
o, n := parse(old), parse(new)
valid := func(p []string) bool {
return len(p) == 6 && p[0] == "projects" && p[2] == "locations" && p[4] == "interconnectKeyGroups"
}
if !valid(o) || !valid(n) || o[3] != n[3] || o[5] != n[5] {
return false
}
if o[1] == n[1] {
return true
}
// The API may return the project number where the config uses the project ID, or vice versa.
isNumber := func(s string) bool {
_, err := strconv.ParseUint(s, 10, 64)
return err == nil
}
return isNumber(o[1]) != isNumber(n[1])
}
Loading
Loading