Terraformで構築したSSM(パラメータストアー)をTerraformで管理している他のリソース(RDS、ECS等の)に適用する方法

# 前書き
機密情報を`AWS Systems Manager Parameter Store`に格納している為、その値をRDSやECS等のサービスに設定として反映させる必要があります。今回は、`Terraform`で管理しているリソースに対し、`Parameter Store`に保存された値を読み込み、反映する手順を記載します。

# AWS Systems Manager(パラメータストア)の概要
アプリケーションの設定データや機密情報(例：パスワード、データベース接続情報、APIキー等)を安全に保存・管理する為のサービス。設定情報をアプリケーション本体とは別で管理する事で、セキュリティを強化し、運用の効率化が図れる

##  主な機能
- 機密情報を安全に管理：パスワードやAPIキー等の重要な情報を暗号化して保存し、不正アクセスを防ぐ
- 設定データをアプリケーションと分離：アプリケーション本体から設定データを切り離し、必要な情報を安全な場所に一元管理する
- 階層構造とバージョンで管理：設定データを階層毎に整理し、バージョン履歴を追跡して過去の変更内容も確認出来る
- アクセス権の制御と利用状況の監査：`IAM`でアクセス権を細かく制御し、監査ログで誰がどの情報にアクセスしたかを記録する
- AWSサービスと連携：`Lambda`や`EC2`などの`AWS`サービスと簡単に連携し、設定情報を必要な時に安全に活用出来るにする

# 前提条件
- `Terraform`をインストールしている
- [aws provider](https://registry.terraform.io/providers/hashicorp/aws/latest)関連の構築が完了している

# 構築手順
- 今回は、DBの機密情報を使用して構築を行う
- `rds.tf`のファイルは、必要最低限の記載に留めている

## ディレクトリ構成
- ディレクトリ構成は、下記の構築で行なっております
```sh
.
├── .terraform/
│   └── # terraformに必要なファイル、ディレクトリが自動生成される
├── .terraform.lock.hcl　# 自動生成
├── .gitignore
├── providers.tf
├── variables.tf
├── terraform.tfvars
├── main.tf
└── modules/
    ├── ssm/
    │   ├── ssm.tf
    │   ├── variables.tf
    │   └── output.tf
    └── rds/
        ├── rds.tf
        ├── variables.tf
        └── output.tf
```

## 各リソースの構築
### 基礎設定：機密情報のSSM保存とRDSへの適用
- DBの機密情報を設置
```terraform.tfvars
database_name = ************
username      = ************
password      = ************
```

```variables.tf
variable "database_name" { type = string }
variable "username" { type = string }
variable "password" { type = string }
```

- `SSM`モジュールで保存した機密情報を`RDS`モジュールに渡して、尚且つ`RDS`の設定に反映する為の設定
```main.tf
# SSM(パラメーターストア)
module "ssm" {
  source = "../../modules/ssm/"
  
  database_name = var.database_name
  username      = var.username
  password      = var.password
}

# RDS
module "rds" {
  source = "../../modules/rds"
  
  database_name = module.ssm.database_name
  username      = module.ssm.username
  password      = module.ssm.password
}
```

### SSM(パラメータストアー)の構築
- `data`を使用する事で、パラメータストアーに設定した値を取得する事が可能
```ssm.tf
# パラメータストアーに保存した機密情報を取得
data "aws_ssm_parameter" "database_name" {
  name = "DATABASE_NAME"
}

data "aws_ssm_parameter" "username" {
  name = "USERNAME"
}

data "aws_ssm_parameter" "password" {
  name = "PASSWORD"
}

# パラメータストアーに機密情報を登録
resource "aws_ssm_parameter" "database_name" {
  name  = "DATABASE_NAME"
  type  = "String" 
  value = var.aurora_database_name
}

resource "aws_ssm_parameter" "username" {
  name  = "USERNAME"
  type  = "String"
  value = var.aurora_username
}

resource "aws_ssm_parameter" "password" {
  name  = "PASSWORD"
  type  = "String"
  value = var.aurora_password
}
```

| メソッド | 説明 |
| :-: | - |
| name | SSMパラメータの名前を設定する |
| type | パラメータのデータタイプを指定する。他にも`SecureString`(暗号化された文字列)や`StringList`(カンマ区切りのリスト)等のオプションがある |
| value | パラメータに保存する実際の値を設定する |


```variables.tf
variable "database_name" { type = string }
variable "username" { type = string }
variable "password" { type = string }
```

```outputs.tf
output "database_name" {
  value = data.aws_ssm_parameter.database_name.value
}

output "username" {
  value = data.aws_ssm_parameter.username.value
}

output "password" {
  value = data.aws_ssm_parameter.password.value
}
```

| メソッド | 説明 |
| :-: | - |
| output | 他のモジュールやコマンドラインに値を出力する為に使用する |

### RDSの構築
- 省略して記載している
```rds.tf
resource "aws_rds_cluster" "rds" {
  cluster_identifier = "test_db"
  # 省略
  
  database_name   = var.database_name
  master_username = var.username
  master_password = var.password

  # 省略
}
```

```variables.tf
variable "database_name" { type = string }
variable "username" { type = string }
variable "password" { type = string }
```


# 参考資料
- [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html)
- [[公式 hashicorp] Resource: aws_ssm_parameter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter)
- [[公式 hashicorp] Data Source: aws_ssm_parameter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter)
- [Terraformでssm parameterを管理するのを試す](https://cross-black777.hatenablog.com/entry/2017/09/12/013713)

# まとめ
今回は、`Terraform`で`SSM`（パラメータストア）の値をどのように反映させるかについて記載しました。実装は意外と簡単にできましたが、セキュアな構築は重要である為、今後も更にセキュリティを強化した`Terraform`環境を構築していきたいと思います。