Terraform × Ansible × GitHub ActionsでWordPless構築の自動化

## はじめに
TerraformでAWSリソース作成、AnsibleでWordPressに必要なWebサーバー、PHPモジュールなどの環境を自動化して構築してみたので記事にしました。また、GitHub Actionsを利用してテンプレートのプッシュをトリガーにTerraform applyを実行するワークフローを取り入れ、CI/CDプロセスを実現しました。

## Ansibleについて 
[Ansible実践入門](https://dev.classmethod.jp/articles/practice_ansible/)
EC2はユーザーデータで起動時に環境構築のスクリプトを自動実行できますが、デメリットとして環境依存と冪等性がないことです。
個人のテスト環境においてはベストプラクティスとは言えないですが、ssh接続さえすれば、Ansibleは再利用可能なPlaybookを作成できるため、大規模なプロジェクトや将来的にスケールする可能性があるなら最適解となります。

なお今回はAnsibleインストールや実行方法については記事を挙げられている方が多いので割愛します。
今後インストールとホスト設定のスクリプトを作成したらEC2のユーザーデータに組み込む予定です。

## 構成
![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812406/f871d8e1-a9f5-4d10-9d7d-ffb68b235655.png)
#### ディレクトリ構成
```

├── terraform/
│   ├── main.tf                 
│   ├── terraform.tfvars        
│   ├── variables.tf            
│   ├── outputs.tf                        
│
├── .github/                
│   └── workflows/          
│       └── terraform-deploy.yml 
├── modules/                    
│   ├── vpc/                    
│   │   ├── main.tf             
│   │   ├── variables.tf        
│   │   └── outputs.tf          
│   ├── ec2/
│   │   ├── main.tf             
│   │   ├── variables.tf        
│   │   └── outputs.tf
│   ├── rds/
│   │   ├── main.tf             
│   │   ├── variables.tf        
│   │   └── outputs.tf
│   ├── alb/
│   │   ├── main.tf             
│   │   ├── variables.tf        
│   │   └── outputs.tf
│   ├── cdn/
│   │   ├── main.tf             
│   │   ├── variables.tf        
│   │   └── outputs.tf
│   ├── route53/
│   │   ├── main.tf             
│   │   ├── variables.tf        
│   │   └── outputs.tf   
│   ├── backend/             
│   │   ├── main.tf          
│   │   ├── variables.tf     
│   │   └── outputs.tf       
│
│             
├── .gitignore               
└── README.md  

# インスタンスのディレクトリ
├── /etc/                           
│   ├── ansible/                    
│        └── playbook.yml            
│        ├── inventory/               
│        │   └── hosts              # キーペアとインスタンスIP定義  
│        ├── roles/                   
│        │   └── common/              
│        │       ├── tasks/           
│        │       └── templates/     
                  
```
#### ↓参考記事
[今一度改めて Terraform ディレクトリ構造のベストプラクティスを考えてみた件](https://tech.visasq.com/terraform-directory-best-practice)
[Terraform ベストプラクティスを整理してみました。](https://dev.classmethod.jp/articles/terraform-bset-practice-jp/)
[TerraformとGitHub Actionsを使ってCI/CDを実現するための基本ガイド](https://www.issoh.co.jp/tech/details/2715/#TerraformStateS3)

## 各種テンプレート 
##### ※Terraformの状態管理（リソースの同期）があるterraform.tfstateはS3とDynamoDB（backend）で管理するため.gitignoreに追加します。
https://github.com/ryt117/wordpress

## Playbook
```
- hosts: client_node
  become: true
  tasks:
    # enable php
    - name: Enable PHP 8.2 repository
      shell: amazon-linux-extras enable php8.2


    # パッケージインストール
    - name: install packages
      yum:
        name:
          - httpd
          - php
          - php-mbstring
          - php-xml
          - php-mysqli
        state: present

    # WordPressダウンロード
    - name: download wp
      get_url:
        url: http://ja.wordpress.org/latest-ja.tar.gz
        dest: /tmp/latest-ja.tar.gz

    # WordPress展開
    - name: extract wp
      unarchive:
        src: /tmp/latest-ja.tar.gz
        dest: /tmp
        remote_src: yes

    # ドキュメントルートに配置
    - name: cp wp
      copy:
        src: /tmp/wordpress/
        dest: /var/www/html/
        remote_src: yes
    
    # ヘルスチェック用ファイル作成
    - name: create health check file
      file:
        path: /var/www/html/.check_alive
        state: touch

    # Apacheユーザー設定
    - name: user setting
      file:
        path: /var/www/html
        state: directory
        owner: apache
        group: apache
        recurse: yes

    # Apache起動と有効化    
    - name: apache start / enable
      service:
        name: httpd
        state: started
        enabled: yes
```

## 確認
#### パッケージのインストール
```
[ec2-user@ip-10-0-0-215 html]$ rpm -q httpd php 
httpd-2.4.62-1.amzn2.0.2.x86_64
php-8.2.34-1.amzn2.x86_64
```

#### WordPressのダウンロードと展開
```
[ec2-user@ip-10-0-0-215 html]$ ls -la /tmp/wordpress
total 236
drwxr-xr-x  5 1006 1006  4096 Feb 11 17:00 .
drwxrwxrwt 10 root root   290 Mar 27 01:46 ..
-rw-r--r--  1 1006 1006   405 Feb  6  2020 index.php
-rw-r--r--  1 1006 1006 19915 Jan  1  2024 license.txt
-rw-r--r--  1 1006 1006  7409 Jun 18  2024 readme.html
-rw-r--r--  1 1006 1006  7387 Feb 13  2024 wp-activate.php
drwxr-xr-x  9 1006 1006  4096 Feb 11 17:00 wp-admin
-rw-r--r--  1 1006 1006   351 Feb  6  2020 wp-blog-header.php
-rw-r--r--  1 1006 1006  2323 Jun 14  2023 wp-comments-post.php
-rw-r--r--  1 1006 1006  3336 Oct 15 15:24 wp-config-sample.php
drwxr-xr-x  5 1006 1006    69 Feb 11 17:16 wp-content
-rw-r--r--  1 1006 1006  5617 Aug  2  2024 wp-cron.php
drwxr-xr-x 30 1006 1006 12288 Feb 11 17:16 wp-includes
-rw-r--r--  1 1006 1006  2502 Nov 26  2022 wp-links-opml.php
-rw-r--r--  1 1006 1006  3937 Mar 11  2024 wp-load.php
-rw-r--r--  1 1006 1006 51367 Sep 30 19:12 wp-login.php
-rw-r--r--  1 1006 1006  8543 Sep 18  2024 wp-mail.php
-rw-r--r--  1 1006 1006 29032 Sep 30 17:08 wp-settings.php
-rw-r--r--  1 1006 1006 34385 Jun 19  2023 wp-signup.php
-rw-r--r--  1 1006 1006  5102 Oct 18 15:56 wp-trackback.php
-rw-r--r--  1 1006 1006  3246 Mar  2  2024 xmlrpc.php
```

#### ヘルスチェック用ファイル
```
[ec2-user@ip-10-0-0-215 html]$ ls -la /var/www/html/.check_alive
-rw-r--r-- 1 apache apache 0 Mar 27 00:19 /var/www/html/.check_alive
```

## 最後に
ディレクトリ構成のベストプラクティス、CI/CDにおけるリソースの状態管理の理解が深まった。