Skip to content

Commit ef3baae

Browse files
authored
fix: minor updates for CI (#691)
1 parent af3f53c commit ef3baae

File tree

21 files changed

+142
-54
lines changed

21 files changed

+142
-54
lines changed

.github/workflows/lint.yaml

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright 2024 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+
# NOTE: This file was taken from:
16+
# https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/master/infra/terraform/test-org/org/locals.tf
17+
18+
name: 'lint'
19+
20+
on:
21+
workflow_dispatch:
22+
pull_request:
23+
branches:
24+
- main
25+
26+
concurrency:
27+
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
28+
cancel-in-progress: true
29+
30+
jobs:
31+
lint:
32+
name: 'lint'
33+
runs-on: 'ubuntu-latest'
34+
steps:
35+
- uses: 'actions/checkout@v4'
36+
- id: variables
37+
run: |
38+
MAKEFILE=$(find . -name Makefile -print -quit)
39+
if [ -z "$MAKEFILE" ]; then
40+
echo dev-tools=gcr.io/cloud-foundation-cicd/cft/developer-tools:1 >> "$GITHUB_OUTPUT"
41+
else
42+
VERSION=$(grep "DOCKER_TAG_VERSION_DEVELOPER_TOOLS := " $MAKEFILE | cut -d\ -f3)
43+
IMAGE=$(grep "DOCKER_IMAGE_DEVELOPER_TOOLS := " $MAKEFILE | cut -d\ -f3)
44+
REGISTRY=$(grep "REGISTRY_URL := " $MAKEFILE | cut -d\ -f3)
45+
echo dev-tools=${REGISTRY}/${IMAGE}:${VERSION} >> "$GITHUB_OUTPUT"
46+
fi
47+
- run: docker run --rm -v ${{ github.workspace }}:/workspace ${{ steps.variables.outputs.dev-tools }} /usr/local/bin/test_lint.sh

anthos-attached-clusters/kind/README.md

+3-6
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,10 @@ The other examples and module limit dependancies to terraform core providers, bu
4343
--membership=${CLUSTER} \
4444
--role=${ROLE} \
4545
--users=${PRINCIPAL}
46-
47-
gcloud container fleet memberships get-credentials ${CLUSTER} --project ${PROJECT}
48-
46+
47+
gcloud container fleet memberships get-credentials ${CLUSTER} --project ${PROJECT}
48+
4949
kubectl get ns
5050
5151
```
5252
This will allow you to access the cluster using kubectl as you would other GKE Enterprise clusters, regardless of location (ie in GCP, other clouds, or on prem).
53-
54-
55-

anthos-bm-apigee/docs/variables.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ terraform-docs markdown table \
2222

2323
| Name | Version |
2424
|------|---------|
25-
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= v0.15.5, < 1.2 |
25+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= v0.15.5, < 1.4 |
2626
| <a name="requirement_google"></a> [google](#requirement\_google) | >= 3.68.0 |
2727
| <a name="requirement_google-beta"></a> [google-beta](#requirement\_google-beta) | >= 3.68.0 |
2828

anthos-bm-apigee/versions.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
terraform {
18-
required_version = ">= v0.15.5, < 1.2" # this line should not change during a release
18+
required_version = ">= v0.15.5, < 1.4" # this line should not change during a release
1919
required_providers {
2020
google = {
2121
source = "hashicorp/google"

anthos-bm-gcp-bash/install_admin_cluster.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ gcloud projects add-iam-policy-binding "$PROJECT_ID" \
163163
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
164164
--member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \
165165
--role="roles/kubernetesmetadata.publisher" \
166-
--no-user-output-enabled
166+
--no-user-output-enabled
167167

168168
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
169169
--member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \

anthos-bm-gcp-terraform/docs/variables.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ terraform-docs markdown table \
2222

2323
| Name | Version |
2424
|------|---------|
25-
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= v0.15.5, < 1.2 |
25+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= v0.15.5, < 1.4 |
2626
| <a name="requirement_google"></a> [google](#requirement\_google) | >= 3.68.0 |
2727
| <a name="requirement_google-beta"></a> [google-beta](#requirement\_google-beta) | >= 3.68.0 |
2828

anthos-bm-gcp-terraform/main.tf

+28-1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,33 @@ module "create_service_accounts" {
108108
}
109109

110110
module "instance_template" {
111+
source = "terraform-google-modules/vm/google//modules/instance_template"
112+
version = "~> 8.0"
113+
depends_on = [
114+
module.enable_google_apis_primary,
115+
module.enable_google_apis_secondary
116+
]
117+
# fetched from previous module to explicitely express dependency
118+
project_id = module.enable_google_apis_secondary.project_id
119+
region = var.region # --zone=${ZONE}
120+
source_image = var.image # --image=ubuntu-2004-focal-v20210429
121+
source_image_family = var.image_family # --image-family=ubuntu-2004-lts
122+
source_image_project = var.image_project # --image-project=ubuntu-os-cloud
123+
machine_type = var.machine_type # --machine-type $MACHINE_TYPE
124+
disk_size_gb = var.boot_disk_size # --boot-disk-size 200G
125+
disk_type = var.boot_disk_type # --boot-disk-type pd-ssd
126+
network = var.network # --network default
127+
tags = var.tags # --tags http-server,https-server
128+
min_cpu_platform = var.min_cpu_platform # --min-cpu-platform "Intel Haswell"
129+
can_ip_forward = true # --can-ip-forward
130+
# Disable oslogin explicitly since we rely on metadata based ssh-key (issues/70).
131+
metadata = {
132+
enable-oslogin = "false"
133+
}
134+
service_account = null
135+
}
136+
137+
module "instance_template_worker" {
111138
source = "terraform-google-modules/vm/google//modules/instance_template"
112139
version = "~> 8.0"
113140
depends_on = [
@@ -175,7 +202,7 @@ module "worker_vm_hosts" {
175202
zone = var.zone
176203
network = var.network
177204
vm_names = local.worker_vm_names
178-
instance_template = module.instance_template.self_link
205+
instance_template = module.instance_template_worker.self_link
179206
}
180207

181208
module "configure_controlplane_lb" {

anthos-bm-gcp-terraform/terraform.tfvars.sample

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ instance_count = {
1515
#nfs_server = true
1616
#gpu = {
1717
# count = 1,
18-
# type = "nvidia-tesla-k80"
18+
# type = "nvidia-tesla-t4"
1919
# }

anthos-bm-gcp-terraform/variables.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ variable "region" {
4141
variable "zone" {
4242
description = "Zone within the selected Google Cloud Region that is to be used"
4343
type = string
44-
default = "us-central1-a"
44+
default = "us-central1-b"
4545
}
4646

4747
variable "username" {

anthos-bm-openstack-terraform/resources/abm_cluster_login.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ metadata:
6464
type: kubernetes.io/service-account-token
6565
__EOF__
6666

67-
until [[ $(kubectl get -o=jsonpath="{.data.token}" "secret/${SECRET_NAME}") ]]; do
67+
until [[ $(kubectl get -o=jsonpath="{.data.token}" "secret/${SECRET_NAME}") ]]; do
6868
echo "waiting for token..." >&2;
6969
sleep 1;
7070
done
@@ -76,4 +76,4 @@ echo "🚀 ------------------------------TOKEN--------------------------------
7676
echo "$TOKEN"
7777
echo "🚀 ------------------------------------------------------------------- 🚀"
7878

79-
# [END anthosbaremetal_resources_abm_cluster_login]
79+
# [END anthosbaremetal_resources_abm_cluster_login]

anthos-bm-openstack-terraform/resources/abm_init_host.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function __setup_kubctl__ () {
5252
# Install the bmctl CLI for managing the Anthos cluster
5353
##############################################################################
5454
function __setup_bmctl__ () {
55-
gsutil cp gs://anthos-baremetal-release/bmctl/${ABM_VERSION}/linux-amd64/bmctl .
55+
gsutil cp gs://anthos-baremetal-release/bmctl/"${ABM_VERSION}"/linux-amd64/bmctl .
5656
chmod a+x bmctl
5757
sudo mv bmctl /usr/local/sbin/
5858
__check_exit_status__ $? \
@@ -122,4 +122,4 @@ function __print_separator__ () {
122122
# Run the script from main()
123123
__main__ "$@"
124124

125-
# [END anthosbaremetal_resources_abm_init_host]
125+
# [END anthosbaremetal_resources_abm_init_host]

anthos-bm-openstack-terraform/resources/abm_setup_gcp.sh

+10-11
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@
2020
# Download the service account key in order to configure the Anthos cluster
2121
##############################################################################
2222
function __setup_service_account__ () {
23-
gcloud iam service-accounts create ${SERVICE_ACCOUNT}
24-
gcloud iam service-accounts keys create bm-gcr.json --iam-account="${SERVICE_ACCOUNT}"@"${PROJECT_ID}".iam.gserviceaccount.com
25-
if [ "$?" -eq 0 ]
23+
gcloud iam service-accounts create "${SERVICE_ACCOUNT}"
24+
if ! gcloud iam service-accounts keys create bm-gcr.json --iam-account="${SERVICE_ACCOUNT}"@"${PROJECT_ID}".iam.gserviceaccount.com
2625
then
2726
echo "[+] Successfully downloaded key for service account [$SERVICE_ACCOUNT]"
2827
else
@@ -80,32 +79,32 @@ cat << EOM
8079
- roles/opsconfigmonitoring.resourceMetadata.writer
8180
------------------------------------------------------------------------------
8281
EOM
83-
gcloud projects add-iam-policy-binding $PROJECT_ID \
82+
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
8483
--member="serviceAccount:${SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
8584
--role="roles/gkehub.connect"
8685

87-
gcloud projects add-iam-policy-binding $PROJECT_ID \
86+
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
8887
--member="serviceAccount:${SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
8988
--role="roles/gkehub.admin"
9089

91-
gcloud projects add-iam-policy-binding $PROJECT_ID \
90+
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
9291
--member="serviceAccount:${SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
9392
--role="roles/logging.logWriter"
9493

95-
gcloud projects add-iam-policy-binding $PROJECT_ID \
94+
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
9695
--member="serviceAccount:${SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
9796
--role="roles/monitoring.metricWriter"
9897

99-
gcloud projects add-iam-policy-binding $PROJECT_ID \
98+
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
10099
--member="serviceAccount:${SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
101100
--role="roles/monitoring.dashboardEditor"
102101

103-
gcloud projects add-iam-policy-binding $PROJECT_ID \
102+
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
104103
--member="serviceAccount:${SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
105104
--role="roles/stackdriver.resourceMetadata.writer"
106105

107-
gcloud projects add-iam-policy-binding $PROJECT_ID \
106+
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
108107
--member="serviceAccount:${SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
109108
--role="roles/opsconfigmonitoring.resourceMetadata.writer"
110109

111-
# [END anthosbaremetal_resources_abm_setup_gcp]
110+
# [END anthosbaremetal_resources_abm_setup_gcp]

anthos-bm-openstack-terraform/resources/cloud-config.yaml

+14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
# Copyright 2021 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+
115
#cloud-config
216
users:
317
- default

anthos-bm-openstack-terraform/resources/create-certs.sh

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#!/bin/bash
2+
13
# Copyright 2021 Google LLC
24
#
35
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -139,4 +141,4 @@ openssl x509 -in "${DIR}/my-service.crt" -noout -text
139141
# IP Address:1.2.3.4, DNS:my.dns.name
140142
#
141143

142-
# [END anthosbaremetal_resources_create_certs]
144+
# [END anthosbaremetal_resources_create_certs]

anthos-multi-cloud/AWS/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ gcloud components update
8484
```bash
8585
gcp_project_id = "project-id"
8686
admin_user = "[email protected]"
87-
87+
8888
cluster_version = "supported_gke_version"
8989
# supported versions at https://cloud.devsite.corp.google.com/kubernetes-engine/multi-cloud/docs/aws/reference/versioning#version_lifespans
9090
```

anthos-onprem-terraform/README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ For more information, see the reference documentation for each resource.
1111

1212
#### Anthos clusters on bare metal (ABM)
1313

14-
| Type | Sample _(by loadbalancer type)_ | Terraform resources |
14+
| Type | Sample _(by loadbalancer type)_ | Terraform resources |
1515
| ---------------- | ---------------------------------------------- | ------------------- |
16-
| **user** cluster | Bundled [MetalLB](./abm_user_cluster_metallb/) | [google_gkeonprem_bare_metal_cluster](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_bare_metal_cluster) </br> [google_gkeonprem_bare_metal_node_pool](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_bare_metal_node_pool) |
17-
| **user** cluster | [ManualLB](./abm_user_cluster_manuallb/) | [google_gkeonprem_bare_metal_cluster](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_bare_metal_cluster) </br> [google_gkeonprem_bare_metal_node_pool](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_bare_metal_node_pool) |
16+
| **user** cluster | Bundled [MetalLB](./abm_user_cluster_metallb/) | [google_gkeonprem_bare_metal_cluster](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_bare_metal_cluster) </br> [google_gkeonprem_bare_metal_node_pool](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_bare_metal_node_pool) |
17+
| **user** cluster | [ManualLB](./abm_user_cluster_manuallb/) | [google_gkeonprem_bare_metal_cluster](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_bare_metal_cluster) </br> [google_gkeonprem_bare_metal_node_pool](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_bare_metal_node_pool) |
1818

1919
---
2020

2121
#### Anthos clusters on VMware (AVMware)
2222

23-
| Type | Sample _(by loadbalancer type)_ | Terraform resources |
23+
| Type | Sample _(by loadbalancer type)_ | Terraform resources |
2424
| ---------------- | ----------------------------------------------- | ------------------- |
25-
| **user** cluster | Bundled [MetalLB](./avmw_user_cluster_metallb/) | [google_gkeonprem_vmware_cluster](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_vmware_cluster) </br> [google_gkeonprem_vmware_node_pool](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_vmware_node_pool) |
25+
| **user** cluster | Bundled [MetalLB](./avmw_user_cluster_metallb/) | [google_gkeonprem_vmware_cluster](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_vmware_cluster) </br> [google_gkeonprem_vmware_node_pool](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/gkeonprem_vmware_node_pool) |
2626

2727
---

anthos-onprem-terraform/avmw_user_cluster_metallb/README.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ have changed directory to where this samples is:
5858

5959
### Upgrade the user cluster with terraform
6060

61-
Use the same terraform script to upgrade the user cluster, by simply changing
62-
the version to the new version. Note that this script can be used for upgrades
63-
only if you had created the user cluster using this script. When you run the
64-
script with the updated version, the `terraform.tfstate` created during the
61+
Use the same terraform script to upgrade the user cluster, by simply changing
62+
the version to the new version. Note that this script can be used for upgrades
63+
only if you had created the user cluster using this script. When you run the
64+
script with the updated version, the `terraform.tfstate` created during the
6565
first run of the script is compared to recognize the change.
6666

67-
Before upgrading the user cluster, please make sure the admin cluster has been
67+
Before upgrading the user cluster, please make sure the admin cluster has been
6868
enrolled in the Anthos On-Prem API. Steps for enrolling the admin cluster are
6969
listed in [public documentation](https://cloud.google.com/anthos/clusters/docs/on-prem/latest/how-to/enroll-cluster#enroll_a_cluster).
7070

@@ -80,14 +80,14 @@ gcloud beta container vmware admin-clusters enroll ADMIN_CLUSTER_NAME \
8080
This `gcloud_update_admin_cluster_platform_controller` module uses the `gcloud`
8181
command prepare the admin cluster to enable the user cluster upgrade.
8282

83-
- [**`gcloud_update_admin_cluster_platform_controller`**](./main.tf#L53-L65):
83+
- [**`gcloud_update_admin_cluster_platform_controller`**](./main.tf#L53-L65):
8484
This module is used to ensure that the ** platform controller** of the admin cluster
8585
is on a compatible version. The platform controller contains one or more bundles of
8686
components that the admin cluster uses to manage user clusters. The bundles are
8787
version specific, that is, the platform controller must contain a bundle version that
8888
matches the _Anthos on VMware version of the user cluster_. Thus, by having this
89-
module in the script we ensure that the platform controller in the admin cluster is
90-
always on the correct user cluster version.
89+
module in the script we ensure that the platform controller in the admin cluster is
90+
always on the correct user cluster version.
9191

9292
Then, following the steps below to upgrade the user cluster via terraform.
9393

anthos-onprem-terraform/avmw_user_cluster_metallb/main.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ resource "google_project_service" "default" {
4848
}
4949

5050
# This module is used to update the platform controller on your admin cluster. This
51-
# is a necessary step for the user cluster version update. If the admin cluster is
51+
# is a necessary step for the user cluster version update. If the admin cluster is
5252
# already on the correct version, then this module does not change anything
5353
module "gcloud_update_admin_cluster_platform_controller" {
5454
source = "terraform-google-modules/gcloud/google"

test/fixtures/abm_gce_gpu/main.tf

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616

1717
locals {
18-
ssh_as_tfadmin_cmd = "gcloud compute ssh tfadmin@cluster1-abm-ws0-001 --project=${var.editor_project_id} --zone=us-central1-a --ssh-flag=\"-T\" -q -- ls"
18+
ssh_as_tfadmin_cmd = "gcloud compute ssh tfadmin@cluster1-abm-ws0-001 --project=${var.editor_project_id} --zone=us-central1-b --ssh-flag=\"-T\" -q -- ls"
1919
install_abm_cmd = <<EOF
20-
gcloud compute ssh tfadmin@cluster1-abm-ws0-001 --project=${var.editor_project_id} --zone=us-central1-a \
20+
gcloud compute ssh tfadmin@cluster1-abm-ws0-001 --project=${var.editor_project_id} --zone=us-central1-b \
2121
--ssh-flag=-T -q -- sudo ./run_initialization_checks.sh
2222
EOF
2323
}
@@ -29,6 +29,6 @@ module "anthos_bm_gcp" {
2929
resources_path = "../../../anthos-bm-gcp-terraform/resources"
3030
gpu = {
3131
count = 1,
32-
type = "nvidia-tesla-k80"
32+
type = "nvidia-tesla-t4"
3333
}
3434
}

test/integration/abm_gce_defaults_on_editor_project/abm_gce_editor_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,6 @@ func TestABMEditor(t *testing.T) {
9898

9999
// runSSHCmd runs gcloud ssh command with ssh args and returns output
100100
func runSSHCmd(t *testing.T, project, user, args string) string {
101-
commonArgs := gcloud.WithCommonArgs([]string{"--command", args, "--project", project, "--zone", "us-central1-a", "--ssh-flag=-T", "-q"})
101+
commonArgs := gcloud.WithCommonArgs([]string{"--command", args, "--project", project, "--zone", "us-central1-b", "--ssh-flag=-T", "-q"})
102102
return gcloud.RunCmd(t, fmt.Sprintf("compute ssh %s", user), commonArgs)
103103
}

0 commit comments

Comments
 (0)