1. CFT 入門ガイド
最終更新日: 2020 年 3 月 3 日
Cloud Foundation Toolkit とは何ですか?
基本的に、CFT は、Google Cloud Platform ですぐに使用を開始するためのベスト プラクティス テンプレートを提供しています。このチュートリアルでは、Cloud Foundation Toolkit に貢献する方法を学びます。
必要なもの
- GitHub アカウント。
- マシンに Docker がインストールされている(Mac でインストール、Windows でインストール)
- コード編集用のコードエディタ(例: Visual Studio Code)
- Git と GitHub に関する基本的な知識
- Terraform と Infrastructure as Code の使用経験
- サービス アカウントにプロジェクト作成者ロールを付与する権限
作成するアプリの概要
この Codelab では、Cloud Foundation Toolkit(CFT)に貢献する方法を学びます。
次のことを行います。
- CFT に貢献するための開発環境をセットアップする
- CFT モジュールに機能を追加する
- 機能のテストを追加する
- CFT で統合テストを実行する
- lint テストを実行する
- コードを GitHub に commit して pull リクエスト(PR)を送信する
上の手順をすべて実行するには、新機能を Google Cloud Storage CFT モジュールに追加します。"silly_label"
というラベルを追加します。これは、GCS CFT モジュールで作成されたすべてのバケットに自動的に追加されます。また、機能を検証し、エンドツーエンドの統合を確保するためのテストを作成することもできます。
2. 開発環境の設定
必要に応じて、開発目的で Cloud Shell を利用できます。CFT への投稿に Cloud Shell を使用しない場合は、お使いのマシンに開発環境を設定できます。
Git を設定する
GitHub は、Git と呼ばれるオープンソースのバージョン管理システム(VCS)をベースにしています。Git は、マシンまたは Cloud Shell 上でローカルに発生する GitHub 関連のすべての処理を担当します。
- Cloud Shell を使用する場合は、git がプリインストールされているため、インストールする必要はありません。
$ git --version
# This will display the git version on the Cloud Shell.
マシン上に開発環境を設定する場合は、Git をインストールする必要があります。
Git でユーザー名とメールを設定する
Git はユーザー名を使用して commit を ID に関連付けます。Git ユーザー名が GitHub ユーザー名と同じではありません。
Git commit に関連付けられた名前を変更するには、git config コマンドを使用します。git config
を使用して Git commit に関連付けられた名前を変更すると、今後の commit にのみ影響し、過去の commit に使用された名前は変更されません。
Git が正常にセットアップされ、ブランチのフォーク、作成、クローン作成を行えるはずです。この Codelab では、Git を幅広く使用します。
3. CFT の GCS リポジトリをフォークする
CFT リポジトリをフォークする
前のステップで、ローカルマシンまたは Cloud Shell に Git を設定します。次に、Google Cloud Storage の CFT リポジトリをフォークして、コントリビューションを開始する必要があります。
フォークはリポジトリのコピーです。リポジトリをフォークすると、元のプロジェクトに影響を与えることなく、さまざまな変更を試すことができます。
フォークは通常、誰かのプロジェクトに対する変更を提案するため、または他人のプロジェクトを自分のアイデアの出発点として使用する目的で使用されます。
たとえば、バグ修正に関連する変更を提案するためにフォークを使用できます。以下の方法でバグを修正できます。
- リポジトリをフォークします。
- 修正します。
- pull リクエストをプロジェクト オーナーに送信します。
CFT リポジトリをフォークする手順:
- ウェブブラウザを開き、terraform-google-modules/terraform-google-cloud-storage リポジトリに移動します。このリポジトリは Codelab 全体で使用します。
- ページの右上隅にある [Fork] をクリックします。
- フォークする場所、プロファイルを選択するオプションが表示されたら、リポジトリをフォークします。
ローカルでフォークのクローンを作成する
作成したフォークは、GCS モジュール リポジトリのコピーです。次に、このリポジトリのクローンをローカル環境に作成して、新しい機能を追加します。
フォークのクローンを作成する手順:
- ウェブブラウザを開き、terraform-google-modules/terraform-google-cloud-storage にあるフォークに移動します。
- 右上に [クローンまたはダウンロード] が表示されます。クリックします。
- [クローンまたはダウンロード]をクリックした後[メモ帳] ボタンをクリックしてアイコンをクリックしてフォークの URL をコピーします。この URL を使用して、フォークのクローンをローカル環境に作成します。
- VSCode またはマシンのターミナルに移動して、フォークのクローンを作成します。
$ git clone <url>
# This command will clone your fork locally.
# Paste the copied URL from the previous step.
- ローカルでフォークのクローンを作成できたので、リポジトリに移動してフォークから新しいブランチを作成し、一時的なブランチのコードを変更する必要があります。
慣例として、ブランチには次のような名前を付けることができます。
- 機能リクエストの場合:
feature/feature-name
- 内部アップデートの場合:
internal/change-name
- バグの修正:
bugfix/issue-name
新しい特徴を追加するため、一時的なブランチ feature/silly_label
を呼び出します。
$ cd terraform-google-cloud-storage
# This command takes you into the cloned directory on your local machine.
$ git branch
# This command tells your current branch
# When you run this for the first time after you have cloned, your
# output should say "master", that is your fork.
$ git checkout -b feature/silly_label
# This command creates a new branch on your fork and switches your
# branch to the newly created branch.
$ git branch
# This command will confirm your current branch to be "feature/silly_label"
これで、Cloud Foundation Toolkit の作業を開始する準備が整いました。
4. テスト環境を作成する
標準の CFT 開発プロセスは、テスト用に分離されたテスト プロジェクトを使用することをベースとしています。この手順では、サービス アカウントを使用してテスト プロジェクト(標準構成に基づく)を作成する方法について説明します。
0. Docker Engine をインストールする
マシンを開発目的で使用している場合は、Docker Engine をインストールする必要があります。
1. Google Cloud SDK をインストールする
GCP Cloud Shell を使用している場合は、Google Cloud SDK をインストールする必要はありません。
Google Cloud SDK に移動し、お使いのプラットフォーム用のインタラクティブなインストーラをダウンロードします。
2. 構成を設定する
テスト環境を作成するには、Google Cloud の組織、テストフォルダ、請求先アカウントが必要です。これらの値は、環境変数を使用して設定する必要があります。
export TF_VAR_org_id="your_org_id"
export TF_VAR_folder_id="your_folder_id"
export TF_VAR_billing_account="your_billing_account_id"
3 サービス アカウントを設定する
テスト環境を作成する前に、サービス アカウント キーをテスト環境にダウンロードする必要があります。このサービス アカウントには、プロジェクト作成者、請求先アカウント ユーザー、組織閲覧者のロールが必要です。新しいサービス アカウントを作成する手順は次のとおりですが、既存のアカウントを再利用することもできます。
3.1 シード GCP プロジェクトを作成または選択する
サービス アカウントを作成する前に、サービス アカウントをホストするプロジェクトを選択する必要があります。新しいプロジェクトを作成することもできます。
gcloud config set core/project YOUR_PROJECT_ID
3.2 Google Cloud APIs を有効にする
シード プロジェクトで次の Google Cloud APIs を有効にします。
gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable iam.googleapis.com
gcloud services enable cloudbilling.googleapis.com
3.3 サービス アカウントを作成する
テスト環境を管理するための新しいサービス アカウントを作成します。
# Creating a service account for CFT.
gcloud iam service-accounts create cft-onboarding \
--description="CFT Onboarding Terraform Service Account" \
--display-name="CFT Onboarding"
# Assign SERVICE_ACCOUNT environment variable for later steps
export SERVICE_ACCOUNT=cft-onboarding@$(gcloud config get-value core/project).iam.gserviceaccount.com
サービス アカウントが作成されたことを確認します。
gcloud iam service-accounts list --filter="EMAIL=${SERVICE_ACCOUNT}"
3.4 サービス アカウントにプロジェクト作成者、請求先アカウント ユーザー、組織閲覧者のロールを付与します。
gcloud resource-manager folders add-iam-policy-binding ${TF_VAR_folder_id} \
--member="serviceAccount:${SERVICE_ACCOUNT}" \
--role="roles/resourcemanager.projectCreator"
gcloud organizations add-iam-policy-binding ${TF_VAR_org_id} \
--member="serviceAccount:${SERVICE_ACCOUNT}" \
--role="roles/billing.user"
gcloud organizations add-iam-policy-binding ${TF_VAR_org_id} \
--member="serviceAccount:${SERVICE_ACCOUNT}" \
--role="roles/resourcemanager.organizationViewer"
これで、テスト環境の管理に使用できるサービス アカウントが作成されました。
4. 請求先アカウント リソースに請求先アカウント ユーザーロールを割り当てる
4.1 請求先アカウントの IAM ポリシーを取得する
請求先アカウントの既存の IAM ポリシー バインディングをダウンロードする
gcloud beta billing accounts get-iam-policy ${TF_VAR_billing_account} | tee policy.yml
4.2 ポリシーを更新してサービス アカウントを追加する
policy.yml
ファイルを更新して、roles/billing.user
ロールを持つサービス アカウントの新しいバインディングを追加します。
bindings:
- members:
- serviceAccount:cft-onboarding@<YOUR_PROJECT_ID>.iam.gserviceaccount.com
role: roles/billing.user
4.3 請求先アカウントに関するポリシーを更新する
請求先アカウントに変更を適用する
gcloud beta billing accounts set-iam-policy ${TF_VAR_billing_account} policy.yml
5. Terraform 認証情報を準備する
テスト環境を作成するには、サービス アカウント キーをシェルにダウンロードする必要があります。
5.1 サービス アカウント キー
Terraform 用のサービス アカウント キーを作成してダウンロードする
gcloud iam service-accounts keys create cft.json --iam-account=${SERVICE_ACCOUNT}
5.2 Terraform 認証情報を設定する
環境変数 SERVICE_ACCOUNT_JSON
を使用して Terraform に鍵を指定し、値をサービス アカウント キーの contents に設定します。
export SERVICE_ACCOUNT_JSON=$(< cft.json)
6. Terraform デプロイ用のテスト プロジェクトを作成する
すべての準備が整ったので、1 つのコマンドでテスト プロジェクトを作成できます。このコマンドは、terraform-google-cloud-storage ディレクトリのルートから実行します。
make docker_test_prepare
make docker_test_prepare
を実行すると、以下の出力が表示されます。最後に、作成されたテスト project_id が返されます。このテスト プロジェクトでは、新しい機能を追加して Cloud Storage モジュールをデプロイしてテストします。
macbookpro3:terraform-google-cloud-storage user$ make docker_test_prepare
docker run --rm -it \
-e SERVICE_ACCOUNT_JSON \
-e TF_VAR_org_id \
-e TF_VAR_folder_id \
-e TF_VAR_billing_account \
-v /Users/cft/terraform-google-cloud-storage:/workspace \
gcr.io/cloud-foundation-cicd/cft/developer-tools:0.8.0 \
/usr/local/bin/execute_with_credentials.sh prepare_environment
Activated service account credentials for: [cft-onboarding@<project_id>.iam.gserviceaccount.com]
Activated service account credentials for: [cft-onboarding@<project_id>.iam.gserviceaccount.com]
Initializing modules...
Initializing the backend...
Initializing provider plugins...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.google-beta: version = "~> 3.9"
* provider.null: version = "~> 2.1"
* provider.random: version = "~> 2.2"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
module.project.module.project-factory.null_resource.preconditions: Refreshing state... [id=8723188031607443970]
module.project.module.project-factory.null_resource.shared_vpc_subnet_invalid_name[0]: Refreshing state... [id=5109975723938185892]
module.project.module.gsuite_group.data.google_organization.org[0]: Refreshing state...
module.project.module.project-factory.random_id.random_project_id_suffix: Refreshing state... [id=rnk]
module.project.module.project-factory.google_project.main: Refreshing state... [id=<project-id>]
module.project.module.project-factory.google_project_service.project_services[0]: Refreshing state... [id=<project-id>/storage-api.googleapis.com]
module.project.module.project-factory.google_project_service.project_services[1]: Refreshing state... [id=<project-id>/cloudresourcemanager.googleapis.com]
module.project.module.project-factory.google_project_service.project_services[2]: Refreshing state... [id=<project-id>/compute.googleapis.com]
module.project.module.project-factory.data.null_data_source.default_service_account: Refreshing state...
module.project.module.project-factory.google_service_account.default_service_account: Refreshing state... [id=projects/ci-cloud-storage-ae79/serviceAccounts/project-service-account@<project-id>.iam.gserv
iceaccount.com]
module.project.module.project-factory.google_project_service.project_services[3]: Refreshing state... [id=<project-id>/serviceusage.googleapis.com]
module.project.module.project-factory.null_resource.delete_default_compute_service_account[0]: Refreshing state... [id=3576396874950891283]
google_service_account.int_test: Refreshing state... [id=projects/<project-id>/serviceAccounts/cft-onboarding@<project-id>.iam.gserviceaccount.com]
google_service_account_key.int_test: Refreshing state... [id=projects/<project-id>/serviceAccounts/cft-onboarding@<project-id>.iam.gserviceaccount.com/keys/351009a1e011e88049ab2097994d1c627a61
6961]
google_project_iam_member.int_test[1]: Refreshing state... [id=<project-id>/roles/iam.serviceAccountUser/serviceaccount:cft-onboarding@<project-id>.iam.gserviceaccount.com]
google_project_iam_member.int_test[0]: Refreshing state... [id=<project-id>/roles/storage.admin/serviceaccount:cft-onboarding@<project-id>.iam.gserviceaccount.com]
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
project_id = <test-project-id>
sa_key = <sensitive>
Found test/setup/make_source.sh. Using it for additional explicit environment configuration.
これで、テスト プロジェクトが作成されました。コンソール出力で確認できます。project_id で参照されます。開発環境とテスト環境が設定されました。
5. CFT モジュールに新機能を追加する
開発環境とテスト環境のセットアップが完了したので、「silly_label」を追加してみましょう。google-cloud-storage CFT モジュールに追加します。
terraform-google-cloud-storage 内にいることを確認し、以下のフォルダ構造に示すように main.tf ファイルを開きます。
「silly_label」以降特徴を 27 行目の変数「labels」に追加します。以下に示すように、main.tf 内に記述します。
terraform-google-cloud-storage/main.tf
resource "google_storage_bucket" "buckets" {
<...>
storage_class = var.storage_class
// CODELAB:Add silly label in labels variable
labels = merge(var.labels, { name = replace("${local.prefix}${lower(element(var.names, count.index))}", ".", "-") }, { "silly" = var.silly_label })
force_destroy = lookup(
<...>
}
次に、上記のフォルダ構造に表示される variables.tf に silly_label 変数を追加します。
以下のコードをコピーして、variables.tf の 29 行目に追加し、追加する variable ブロックの上と下に改行文字があることを確認します。
terraform-google-cloud-storage/variables.tf
variable "names" {
description = "Bucket name suffixes."
type = list(string)
}
// CODELAB: Add "silly_label" variable to variables.tf between "names" and "location"
variable "silly_label" {
description = "Sample label for bucket."
type = string
}
variable "location" {
description = "Bucket location."
default = "EU"
}
6. Storage バケットの例に新しい特徴を追加する
モジュールの main.tf に機能を追加したら、例を使用して、追加した機能をテストします。
「silly_label」example/multiple-buckets/main.tf ファイルに
この例は、次のステップでインテグレーション テストを実行するフィクスチャで使用されます。
以下の変数の silly_label 行をコピーして、フォルダ構造に表示されているように、terraform-google-cloud-storage/examples/multiple-buckets/ の main.tf の 27 行目に貼り付けます。
terraform-google-cloud-storage/examples/multiple-buckets/main.tf
module "cloud_storage" {
<...>
// CODELAB: Add "silly_label" as an example to main.tf.
silly_label = "awesome"
<..>
}
7. 機能をチェックする Inspec テストを作成する
モジュールの main.tf に特徴量を追加した後、その特徴量を Multiple_buckets サンプルに追加して、フィクスチャを使用してテストできるようにしました。Ruby で記述された InSpec 統合テストで機能をテストする必要があります。
新しいテストを次のフォルダ構造にある gsutil.rb ファイルに追加します。
「silly_label」を追加しましたそれらの新機能をテストするために、テストを記述する必要があります。
次のコードでは、gsutil コマンドを使用して各バケットのラベルを取得し、コマンドから返された出力を確認します。
terraform-google-cloud-storage/test/integration/multiple-buckets/controls/gsutil.rb
control "gsutil" do
<..>
# CODELAB: Copy paste the below test in gsutil.rb to test silly_label feature.
# command to get the labels for bucket_1
describe command("gsutil label get gs://#{attribute("names_list")[0]}") do
//check if the command gave a valid response
its(:exit_status) { should eq 0 }
its(:stderr) { should eq "" }
//parse the command's output into JSON
let!(:data) do
if subject.exit_status == 0
JSON.parse(subject.stdout)
else
{}
end
end
# check if bucket_1 has the new "silly" label with the value "awesome"
describe "bucket_1" do
it "has label" do
data.each do |bucket|
expect(data["silly"]).to include("awesome")
end
end
end
end
8. CFT で統合テストを実行する
統合テスト
統合テストは、ルート モジュール、サブモジュール、サンプル モジュールの動作を検証するために使用されます。追加、変更、修正には、テストが必要です。
インテグレーション テストは、Kitchen、Kitchen-Terraform、InSpec を使用して実行されます。これらのツールは、便宜上 Docker イメージ内にパッケージ化されています。
これらのテストの一般的な戦略は、サンプル モジュールの動作を検証し、ルート モジュール、サブモジュール、サンプル モジュールがすべて機能的に正しいことを確認することです。
インタラクティブ実行では、各ステップを複数のコマンドで実行します。
make docker_run
を実行して、テスト用 Docker コンテナをインタラクティブ モードで起動します。
Make は、ターゲット プログラムの導出方法を指定する Makefile と呼ばれるファイルを読み取って、実行可能なプログラムやライブラリをソースコードから自動的にビルドするビルド自動化ツールです。ファイルを変更したら、Docker コンテナを自動的に更新する必要があります。
make docker_run
を実行するときは、Docker コンテナにワークスペースを作成し、サービス アカウントの認証情報を有効にします。ワークスペースは、次のステップでテストを実行するために使用します。
ターミナルに次の出力が表示されます。
Activated service account credentials for: [cft@<PROJECT_ID>.iam.gserviceaccount.com]
kitchen_do list
を実行して、インテグレーション テストを含むワークスペース内のすべてのインスタンスを一覧表示します。You will see the below output in your terminal.
[root@<CONTAINER_ID> workspace]# kitchen_do list
Automatically setting inputs from outputs of test/setup
Found test/source.sh. Using it for additional explicit environment configuration.
Activated service account credentials for: [cft@<PROJECT_ID>.iam.gserviceaccount.com]
Instance Driver Provisioner Verifier Transport Last Action Last Error
multiple-buckets-default Terraform Terraform Terraform Ssh Verified <None>
kitchen_do create <EXAMPLE_NAME>
を実行して、サンプル モジュールの作業ディレクトリを初期化します。
このステップでキッチンが初期化され、ワークスペース内の Terraform が初期化されます。
ターミナルに以下の出力が表示されます。
[root@<CONTAINER_ID> workspace]# kitchen_do create multiple-buckets-default
Automatically setting inputs from outputs of test/setup
Found test/source.sh. Using it for additional explicit environment configuration.
Activated service account credentials for: [cft@<PROJECT_ID>.iam.gserviceaccount.com]
-----> Starting Kitchen (v1.24.0)
-----> Creating <multiple-buckets-default>...
Terraform v0.12.12
+ provider.google v3.10.0
Your version of Terraform is out of date! The latest version
is 0.12.21. You can update by downloading from www.terraform.io/downloads.html
$$$$$$ Running command `terraform init -input=false -lock=true -lock-timeout=0s -upgrade -force-copy -backend=true -get=true -get-plugins=true -verify-plugins=true` in directory /workspace/test/fi
xtures/multiple_buckets
Upgrading modules...
- example in ../../../examples/multiple_buckets
- example.cloud_storage in ../../..
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "google" (hashicorp/google) 2.18.1...
- Downloading plugin for provider "random" (hashicorp/random) 2.2.1...
Terraform has been successfully initialized!
$$$$$$ Running command `terraform workspace select kitchen-terraform-multiple-buckets-default` in directory /workspace/test/fixtures/multiple_buckets
Finished creating <multiple-buckets-default> (0m11.01s).
-----> Kitchen is finished. (0m12.62s)
kitchen_do converge <EXAMPLE_NAME>
を実行して、サンプル モジュールを適用します。
このステップでは、前のステップで作成した Terraform ワークスペースを、この Codelab で前に作成した GCP プロジェクトに適用します。
ターミナルに以下の出力が表示されます。
[root@<CONTAINER_ID> workspace]# kitchen_do converge multiple-buckets-default
Automatically setting inputs from outputs of test/setup
Found test/source.sh. Using it for additional explicit environment configuration.
Activated service account credentials for: [cft@<YOUR_PROJECT_ID>.iam.gserviceaccount.com]
-----> Starting Kitchen (v1.24.0)
-----> Converging <multiple-buckets-default>...
Terraform v0.12.20
+ provider.google v3.9.0
Your version of Terraform is out of date! The latest version
is 0.12.21. You can update by downloading from https://www.terraform.io/downloads.html
$$$$$$ Running command `terraform workspace select kitchen-terraform-multiple-buckets-default` in directory /workspace/test/fixtures/multiple_buckets
$$$$$$ Running command `terraform get -update` in directory /workspace/test/fixtures/multiple_buckets
- example in ../../../examples/multiple_buckets
- example.cloud_storage in ../../..
$$$$$$ Running command `terraform validate ` in directory /workspace/test/fixtures/multiple_buckets
Success! The configuration is valid.
$$$$$$ Running command `terraform apply -lock=true -lock-timeout=0s -input=false -auto-approve=true -parallelism=10 -refresh=true ` in directory /workspace/test/fixtures/multiple_buckets
random_pet.main: Creating...
random_pet.main: Creation complete after 0s [id=<BUCKET-ID>]
module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Creating...
module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Creating...
module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Creation complete after 3s [id=<BUCKET-ID-01>]
module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Creation complete after 3s [id=<BUCKET-ID-02>]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Outputs:
names = {
"one" = "<BUCKET-ID-01>"
"two" = "<BUCKET-ID-02>"
}
names_list = [
"<BUCKET-NAME-01>",
"<BUCKET-NAME-02>",
]
project_id = ci-cloud-storage-ae79
Finished converging <multiple-buckets-default> (0m7.17s).
-----> Kitchen is finished. (0m8.77s)
kitchen_do verify <EXAMPLE_NAME>
を実行して、サンプル モジュールをテストします。
このステップは、multiple_buckets モジュールのテストを含む gsutils.rb ファイルを使用して実行します。各テストには gsutil コマンドがあります。このコマンドは、サービス アカウントの認証情報の設定を使用して先ほど作成したテスト プロジェクトに対して実行されます。
エラーが発生した場合は、テストで想定されていた内容とコマンドが受信した内容が表示されます。
ターミナルに以下の出力が表示されます。
multiple_buckets local: Verifying
Profile: multiple_buckets
Version: (not specified)
Target: local://
✔ gsutil: gsutil
✔ Command: `gsutil ls -p <PROJECT_ID>` exit_status should eq 0
✔ Command: `gsutil ls -p <PROJECT_ID>` stderr should eq ""
✔ Command: `gsutil ls -p <PROJECT_ID>` stdout should include "multiple-buckets-mzgy-eu-one"
✔ Command: `gsutil ls -p <PROJECT_ID>` stdout should include "<BUCKET-ID-01>"
✔ Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-01>` exit_status should eq 0
✔ Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-01>` stderr should eq ""
✔ Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-01>` stdout should include "Enabled: True"
✔ Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-02>` exit_status should eq 0
✔ Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-02>` stderr should eq ""
✔ Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-02>` stdout should include "Enabled: False"
✔ Command: `gsutil label get gs://<BUCKET-ID-01>` exit_status should eq 0
✔ Command: `gsutil label get gs://<BUCKET-ID-01>` stderr should eq ""
✔ Command: `gsutil label get gs://<BUCKET-ID-01>` bucket_1 has label
✔ Command: `gsutil label get gs://<BUCKET-ID-02>` exit_status should eq 0
✔ Command: `gsutil label get gs://<BUCKET-ID-02>` stderr should eq ""
✔ Command: `gsutil label get gs://<BUCKET-ID-02>` bucket_2 has label
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq "NEARLINE"
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq "SetStorageClass"
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq 10
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq false
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq ["MULTI_REGIONAL", "STANDARD", "DURABLE_REDUCED_AVAILABILITY"]
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` exit_status should eq 0
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` stderr should eq ""
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq "NEARLINE"
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq "SetStorageClass"
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq 10
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq false
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq ["MULTI_REGIONAL", "STANDARD", "DURABLE_REDUCED_AVAILABILITY"]
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` exit_status should eq 0
✔ Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` stderr should eq ""
Profile Summary: 1 successful control, 0 control failures, 0 controls skipped
Test Summary: 30 successful, 0 failures, 0 skipped
Finished verifying <multiple-buckets-default> (0m8.83s).
-----> Kitchen is finished. (0m16.61s)
kitchen_do destroy <EXAMPLE_NAME>
を実行して、サンプル モジュールの状態を破棄します。
これにより、上記の手順で作成したワークスペースが破棄されます。このステップでは、プロジェクトで作成された GCS バケットと GCS モジュールに追加したラベルも破棄されます。
ターミナルで次の出力を確認できます。
[root@<CONTAINER_ID> workspace]# kitchen_do destroy multiple-buckets-default
Automatically setting inputs from outputs of test/setup
Found test/source.sh. Using it for additional explicit environment configuration.
Activated service account credentials for: [ci-cloud-storage@ci-cloud-storage-54ab.iam.gserviceaccount.com]
-----> Starting Kitchen (v1.24.0)
-----> Destroying <multiple-buckets-default>...
Terraform v0.12.12
+ provider.google v3.10.0
Your version of Terraform is out of date! The latest version
is 0.12.21. You can update by downloading from www.terraform.io/downloads.html
$$$$$$ Running command `terraform init -input=false -lock=true -lock-timeout=0s -force-copy -backend=true -get=true -get-plugins=true -verify-plugins=true` in directory /workspace/test/fixtures/mu
ltiple_buckets
Initializing modules...
Initializing the backend...
Initializing provider plugins...
Terraform has been successfully initialized!
$$$$$$ Running command `terraform workspace select kitchen-terraform-multiple-buckets-default` in directory /workspace/test/fixtures/multiple_buckets
$$$$$$ Running command `terraform destroy -auto-approve -lock=true -lock-timeout=0s -input=false -parallelism=10 -refresh=true ` in directory /workspace/test/fixtures/multiple_buckets
random_string.prefix: Refreshing state... [id=mzgy]
module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Refreshing state... [id=<BUCKET-ID-01>]
module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Refreshing state... [id=<BUCKET-ID-02>]
module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Destroying... [id=<BUCKET-ID-01>]
module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Destroying... [id=<BUCKET-ID-02>]
module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Destruction complete after 1s
module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Destruction complete after 2s
random_string.prefix: Destroying... [id=mzgy]
random_string.prefix: Destruction complete after 0s
Destroy complete! Resources: 3 destroyed.
$$$$$$ Running command `terraform workspace select default` in directory /workspace/test/fixtures/multiple_buckets
Switched to workspace "default".
$$$$$$ Running command `terraform workspace delete kitchen-terraform-multiple-buckets-default` in directory /workspace/test/fixtures/multiple_buckets
Deleted workspace "kitchen-terraform-multiple-buckets-default"!
Finished destroying <multiple-buckets-default> (0m6.49s).
-----> Kitchen is finished. (0m8.10s)
9. 入力と出力のドキュメントの生成
ルート モジュール、サブモジュール、サンプル モジュールの README 内の Inputs テーブルと Outputs テーブルは、それぞれのモジュールの variables
と outputs
に基づいて自動的に生成されます。モジュール インターフェースが変更された場合は、これらのテーブルを更新する必要があります。
次のコマンドを実行します。
make generate_docs
# This will generate new Inputs and Outputs tables
10. CFT で lint テストを実行する
リンターは、ソースコードを分析して、プログラミング エラー、バグ、スタイル エラー、不審な構造にフラグを付けるツールです。
リポジトリ内のファイルの多くは、lint チェックやフォーマットを行うことで、標準の品質を維持できます。CFT の品質を確認するには、lint テストを使用します。
次のコマンドを実行します。
make docker_test_lint
# This will run all lint tests on your repo
11. GitHub で PR を提出する
ローカルでコードを変更し、統合テストでテストしたので、このコードをマスター リポジトリに公開しようと思います。
コードをマスター リポジトリで使用できるようにするには、コードの変更をブランチに commit し、マスター リポジトリに push する必要があります。Codelab の開始時にフォークしたメイン リポジトリにコードを追加するには、リポジトリにコードを commit した後にマスター リポジトリで pull リクエスト(PR)を行います。
PR を行うと、提案されたコード変更を確認するようにリポジトリ管理者に通知されます。さらに、他のユーザーをレビュー担当者として追加して、コード変更に対するフィードバックを得ることもできます。PR は、リポジトリでテストを実行する Cloud Build をトリガーします。
コードレビュー担当者は、コードの変更に基づいてコードにコメントし、ベスト プラクティスやドキュメントに基づいて変更が必要な場合は、変更を依頼します。管理者はコードの変更内容をレビューし、コードがリポジトリに準拠していることを確認し、コードをマスター リポジトリにマージする前に再度変更を加えるよう求めることがあります。
以下のステップを実行して、フォークしたブランチにコードを commit し、フォークしたブランチにコードを push します。
- まず、変更したファイルをローカル リポジトリに追加します。
$ git add main.tf
$ git add README.md
$ git add variables.tf
$ git add examples/multiple-buckets/main.tf
$ git add test/integration/multiple-buckets/controls/gsutil.rb
# The ‘git add' command adds the file in the local repository and
# stages the file for commit. To unstage a file, use git reset HEAD YOUR-FILE
- これでファイルがステージングされました。次は変更を commit します。
$ git commit -m "First CFT commit"
# This will commit the staged changes and prepares them to be pushed
# to a remote repository. To remove this commit and modify the file,
# use 'git reset --soft HEAD~1' and commit and add the file again.
- ローカル リポジトリの commit された変更を GitHub に push して、pull リクエスト(PR)を作成する。
$ git push -u origin master
# Pushes the changes in your local repository up to the remote
# repository you specified as the origin
これで、コードを変更して pull リクエストを行う準備が整いました。
次の手順で terraform-google-modules/terraform-google-cloud-storage リポジトリに PR を作成します。
- ウェブブラウザで、リポジトリのメインページに移動します。
- [ブランチ] メニューで、commit を含むフォークを選択します。
- [Branch] の右側[New pull request] をクリックします。
- ベースの「base」を使用しますプルダウン メニューで、変更を統合するブランチを選択します。通常は「マスター」ですブランチに分割できます。
- pull リクエストのタイトルと説明を入力して、コードの変更内容を説明します。簡潔でありながら、できるだけ具体的に記述します。
- 審査用の pull リクエストを作成するには、[Create Pull Request] をクリックします。
- PR によってトリガーされる Cloud Build トリガーが実行されていることがわかります。
最初のコード変更をフォークしたブランチに正常に push し、マスター ブランチに対して最初の CFT PR を生成しました。
12. 完了
これで、機能を CFT モジュールに追加し、PR を送信して審査を受けることができました。
CFT モジュールに機能を追加し、サンプルを使用してローカルでテストし、コードを GitHub に commit する前にテストを実施しました。最後に、PR によるレビューと最終的な CFT への統合を行いました。
これで、Cloud Foundation Toolkit の使用を開始するための重要な手順について学習しました。