Terraform RegistryにModuleを公開した

## 概要
Terraform公式の [Terraform Registry](https://registry.terraform.io/)に Moduleを公開しました。その手順を解説します。

## Terraform Registry とは
Terraformのモジュールを公開できるサービスです。
<img width="1439" alt="スクリーンショット 2020-04-15 1.05.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206741/056eda7a-42e4-2728-20f6-e65241d3a796.png">

登録されているモジュールは利用することができ、自分でモジュールを用意しなくてもいいので便利です。
Terraformの開発元であるHashiCorp社が作成したモジュール等も公開されており、自分でモジュールを作成する際にも参考になります。

## 公開したModule
AWS VPCを構築するモジュールです。
https://registry.terraform.io/modules/nekochans/vpc/aws/1.0.1

[nekochans](https://github.com/nekochans)というGitHub Organizationで@keitaknと個人開発を進めています。新しくAWS環境を構築することが多く、毎回モジュールを作成することが手間となっていました。
開発効率をあげるために、AWS環境構築には必須となるリソースをモジュールとして公開ししました。
また少しでも料金を下げるためにNAT GatewayではなくNAT Instanceを利用しています。

GitHubのソースコードはこちらです。
https://github.com/nekochans/terraform-aws-vpc

## 必須条件
モジュールを公開するためには、いくつかの条件があります。
詳細はこちらをご確認ください。
https://www.terraform.io/docs/registry/modules/publish.html

- GitHubの公開リポジトリで管理されていること
- リポジトリ名が`terraform-<PROVIDER>-<NAME>`という形式で命名されていること
- GitHubリポジトリのdescriptionが設定されていること
- 構成が[Standard Module Structure](https://www.terraform.io/docs/registry/modules/publish.html)に従っていること
- セマンティックバージョンに従ったタグがついていること

## 公開手順

### GitHubリポジトリを作成

リポジトリの命名規則に従って公開リポジトリを作成します。

命名規則： `terraform-<PROVIDER>-<NAME>`

`PROVIDER`はリソースを構築する対象のプロバイダーを指定します。(aws,googleなど)
`NAME`はモジュールで管理する対象を指定します。

今回はAWSにVPCを構築するモジュールを作成するので、 `terraform-aws-vpc`とします。

リポジトリのdescriptionにはモジュールの説明を記載します。
`Terraform module to create VPC resource with Nat Instance on AWS.`

### Moduleの作成
[Standard Module Structure](https://www.terraform.io/docs/registry/modules/publish.html)に従いモジュールを作成します。

今回は下記のディレクトリ構成にしました。

```
├── examples
│   └── complete
│       ├── README.md
│       ├── main.tf
│       └── outputs.tf
├── LICENSE
├── README.md
├── main.tf
├── outputs.tf
├── variables.tf
├── versions.tf
└── vpc_flow_log.tf
```

#### main.tf, variables.tf, outputs.tf

最低限、下記のファイルが必要です。

main.tf: エントリポイント
variables.tf： 入力値を定義
outputs.tf： 出力値を定義

variables.tf, outputs.tfではdescriptionを定義する必要があります。


```variables.tf
variable "name" {
  description = "Name to be used on all the resources as identifier"
  type        = string
  default     = ""
}
```

```outputs.tf
output "vpc_id" {
  value       = aws_vpc.this.id
  description = "The ID of the VPC"
}
```

ネストしたモジュールを定義する場合は`modules`ディレクトリに配置する必要があります。
今回は複雑ではないモジュールのため`modules`ディレクトリは利用していません。

#### README.md
こちらの内容がTerraform Registryのreadmeとして公開されます。

`README`または`README.md`という名前で作成します。
モジュールでどのようなリソースが作成されるか、使用例などを記載します。

READMEの下記については[terraform-docs](https://github.com/segmentio/terraform-docs)
を利用して自動生成しました。簡単にREADMEを生成できるのでおすすめです。

- Requirements
- Providers
- Inputs
- Outputs

#### examples
モジュールの利用例を作成します。こちらで作成した内容もTerraform Registryにも表示されます。

<img width="917" alt="スクリーンショット 2020-04-15 0.41.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206741/8b16ec9b-79dc-00b1-4eec-f7c8a7de6f95.png">

#### LICENSE
ライセンスファイルを作成します。

### タグの追加
セマンティックバージョンに従ったリリースタグをつけます。
prefixに`v`をつけることも可能です。`1.0.0`や`v1.0.0`の形式でタグを追加します。

```bash
git tag -a v1.0.0 -m "release version v1.0.0"
git push origin tags/v1.0.0
```

### Terraform Registryへの公開
GitHubアカウントでSign-inします。Organizationのリポジトリを公開する場合は、「Grant」を選択して権限を追加する必要があります。
Publishから対象のリポジトリを選択することでモジュールの公開が完了します。
<img width="1438" alt="スクリーンショット 2020-04-15 0.48.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206741/41b9b16c-aa54-30f8-87cb-12ed16c4eb1f.png">

### Moduleの利用
公開されたモジュールは、`<NAMESPACE>/<NAME>/<PROVIDER>`の形式で指定することによって利用できます。
今回作成したモジュールの利用例です。

```tf
module "vpc" {
  source = "nekochans/vpc/aws"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  nat_instance_ami         = "ami-0af1df87db7b650f4"
  nat_instance_type        = "t2.micro"
  nat_instance_volume_type = "gp2"
  nat_instance_volume_size = "30"

  azs             = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
  private_subnets = ["10.10.0.0/24", "10.10.1.0/24", "10.10.2.0/24"]
  public_subnets  = ["10.10.10.0/24", "10.10.11.0/24", "10.10.12.0/24"]
}
```

### 最後に
思ったよりも簡単にTerraform Registryへ公開できました。
これで今後の個人開発もスムーズに進められそうです。

最後まで読んで頂きありがとうございました。