📝

Terraform Cloud入門

2022/12/21に公開

Terraformで環境構築しているとDRYにしたい部分が出てくると思います。
私もprovider周りの記述が重複しDRYにするために現在はTerragruntを使用していましたが
Terraform Cloudでも同じようなことができそうという情報を教えていただいたので今回Cloudの方も触ってみようと思います。
1プロジェクト5人まで無料で使えるとのことです。
※tfファイルは宣言的に記述する言語なのでDRY原則はある程度で良いのかな?というのが個人的な感想です。この辺り詳しい方いたらコメントいただければ嬉しいです。

Terraform Cloudのざっくりイメージ

Terraform Cloudは簡単にいうとネット上にあるサーバでTerraformを実行してAWSなどのリソースを構築するツールになります。
通常はTerraformをPCにインストールするわけです。そうすると一人プロジェクトではいいですが、複数人で同じプロジェクトを管理する際に問題が起こってきます。
Terraformのバージョン違い、tfファイルソースコードの差異・管理(ここはgitを活用し連携)、チームが大きければ権限管理なども必要になります。これらの問題を解決してくれるのがTerraform Cloudになります。

参考サイト

https://cloud.hashicorp.com/products/terraform


以下公式サイトに従って進めていきます。
https://learn.hashicorp.com/collections/terraform/cloud-get-started

Terraform Cloudのアカウント作成

1.以下のアドレスにアクセスします。
https://app.terraform.io/public/signup/account
2.[ユーザー名(任意)][メールアドレス][パスワード(任意)]を決めて入力し[create account]をクリックします。
3.入力したメールアドレスにhashicorpからメールが届きます。(2022年9月時点では〜@hashicorp.comというアドレスから届いていました。)
 中のリンクをクリックするとメールアドレスの確認が完了します。

これでアカウントが作成されました。

※Organization機能はどうやら有料プラン限定の機能のようです。

次に組織を設定します。

organizationの作成

自動的にorganizationの作成画面がでない場合は
コンソール左メニュー

「ユーザーアイコン」

「User Settings」

左メニュー「Organizations」からorganization(組織)を作成します。組織を作ることでチーム開発する際にワークスペース、プライベートモジュール、プロバイダーなどを共有したりできるようになります。無料プランでは最大5名まで組織に入れることができます。

CLIからログイン

前提条件としてローカルPCにインストールされているTerraformCLIのver1.1.0以上、Terraform Cloudアカウントが必要になります。

具体的な手順としては以下となります。
1.「Terraform login」を実行します。
2.プロセスを進めてよろしいでしょうか?と聞かれるので「yes」と入力します。
3.Terraform Cloudでトークンを作成します。ブラウザが自動的に開いた場合はDescriptionにこのトークンが何に使われているか後から見たときにわかりやすい名前をつけて「Create Token」を押します。
※出てこない場合はTerraform Cloudコンソール画面からユーザーアイコンをクリック → User Setting → Tokens → Create Tokenをクリックします。
4.Tokenが表示されたらコピーします。
5.ローカルのTerraform CLIに戻るとトークンの入力を求められているので上記で生成したトークンをペーストしてreturnキーを押します。Welcome to Terraform Cloud!と表示されたら成功です。

ここまでできたらローカルとTerraformの連携が完了しています。

環境変数の設定

tfファイル中に何度も同じ値を記述したりセキュリティに関わる認証情報を記述したくなる場面があると思います。これらを共有したり、安全に管理したりする際に便利なのが入力変数と環境変数です。環境変数はTerraform Cloud内の安全な場所に値を格納しておくことができ、CLIから認証することで格納した値を呼び出して使うことができます。

入力変数は構成で参照する値の変数、環境変数はプロバイダの資格情報やログの詳細度などに使われます。
実際に変数セットを作成してみましょう。

1.Terraform Cloudコンソール画面から

Terraformのロゴをクリック

左メニューの「Settings」をクリック

