第0回：AWSのWebアプリ環境を生成AIを使ってterraformを書いてみた、基礎構築

## 狙い：目的
Webアプリケーションを作成する上で、結構めんどくさいのがインフラ周り。Webアプリの勉強をしているのに、インフラの勉強もしないとダメってのも、キツイ。

そこで、今回は生成AIのGoogle Geminiを使ってコーディングを楽にしながら、Webアプリ環境をよしなに作ってくれるterraform環境を構築していく。

主に、生成AIを使うことで
- どの程度のスクリプトでよしなに書いてくれるのか
- どの程度会話を続けたら、良い感じになっていくのか
- 出力されたスクリプトは手直しなしで動くのか

あたりを検証していきたいと思う。

## 作りたいアプリの環境

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/710930e1-d3d2-fdd6-c63a-6a71318960c4.png)

## 第0回の目標
今回は生成AIにterraformを作ってもらう前の話。主に環境構築をしていきます。


## とりあえず基本的な環境構築(terragrunt)

Dockerでterraformやterragruntのバージョンを気にしないような環境を作る。とりあえずDockerとdocker-composeだけ入れてもらえれば、それっぽく動きます。

Dockerやdocker-composeのインストールに関しては、このあたりを参考にしてください。

https://qiita.com/kujiraza/items/a8236f65e2c46735ee91
https://qiita.com/tomokei5634/items/7b1e7a121d5d7bc12116

```:Dockrfile
FROM amazon/aws-cli:2.16.8

RUN yum update -y
RUN yum install -y unzip jq tar gzip curl
RUN curl  -OL https://releases.hashicorp.com/terraform/1.8.5/terraform_1.8.5_linux_amd64.zip
RUN unzip terraform_1.8.5_linux_amd64.zip -d /bin
RUN curl -L "https://github.com/gruntwork-io/terragrunt/releases/download/v0.59.3/terragrunt_linux_amd64" -o /usr/local/bin/terragrunt \
    && chmod +x /usr/local/bin/terragrunt
ENV HISTFILE=/terraform/.bash_history
ENTRYPOINT ["/bin/bash"]
```

```:docker-compose.yml
version: '3.8'
services:
  terragrunt:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./:/terraform
      - ./.aws:/root/.aws
    working_dir: /terraform/environments
    entrypoint: /bin/bash
```

## ファイル構成
terragruntで環境を複数複製出来るように、以下の様な構成にしておく。

```
.
├── Dockerfile
├── docker-compose.yml
├── .gitignore
├── enviroments
│   ├── staging
│   │   ├── network
│   │   │   └── terragrunt.hcl
│   │   └── terragrunt.hcl
│   └── prod
|        |※以下省略
└── modules
    ├── network
    │   ├── main.tf #このあたりを生成AIを使って書いていく
    │   ├── outputs.tf
    │   └── variables.tf　※必要に応じて
```

## terragruntの基本ファイル
terragruntの基本ファイルに、リモート(S3)のstateファイルの設定などを書いておく。別環境や、他の人がterraformを触ることがあっても、不整合が起きないようにしておくことが出来る。ココは、お作法というか、派閥も分かれる箇所で、エイヤでコピペしてもらったほうが良いと思う。

```:enviroments/staging/terragrunt.hcl
remote_state {
  backend = "s3"
  config = {
    bucket         = "gemini-terraform-staging-terraform-state"
    key            = "${path_relative_to_include()}/terraform.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true
    dynamodb_table = "gemini-terraform-staging-terraform-state-lock-table"
  }
  generate = {
    path      = "_backend.tf"
    if_exists = "overwrite_terragrunt"
  }
}

generate "provider" {
  path = "_provider.tf"
  if_exists = "overwrite_terragrunt"
  contents = <<EOF
terraform {
  required_version = "1.8.5"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.53.0"
    }
  }
}
provider "aws" {
  region = "ap-northeast-1"
}
EOF
}


locals {
  ## 共通で使いたい物などを記載
}

terraform {
  extra_arguments "retry_lock" {
    commands = get_terraform_commands_that_need_locking()
    arguments = ["-lock-timeout=20m"]
  }

  

  extra_arguments "custom_vars" {
    commands = [
      "apply",
      "plan",
      "import",
      "push",
      "destroy",
      "refresh"
    ]

    env_vars = {
      TF_VAR_app_name = "gemini-terraform"
      TF_VAR_env = "staging"
    }
  }
}
```

このterragrunt.hclを使うには、勝手に生成される以下のファイルの.gitignoreを設定しておく

```: .gitignore
.terraform
.envrc
_provider.tf
_backend.tf
.terraform.lock.hcl
.terragrunt-cache
```

## 次回
実際にGoogle Geminiでterraformを書いていく。