Visual Studio Code にAssumeRoleを利用してTerraform環境を構築してみた

# はじめに
はじめまして、amaebiと申します。
今回は「個人アカウントにTerraform環境を構築してみた」ということで、Terraformの実行環境を構築したことがなかったので、これを機に作ってみようかなと思い本ブログを書いております。
その上で、`AdministratorAccess`権限を付与したIAMユーザーのアクセスキーを発行して使用しても...怖すぎるのでAssumeRoleを利用してTerraform環境を構築します。
自分用の軽いメモ書き程度なので少し見づらかったりしますが、気楽に見ていただけますと幸いです。

# 構成図
![Terraform.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/aab0e320-3f37-2308-c828-308a9d96f1bc.png)

| 名称 | アタッチされているポリシー |
| ---- | ---- |
| TerraformUser | TerraformRole用のインラインポリシー |
| TerraformRole | AdministratorAccess |

※今回のブログでは、IAM Roleに`AdministratorAccess`を付与しておりますが、セキュリティ上、必要最小限の権限を付与してください。

# 手順
- IAMユーザー作成
- インラインポリシー作成
- IAMロール作成
- Terraformインストール、設定
- Visual Studio Codeインストール、設定
- Terraformファイル作成
- 動作確認

### IAMユーザー作成

マネジメントコンソール > IAM > ユーザー からIAMユーザーを作成します。
ユーザー名以外は特に設定せずそのまま作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/f2a1a78b-4e15-ac56-0e2d-6c850dbdc7e4.png)



### インラインポリシー作成

先ほど作成した`TerraformUser`をクリックし、許可タブから許可ポリシーの 許可を追加 > インラインポリシーを作成 を選択します。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/499fbc7a-7998-4cf7-a793-bc90c5d8880f.png)

こちらのポリシーを付与します。
```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": "sts:AssumeRole",
			"Resource": "arn:aws:iam::<AWSアカウントID>:role/TerraformRole"
		}
	]
}
```

ポリシー名を入力し、各項目の設定内容が間違っていないか確認し、問題がなければ作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/10b03d59-c509-6d25-8b9f-94646f451966.png)

その後、Terraformに接続するためのアクセスキーも発行します。
![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/31519cd4-4ec1-37c3-06b3-0541c5248f68.png)

ユースケースを選択し、チェックボックスにチェックして次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/126eddc1-b4f0-addd-f3cf-6c0379d63bd3.png)

アクセスキーを作成し、アクセスキーとシークレットアクセスキーをメモしておきます。
![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/bf24cba5-3c16-ffe5-e5aa-3194290df328.png)


### IAMロール作成

マネジメントコンソール > IAM > ロール からIAMロールを作成します。
信頼されたエンティティタイプをカスタム信頼ポリシーを選択します。
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/4a2e4ebf-e7f4-6e72-6bd0-6761ff91231a.png)

こちらのポリシーを付与して、次へ
※`ExternalId`で指定したIDと一致した場合のみ、AssumeRoleを行うようにします。
```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": {
			    "AWS": "arn:aws:iam::<AWSアカウントID>:user/TerraformUser"
			},
			"Action": "sts:AssumeRole",
   			"Condition": {
			    "StringEquals": {
			        "sts:ExternalId": "<任意の文字列>"
			    }
			}
		}
	]
}
```

必要に応じたポリシーを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/8810c393-3308-0420-eedd-eb1a4f8cfdec.png)

IAMロール名を入力し、各項目の設定内容が間違っていないか確認し、問題がなければ作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/428066c7-fadf-16d9-14c0-68ddca6e7dfb.png)

### Terraformインストール、設定

今回、ローカルPC(Windows)でTerraform環境を構築していきます。
それではまず、Terraformからインストールしていきます。
※公式のインストール方法はこちらです。

https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli

▼まずはじめに、Terraformの公式サイトから最新バージョンをダウンロードします。
https://developer.hashicorp.com/terraform/install#windows

<h3></h3>

ダウンロードしたファイルを`C:\Terraform`配下へ解凍します。
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/3d094556-1028-40a4-c032-d39188510a71.png)

次に環境変数PATHに`C:\Terraform`を追加し、環境変数の永続設定まで行います。
PowerShellを管理者権限で実行します。

![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/35416cfc-9ef5-b86f-0c83-2f9156c73c5f.png)

