TerraformでAWS入門したら理解が深まった（学び編）

# 概要
先日開催した[初心者LT会](https://qiita.com/newrice_misosoup/items/8fa0630b075a66f73974)でのLTの内容を記事にしました。

初めてTerraformを使ってAWSのリソースを作成した際のつまづきや気づきをまとめているので、参考になればと思います。

# 経歴
- IT未経験新卒１年目
- 自分でAWSのリソースを作成するのは初めて
- Terraformは業務で少し触れた程度

# 対象
- Terraform初心者・これから触れてみたい方
- AWS初心者・これから触れてみたい方
- 駆け出しエンジニア


# Iac・Terraformとは
### Infrastructure as Code (IaC)とは
>手動のプロセスや設定の代わりにコードを使用してコンピューティングインフラストラクチャをプロビジョニングおよびサポートできること

つまり、インフラリソースをコードで管理しようという概念です。インフラをコードで管理して何が嬉しいのかというと、

- 環境・リソースをテンプレート化して複製しやすい
- 設定値をコード管理可能（一時的な設定値変更などの後に元の値なんだっけ？となりづらい）
- 作成するリソースのレビューが可能（コンソールでのリソース作成と違い、適用前にレビューをすることができる）

などコンソール上でのリソース作成・管理に比べて手間やミスを減らせる仕組みになっています。

参考: https://aws.amazon.com/jp/what-is/iac/


### Terraformとは
HashiCorp社が作成したインフラストラクチャをコードとして定義するツール。HashiCorp Configuration Language (HCL)といういわゆる宣言型の言語を使用して構成ファイルを記述する。

Terraformでコードを書いたら、以下のTerraformコマンドを実行してApplyするとリソースが作成されるという仕組みです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931956/14ac9c77-0346-4728-b18d-484651cfbf41.png)

参考: https://qiita.com/souhei-etou/items/7876767f041543321006


## 今回のゴール
Terraformを使用して、VPCとパブリックサブネットを作成。
サブネットの中にEC2インスタンスを置いてGoogleに疎通ができる状態にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931956/dc741d38-afe6-49e6-8524-c121b3934712.png)


作成したEC2インスタンスにssh接続をして、GoogleへのCurlコマンドを打つと疎通が確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931956/46516f44-eb97-4258-a866-49123401f63b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931956/e0785687-977a-4323-bcdf-1c43c2e1d9fe.png)


以下ではこのリソースを作成するまでにつまづいた点や理解が深まった点を紹介します。

参考:https://zenn.dev/ochi_shoichi/scraps/1e224c1501cc29

## 学び①　VPC・サブネット作成とCIDR

始めにVPCとサブネットを作成したのですが、TerraformをApplyした際にサブネットのCIDRはVPCのサブネットのCIDRの範囲内に収まらなければならないというエラーが出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931956/20c7d0b3-73b5-4449-94ab-ad0a1f14a6aa.png)

VPCのCIDRブロックでVPC内で使用するIPアドレスの範囲を決めており、VPCの中にあるサブネットなどにその範囲内でプライベートIPを付与してサブネット間で通信したりするので、サブネットのCIDRブロックはVPCのCIDRブロック内に収めなければならないということでした。

SAAや基本情報の勉強をしていたためCIDRの概念や、VPCの中にサブネットがあるということはそれぞれでは理解していたのですが、いざリソースを作成してこのようなエラーに遭遇したことでこういうことだったのねと、理解が深まりました。





**設定していたCIDRと修正後のCIDRは以下**
|            | 修正前 | 修正後 |
|------------|--------|--------|
| VPC        |   10.1.0.0/24<br> (10.1.0.1～ 10.1.0.254)    |   10.1.0.0/24
| サブネット |10.0.1.0/24 <br>( **10.0.1.1～10.0.1.254**) |10.1.0.0/24 |


## 学び② SCPとIAMポリシーの関係
VPCとサブネットが作成できたのでEC2インスタンスを作成するコードを記述してTerraformをApplyしたのですが、以下のようなエラーが出ました。

今回使用していたIAMユーザーにはあまりよくないのですが、勉強用の環境だったのでAdministratorAccessポリシーをアタッチしていたため、なんでEC2インスタンスが作成できないのだろう？と思ったのですが、
組織で**DenyUnencryptedEC2Volume**というSCPが設定されており、今回作成しようとしていたインスタンスにアタッチするEBSボリュームが暗号化されていなかったことが原因でした。
（会社のAWS勉強用のアカウントを利用していたのでSCPが設定されていました。）

```
Error: creating EC2 Instance:　　 ～　　is not authorized to
perform:ec2:RunInstances on resource: arn:aws:ec2:ap-northeast-xxxxxxx:volume/*
with an explicit deny in a service control policy. Encoded authorization failure message:
```

```
"DecodedMessage": {
    "allowed": false,
    "explicitDeny": true,
    "matchedStatements": {
      "items": [
        {
          "statementId": "DenyUnencryptedEC2Volume",
          "effect": "DENY",
```

SCPもSAAの勉強をする中で出てきていた機能で、そんなものがあるんだ～くらいの理解だったのですが、IAMでアクションを許可していてもSCPで禁止されていることは実行できないのだということを身をもって学びました。

## まとめ
Terraformの使用とは逸れてしまっているかもしれないのですが、実際にTerraformでコードを書いてリソースを作成してみると資格勉強では実感できない学びを得ることができ、先人たちがハンズオンは大事だ！と言っていることの意味が分かりました。

今回Terraformコードの内容は詳しく記述しなかったのですが、ドキュメントを見ながらコードを書く中でリソース同士の依存関係や設定に必要な項目を一目で理解することができたので、はTerraform・AWS初心者の方こそ一歩踏み入れてTerraformでリソースを作成してみるのがおすすめです！