左メニュー「Variable sets」をクリックして「Create variable set」をクリックします。
2.ここではAWSの認証情報を入れるのでNameにAWS Credentialsと名前をつけます。必要であればDescriptionに後からわかるように説明を書いておくのも良いと思います。
WorkSpaceのセレクトボタンはこの変数のスコープをどう設定するかというものです。ここではテストとしてスコープの一番広い全てのワークスペースとオーガナイゼーションに適用するを選択していますが、プロジェクトで使用する際はワークスペースを最小限に絞って設定するのが推奨されています。
3.ここではAWSのアクセスキーとシークレットアクセスキーを設定してみます。
Keyにはわかりやすく「AWS_ACCESS_KEY_ID」「AWS_SECRET_ACCESS_KEY」とし、値はAWSコンソールのIAM設定から持ってきて入力します。

これでAWSの認証情報がTerraform上に登録できましたのでtfファイルのコードの中から情報を安全に読み取って使うことができます。

今回はスコープがグローバルで全てのワークスペースから利用できるグローバル変数セットを作成しました。変数セットの詳細については以下をご参照ください。
https://developer.hashicorp.com/terraform/cloud-docs/workspaces/variables

workflowの作成

ここでの作業を進めるために前提条件として
・Terraform Cloudのアカウントと組織
・TerraformCLI(コマンド)のインストールとTerraform Cloudのトークンでの設定
・AWSアカウント
・GitHubアカウント
が必要になります。

1.Terraformが公式で用意してくれているチュートリアル用のリポジトリをローカルにクローンします。


$ git clone https://github.com/hashicorp/learn-terraform-cloud.git
$ cd learn-terraform-cloud
$ ls -la

色々なファイルがダウンロードされているのがわかると思います。
terraformを触ったことがあればお馴染みのファイル群ですがterraform.tfはTerraform Cloud統合のブロックを定義するとのことです。

2.組織名の更新
早速ファイルを編集していきましょう。まずは簡単なところから組織名を変更してみます。前述の項目で作成した組織名をTerraform Cloudコンソールで確認してみましょう。確認ができたらterraform.tfの以下の部分を探して自分で設定した組織名に変更して保存します。