PowerShellに以下コマンドを入力します。
```powershell
PS C:\xxxx> # 現在の環境変数PATHの設定確認
PS C:\xxxx> $Env:Path
PS C:\xxxx> 
PS C:\xxxx> # 環境変数PATHにパス追加
PS C:\xxxx> $Env:Path += ";C:\Terraform"
PS C:\xxxx> 
PS C:\xxxx> # 環境変数に設定されているか確認
PS C:\xxxx> $Env:Path
PS C:\xxxx> 
PS C:\xxxx> # システム変数PATHの設定確認
PS C:\xxxx> [System.Environment]::GetEnvironmentVariable('PATH' , 'Machine')
PS C:\xxxx>
PS C:\xxxx> # 環境変数の永続設定
PS C:\xxxx> [Environment]::SetEnvironmentVariable('PATH', $Env:Path, 'Machine')
PS C:\xxxx>
PS C:\xxxx> # システム変数に設定されているか確認
PS C:\xxxx> [System.Environment]::GetEnvironmentVariable('PATH' , 'Machine')
PS C:\xxxx>
```

パスが通ったか確認します。
以下のような実行結果が出力されれば成功です。
```powershell
PS C:\xxxx> # パスが通ったか確認する
PS C:\xxxx> terraform -v
Terraform v1.9.2
on windows_amd64
PS C:\xxxx>
```

### Visual Studio Codeインストール、設定

▼Visual Studio Codeの公式サイトから最新バージョンをダウンロードし、セットアップを行います。
https://code.visualstudio.com/

<h3></h3>

Visual Studio Codeを起動し、拡張機能から`Terraform`と検索します。
検索欄から以下の拡張機能が表示されるので、こちらをインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/98512adf-bf8c-686a-e9b7-4ad71c1f70f8.png)

Visual Studio Codeの フォルダを開く から`C:\Terraform`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/4232e41c-4286-1aa4-d52b-951b065c1298.png)

`CTRL + SHIFT + @` でターミナルを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/aca1842d-a33b-e845-04fd-fb24152e7ec6.png)

これで、Visual Studio Codeの設定は完了です。

### 動作確認

実際に`Terraform aplly`を実行して検証環境上にVPCが作成できるか確認していきます。![image7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/137ea433-19ab-7ae1-03a4-5f24631976dd.png)

`C:\Terraform`配下に以下ファイルを作成します。

```terraform:providers.tf
variable "region" {}
variable "access_key" {}
variable "secret_key" {}
variable "role_arn" {}
variable "external_id" {}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region     = var.region
  access_key = var.access_key
  secret_key = var.secret_key

  assume_role {
    session_name = "Terraform"
    role_arn     = var.role_arn
    external_id  = var.external_id
  }
}
```

```terraform:main.tf
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "test-vpc"
  }
}
```

```:terraform.tfvars
region      = "ap-northeast-1"
access_key  = "<アクセスキー>"
secret_key  = "<シークレットアクセスキー>"
role_arn    = "arn:aws:iam::<AWSアカウントID>:role/TerraformRole"
external_id = "<任意の文字列>"
```

それでは、ターミナルからTerraformを実行していきます。
```powershell:terraform init 実行結果
PS C:\Terraform> terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.57.0...
- Installed hashicorp/aws v5.57.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

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.
PS C:\Terraform> 
```
```powershell:terrafrom plan 実行結果
PS C:\Terraform> terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_vpc.vpc will be created
  + resource "aws_vpc" "vpc" {

    省略

    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
PS C:\Terraform> 
```
```powershell:terraform apply 実行結果
PS C:\Terraform> terraform apply 

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:

　省略

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_vpc.vpc: Creating...
aws_vpc.vpc: Creation complete after 2s [id=vpc-0c9a908c5a2ee2de9]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
PS C:\Terraform> 
```

無事applyができたため、VPCが作成された確認します。

作成されていることも確認できました。
![image7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765414/59e97de2-b72f-c7c5-3bd6-97dc823c0f1e.png)




# さいごに
以上、「Visual Studio Code にAssumeRoleを利用してTerraform環境を構築してみた」でした。
HCP Vaultなどを利用すればよりセキュアなTerraform実行環境を構築できると思いますが、とりあえず実行する環境がほしかったのでこのような形になりました(汗)
今後、よりセキュアにしていこうかなと考えていますので、その際にブログを更新します。

# 参考資料
- [VSCodeでのTerraformはじめ](https://qiita.com/garakutayama/items/0cdf43816bde2378f4f9)
- [Terraform用のAWSアクセスキーの権限管理を、スイッチロール形式で最適化する方法](https://blog.mmmcorp.co.jp/2021/01/27/terraform_with_assume_role/)
- [Terraform利用時のアクセスキー管理から脱却！assume_roleを活用して複数環境の管理を楽にする方法](https://staging.techblog.nhn-techorus.com/archives/21329)
- [【AWS】AssumeRoleしてTerraformをより安全に実行する！](https://katsuya-place.com/terraform-assumerole/)