Github ActionsでTerraform(tflocal)実装のAWS Localstack環境構築（１）

### 背景
パブリッククラウドの構築でIaCを用いたTerraform実装を行う際、テストや開発段階でAWSリソースを利用することにより場合によってはコストがかかる場合があります。
一方、LocalStackはAWSのリソースをローカル環境でエミュレーションできるため、料金を気にすることなくテストを行うことが可能です。

### 目的
GitHub ActionsのCI/CDパイプラインを利用し、LocalStackを使用したAWSリソースをTerraformで構築し、インフラのデプロイやコーディングの検証を行います。

### 内容
GitHub Actionsのワークフロー内で、Terraformを使用してLocalStack環境にAWSリソース（例: VPC、EC2、S3バケット、API Gateway、Lambda）を作成します。
ワークフローでエラーが発生した場合、原因調査し、コードの修正とワークフローの再実行を行います。

### 前提条件
必要最低限のリソースを作成します。AWSの仕様や必須設定については考慮はせず、単純に作成ができることをまず目的としています。
※細かいパラメータ設定・妥当性確認については次章で記載予定。

#### 構築内容
**１．Terraformモジュールの準備**  
   AWSリソース（S3、API Gateway、Lambda、Auroraなど）を定義したTerraformファイルを作成します。量が多いので、割愛しますが、
構成は環境によってさまざまかと思いますが、
今回は、再利用性や保守性を意識するため、リソースごとにモジュール化し、
ルートディレクトリ、modulesディレクトリ、variables.tfに持たせ、デフォルト値を入れる設定とします。
（※lambdaのファイルだけディレクトリを間違えたので後ほど修正します。）
下記参照頂ければと思います。
   https://github.com/t-kyn-git/t_kyn_bish_the_test/tree/main/terraform
```bash
│  main.tf
│  provider.tf
│  variables.tf
│
├─lambda
│      index.js
│      lambda_function_payload.zip
│
└─modules
   ├─apigateway
   │      main.tf
   │      outputs.tf
   │      variables.tf
   │
   ├─cloudwatch
   │      main.tf
   │      outputs.tf
   │      variables.tf
   │
   ├─ec2
   │      main.tf
   │      outputs.tf
   │      variables.tf
   │
   ├─lambda
   │      main.tf
   │      outputs.tf
   │      variables.tf
   │
   ├─network
   │      main.tf
   │      outputs.tf
   │      variables.tf
   │
   ├─route53
   │      main.tf
   │      outputs.tf
   │      variables.tf
   │
   ├─s3
   │      main.tf
   │      outputs.tf
   │      variables.tf
   │
   ├─securitygroup
   │      main.tf
   │      outputs.tf
   │      variables.tf
   │
   └─vpc
           main.tf
           outputs.tf
           variables.tf
```

   
**２．GitHub Actionsの設定**  
   以下のステップを含むワークフローを設定します
   TFLocal CLIのインストールおよび、tflocalでの初期化・適用を行います。
```
name: TFLocal Workflow

on: [push]

jobs:
  terraform-local:
    runs-on: ubuntu-latest
    services:
      docker:
        image: docker:19.03.12  # 互換性のある Docker バージョンを指定
        options: --privileged    # Docker コンテナ内で Docker を実行するためのオプション

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up LocalStack
      run: |
        docker run --rm -d -p 4566:4566 -p 4571:4571 \
          -e LAMBDA_EXECUTOR=docker \
          -e SERVICES=lambda,ec2,vpc,s3,apigateway,iam,rds,cloudwatch,route53 \
          -e DEBUG=1 \
          -v /var/run/docker.sock:/var/run/docker.sock \
          localstack/localstack

    - name: Check Docker availability
      run: |
        docker --version

    # TFLocal のインストール
    - name: Install TFLocal
      run: |
          pip install localstack-client
          pip install terraform-local

    # 暫定追加
    - name: Print current directory(Temporary add 2024/09/07)
      run: ls -lrt

    # Lambdaのファイルがあるかの事前確認
    - name: Verify ZIP file creation
      run: |
        cd terraform
        ls -la lambda/
        unzip -l lambda/lambda_function_payload.zip

    # Terraform の初期化
    - name: Initialize TFLocal
      run: |
        cd terraform
        tflocal init

    # Terraform の適用
    - name: Apply TFLocal configuration
      run: |
        cd terraform
        ls -lrtR
        tflocal apply -auto-approve

    # 出力の確認
    - name: Output TFLocal state
      run: |
        cd terraform
        tflocal output

    # 出力の確認
    - name: show TFLocal state
      run: |
        cd terraform
        tflocal show
        tflocal state list
```
   - LocalStackコンテナの起動
   - Terraformによるインフラの計画・適用
       - （`terraform plan`および`terraform apply`の代わりに、tflocal applyします。）

**３．LocalStackでのリソース作成**  
   LocalStackのAPIエンドポイントにTerraformからアクセスし、定義したリソースが正しく作成されるかをGithubActionsで確認します。
   トライアンドエラーでかなり作成しているので、細かい内容はGitHubActionsのWorkflowの内容で確認ができます。
エラーの一例として、下記が表示されますので、必要に応じてコードを修正します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551020/bdadfe79-93d2-80be-f693-6fe4e6ab9d4d.png)

**４．自動テスト**  
   リソースの作成後、自動テストを実施し、API GatewayやLambdaが期待通りに動作するかを確認。

### 結果
GitHub Actions上でTerraformとLocalStackを利用したWorkflowに成功しました。
コーディング内容を確認するくらいであれば、実際のAWS環境を用意しなくとも、動作確認は可能でありそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551020/ce826f66-8ced-0c10-075a-d0d941cc978d.png)
「show TFLocal state」で、tflocal showとtflocal state listを実行しているので、
項目の確認も可能そうです。

### 今後の課題
今回は単純にリソース作成だけでしたが、
今後の展望としては
* Locakstackで作成できる範囲で、パラメータを設定し、どれだけ作成ができるのか
* tflocalをterraformにして、エイリアス設定でもできるか
を確認したいと思います。

### 参考
- LocalStack公式ドキュメント: [https://localstack.cloud](https://localstack.cloud)
- Terraform公式ドキュメント: [https://www.terraform.io](https://www.terraform.io)
- Lambdaのaws_lambda_functionについて: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function