cloud {
    organization = "organization-name"

3.ワークスペースを作成
前述の2で編集したcloudというブロックはこのディレクトリから操作するTerraform Cloudの組織とワークスペースを指定しています。

次に以下のコマンドを実行します。


$ terraform init

terraform loginでTerraform Cloudと連携が取れている状態で上記のようにinitすることで指定した組織内に新たにワークスペースが生成されます。

Terrafrom Cloudコンソールから確認して「learn-terraform-cloud」というワークスペースができていたら成功です。

※M1Macを使用していると以下のようなエラーが出ます。

Provider registry.terraform.io/hashicorp/aws v3.28.0 does not have a package available for your current platform, darwin_arm64.

これはTerraformのawsのソースver3.28.0だとM1のAppleシリコンCPUに対応していませんというものなので以下のようにterraform.tfでバージョンを上げてあげます。

aws = {
      source  = "hashicorp/aws"
      version = "~> 3.33.0"
    }

調査したところ33からM1にも対応したとのことなので上記のように設定しました。
設定したら以下のようにオプションを追加してinitを実行します。

$ terraform init -upgrade

Terraform Cloud has been successfully initialized!と表示されTerrafrom Cloudコンソールから確認して「learn-terraform-cloud」というワークスペースができていたら成功です。

4.変数セットをワークスペースに割り当てましょう。
Terraform Cloudのコンソールから左上のTerraformのロゴをクリック → 左メニューのWorkspacesをクリックしてWORKSPACE NAMEのリンクをクリックするとワークスペースの画面を開きます。すると左メニューに「Variables」という項目があるのでクリックします。画面内最下部に(執筆時)「Apply variable set」というボタンがあるのでクリックします。

ここで以下のエラーが出た方は既に変数セットがワークスペースに割り当てられているのかもしれません。


No variable sets available
All variable sets have been applied to this workspace, or there are none available.
Variable sets are groupings of variables that you can apply to multiple workspaces.

「コンソール左上のアイコン」をクリック → 「WORKSPACE NAME」 → 左メニューの「Variables」をクリックし
Variable sets(1)となっていれば変数セットは登録されています。

インフラストラクチャの作成

変数の登録

ここではワークスペース固有の変数を設定していきます。
「コンソール左上のアイコン」をクリック → 「WORKSPACE NAME」 → 左メニューの「Variables」をクリックし
Workspace variablesというセクションの「Add variable」というボタンをクリックします。
そしてkeyに「instance_type」、valueに「t2.micro」と入力し保存します。
これで一つの変数が登録できました。
さらにもう一つ変数を登録します。
keyに「instance_name」valueに「Provisioned by Terraform」を入力し保存します。
これで準備が整いました。

EC2の立ち上げ

ローカルPCのターミナルに戻り以下のコマンドを実行します。

$ terraform apply

自分の環境では以下のエラーが出ました。

aws.Config.CredentialsChainVerboseErrors

原因はTerraform Cloudに登録した変数のkeyが違っていました。
aws_access_key_id → AWS_ACCESS_KEY_ID
aws_secret_access_key → AWS_SECRET_ACCESS_KEY
ここは値が決まっているようなので注意しましょう。

インフラストラクチャの変更

前の手順で起動したEC2のインスタンスタイプを変更してみたいと思います。

ローカルPCのターミナルで以下のコマンドを実行することでインスタンスタイプが変わると思います。

$ terraform apply -var="instance_type=t3.nano"

AWSコンソールから確認してEC2のインスタンスタイプがt3.nanoに変わっていたら成功です。

バージョン管理システムを使ったワークフロー

GitHub、GitBucketなどのバージョン管理システムサイトを使用して共有リポジトリでマージしたタイミングでAWSなどの本番にも適用させるといった流れのワークフローを組むこともできます。

GitHubで新しいリポジトリを作成します

ここでは簡単に解説させていただきます。
GitHubで「new」ボタンを押して新しいリポジトリを作成します。
設定はほぼデフォルトで問題ないと思いますが念の為プライベートリポジトリで作成した方が安心だと思います。
リポジトリが作成できたらアドレスが表示されますのでHTTPSの方をコピーします。
これでGitHub上にリモートリポジトリが作成できました。

次にローカルPCのターミナルを開き前の手順でクローンしてきたローカルリポジトリ(フォルダ)を開きます。
このローカルリポジトリのリモートとして先ほど作成したリモートリポジトリを設定します。

$ git remote -v
$ git remote set-url origin コピーしたHTTPSのアドレス
$ git remote -v

git remote -vの結果が自分のリポジトリになっていたら成功です。

次にファイルを編集して保存します。
terraform.tfを開いてcloudブロックをコメントアウトします。


/*
cloud {
   organization = "organization-name"

   workspaces {
     name = "learn-terraform-cloud"
   }
}
*/

ファイルを保存したらgitでも記録します。

$ git add .
$ git commit -m "Remove cloud block"
$ git push

ここでエラーが出た方は認証がうまく行っていないかもしれませんので
Tokenを作成しパスワードの代わりに使用すると認証できるかもしれません。
GitHubでHTTPSを使った認証
※パスワードでの認証は廃止されたのでHTTPSで認証するには現在トークンを作成する必要があります。

これでリモートリポジトリにterraform.tfの変更を送信できました。

TerraformCloudの設定を有効にする

Terraform Cloudのコンソールから「Workspace Settings」→「Version Control」を選択します。
「Connect to version control」というボタンを押します。
「Github」のボタンを押します。
ここでブラウザのポップアップ防止機能が働いてエラーが出る場合がありますので適宜対応してみてください。
次の画面が開いたら「Authorize Terraform Cloud by HashiCorp」という緑のボタンを押します。

GitHubの画面に飛び、Terraform Cloudをインストールするように求められる場合があります。求められたらアカウントまたは組織を選びます。

次にリポジトリを選ぶ画面が表示されるので「learn-terraform-cloud」を選びます。
「Automatic speculative plans」にチェックを入れて「Update VCS settings」をクリックします。

実行を破棄

Terraform CloudのコンソールでWorkspaceを開き左メニューから「Runs」を開きます。
すると「Remove cloud block」(ローカルで入力したコミットメッセージ)の名前でジョブが走っていますのでこれを破棄します。
「Apply pending」という文字のところをクリックすると詳細が開きます。その中に「Discard Run」というボタンがあるのでクリックします。

次に左メニューから「Variables」をクリックしてWorkspace variablesにあるinstance_typeの項目にある「・・・」をクリックし「Delete」をクリックします。

ローカルでインスタンスタイプを設定してGitHubへプッシュ

ローカルリポジトリ内のルートディレクトリに「terraform.auto.tfvars」というファイルを作成し以下の内容を記述して保存します。

instance_type = "t2.micro"

先ほどTerraform Cloud上で削除したインスタンスタイプをローカルで指定しています。
保存が完了したらGitに登録します。

$ git checkout -b use_auto_vars_file
$ git add .
$ git commit -m "Add auto.tfvars file"
$ git push -u origin use_auto_vars_file

ここまで完了するとGitHub上に「use_auto_vars_file」というブランチが生成されます。

GitHubを開いてuse_auto_vars_fileブランチを開き「Create pull request」をクリックします。
少し待つと「Details」という小さいリンクが表示されますのでクリックします。
するとTerraform Cloudのコンソール画面が開いてジョブの確認ができます。

ジョブでPlan finishedと表示されているのを確認したらGitHubのコンソールに戻ってプルリクエストをマージします。

またTerraform Cloudのコンソール画面を開いて「Apply pending」をクリックすると詳細が表示され「Confirm & Apply」というボタンが表示されるのでクリックします。

※ここで詳細が表示されなかったり「Confirm & Apply」というボタンが表示されなかったりした場合実行途中のジョブがある可能性があります。Terraform cloudのコンソールからRunsのページを開き実行中のジョブを適宜破棄するなり完了してから再度お試しください。

ここまで完了できたらAWS上のEC2のインスタンスタイプがt2.microに変わっていると思います。
GitHubのメインブランチにマージしたタイミングで自動的にデプロイができるようになりました。

リソースとワークスペースの破棄

ここまで作成したリソースとワークスペースを破棄します。破棄はTerraform Cloudのコンソール画面から行います。テラフォームクラウドコンソールからワークスペースの画面に移動します。そこで左メニューに「Destruction and Deletion」というメニューがあるのでクリックします。すると2つのボタンが表示されます。
「Queue destroy plan」はワークスペースによって管理されているすべてのインフラストラクチャを破棄します。
「Delete from Terraform Cloud」はワークスペースが管理しているインフラストラクチャはそのままにTerraform Cloudからワークスペースを削除します。
※ワークスペースを削除してもAWSなどのクラウド上にはEC2などのリソースがまだ残ったままになります。クラウド上のリソースも忘れないように削除しましょう。

Queue destroy plan

ここではクラウド上のリソースも含めて破棄する手順を進めてみます。
「Queue destroy plan」をクリックします。
「ワークスペース名を入力」します。
「Plan finished」の内容を確認します。
「Apply pending」をクリックして開くとボタンが3つ出てくるので「Confirm & Apply」を押して実行するとTerraform Cloudのワークスペースとクラウド上のリソースが破棄できます。
クラウド上のコンソールを確認してリソースが破棄されていれば完了です。

Delete Workspace

Terraform Cloud上のワークスペースを削除します。
「Delete from workspace」ボタンをクリックします。
ワークスペースの名前を入力して「Delete workspace」ボタンをクリックします。
これでTerraform Cloudのワークスペースを削除できました。

所感

ここまでできると基本的なワークフローがTerraform Cloudでできるようになったと思います。
Terraform Cloudを触るきっかけとなったのは「環境変数が使える」「チーム開発する際に便利そう」というものでしたがまさにその2点で非常に手軽に安心感を持つことができました。

Discussion