CloudFormationでWordPressのサーバをたててみた

フェイス・ソリューション・テクノロジーズ株式会社IS本部OSユニットのimaiです。
今回は、AWS CloudFormationでWordPressサーバを構築した経験を共有したいと思います。

はじめに

AWSでWordPressサーバを構築する際、手動での設定は時間がかかり、また人為的ミスのリスクも高くなります。特に本番環境では、セキュリティや可用性、パフォーマンスなど、多くの要素を考慮する必要があります。
そこで今回は、Infrastructure as Code(IaC)の考え方に基づき、AWS CloudFormationでWordPress環境を構築しました。

CloudFormationを選択した理由

  • 他のAWSサービスとの連携が容易
  • テンプレートの再利用性が高く、環境の複製が簡単
  • JSONやYAMLでの記述が可能で、バージョン管理がしやすい
  • テンプレートのバリデーション機能により、デプロイ前のエラー検出が可能

CloudFormationを使用することで得られる利点

  • インフラ構成をコードとして管理し、変更履歴の追跡が可能に
  • 環境の再現性を確保し、検証環境と本番環境の差異を最小化
  • デプロイの自動化を実現し、人為的ミスを防止

CloudFormationの詳細については、弊社のSaki@猫好きが説明していますので、そちらをご確認ください。

システム構成

今回構築したシステムの特徴

  • パブリックサブネットとプライベートサブネットの適切な配置
  • マルチAZ構成のRDSで高可用性を実現
  • CloudFrontによるコンテンツ配信の最適化
  • CloudWatchでの監視体制の確立

主なポイント

すべて紹介するとコードが膨大になるため、ポイントを絞って紹介します。

1. テンプレートの分割管理

大規模なインフラ構成では、1つのテンプレートファイルが肥大化し、管理が困難になりがちです。
そこで、機能ごとにテンプレートを分割しました。

テンプレートを分割することによるメリット

  • 各コンポーネントの独立した管理が可能
  • テンプレートの再利用性が向上
  • 変更の影響範囲を限定できる
  • レビューがしやすく、品質管理が容易
AWSTemplateFormatVersion: 2010-09-09

Resources:
  # ネットワークインフラの基盤となるVPCスタック
  VPCStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: vpc.yaml
      
  # データベースを構築するRDSスタック
  RDSStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: rds.yaml
      
  # サーバを構築するEC2スタック
  EC2Stack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: ec2.yaml
...

2. セキュアなパスワード管理

セキュリティ面で最も重要な要素の1つが、データベースやサーバのパスワード管理です。
今回は、Systems Manager Parameter StoreのSecure Stringを活用し、パスワードを暗号化して管理しました。

Resources:
  MyRDSDBInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      # データベースの基本設定
      DBInstanceIdentifier: !Ref DBInstanceIdentifier
      MasterUsername: !Ref DBMasterUserName
      # セキュアなパスワード管理 - Parameter Storeから取得
      MasterUserPassword: !Sub '{{resolve:ssm-secure:${DBPasswordParameterName}}}'
      # エンジンとバージョン設定
      Engine: mysql
      EngineVersion: 8.0.39
...

3. 堅牢なネットワーク設計

セキュリティとパフォーマンスを考慮し、VPCを適切に設計することは非常に重要です。

注意したポイント

  • パブリック/プライベートサブネットの分離
  • アベイラビリティゾーンの冗長化
  • 適切なルーティング設定
Resources:
  # VPCのメイン定義
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
...

  # Webサーバー用パブリックサブネット
  MyPublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.0.0/20
      MapPublicIpOnLaunch: true  # 自動でパブリックIP割り当て
      AvailabilityZone: !Select [0, !GetAZs '']  # AZ冗長化
...

  # RDS用プライベートサブネット
  MyPrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.32.0/20
      MapPublicIpOnLaunch: false
      AvailabilityZone: !Select [0, !GetAZs '']
...

4. WordPressの自動セットアップ

WordPressの初期設定を自動化することで、構築時間の短縮と設定ミスの防止を実現しました。

主なポイント

  • 必要なパッケージの自動インストール
  • データベース接続設定の自動化
  • WP-CLIによる効率的な管理
#!/bin/bash

# WordPressの設定ファイル作成と権限設定
cd /var/www/html
sudo -u apache cp wp-config-sample.php wp-config.php

# データベース接続情報の設定
sed -i "s/database_name_here/${DB_NAME}/" wp-config.php
sed -i "s/username_here/${DB_MASTER_USER_NAME}/" wp-config.php

# Parameter Storeからパスワード取得
DB_MASTER_USER_PASSWORD=$(aws ssm get-parameter \
    --name ${DB_PASSWORD_PARAMETER_NAME} \
    --region ${AWS_REGION} \
    --with-decryption \
    --query 'Parameter.Value' \
    --output text)
sed -i "s/password_here/${DB_MASTER_USER_PASSWORD}/" wp-config.php
sed -i "s/localhost/${RDS_ENDPOINT}/" wp-config.php

# WP-CLIによる初期設定
EC2_PUBLIC_IP=$(ec2-metadata --public-ipv4 | cut -d ' ' -f 2)
WP_USER_PASSWORD=$(aws ssm get-parameter \
    --name ${WP_PASSWORD_PARAMETER_NAME} \
    --region ${AWS_REGION} \
    --with-decryption \
    --query 'Parameter.Value' \
    --output text)

# WordPressコアのインストールと初期設定
sudo -u apache wp core install \
  --url="http://${EC2_PUBLIC_IP}" \
  --title="${WP_TITLE}" \
  --admin_user="${WP_USER_NAME}" \
  --admin_password="${WP_USER_PASSWORD}" \
  --admin_email="${WP_USER_EMAIL}" \
  --skip-email
...

5. 包括的な監視設定

システムの安定運用には、適切な監視体制の構築が不可欠です。

CloudWatchで包括的な監視を実装

  • リソース使用率の監視
  • ログの収集
  • アラート通知の自動化
Resources:
  # CPU使用率監視アラーム
  EC2CPUUtilizationAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub ${EC2InstanceId}-CPUUtilizationAlarm
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Period: 300  # 5分間隔での監視
      EvaluationPeriods: 1
      Statistic: Average
      Threshold: 80  # 80%を超えたらアラート
      ComparisonOperator: GreaterThanOrEqualToThreshold
      # SNSトピックへのアラート通知
      AlarmActions:
        - !Ref SNSTopicArn
...

6. 高可用性の実現

システムの可用性を高めるための対策を実装しました。

システムの可用性を高めるための対策

  • マルチAZ構成によるデータベースの冗長化
  • 自動アップデート
Resources:
  MyRDSDBInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      # 基本設定
      DBInstanceIdentifier: !Ref DBInstanceIdentifier
      DBName: !Ref DBName
      DBInstanceClass: db.t3.micro
      Engine: mysql
      EngineVersion: 8.0.39

      # 高可用性設定
      MultiAZ: true  # マルチAZ構成の有効化
      AutoMinorVersionUpgrade: true # マイナーバージョンの自動アップグレード
      PreferredMaintenanceWindow: sat:16:00-sat:18:00 # メンテナンス時間帯

      # ネットワーク設定
      DBSubnetGroupName: !Ref MyRDSDBSubnetGroup
      VPCSecurityGroups:
        - !Ref RDSSecurityGroupId
...

7. 自動更新の実装

セキュリティパッチの適用やシステムの更新を自動化することで、運用負荷の軽減とセキュリティの向上を図りました。

Resources:
  # メンテナンスウィンドウの設定
  SSMMaintenanceWindow:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      Name: PatchMaintenanceWindow
      Schedule: cron(0 1 * * ? *)  # 毎日午前1時に実行
      ScheduleTimezone: Asia/Tokyo
      Duration: 2  # 2時間の実行枠
      Cutoff: 1   # 1時間前にタスク開始を締め切り
...

  # パッチ適用タスク
  SSMMaintenanceWindowTask:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      WindowId: !Ref SSMMaintenanceWindow
      TaskType: RUN_COMMAND
      TaskArn: AWS-RunPatchBaseline  # AWSの標準パッチベースラインを使用
      Priority: 1
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref SSMMaintenanceWindowTarget
...
      # パッチ適用の詳細設定
      TaskInvocationParameters:
        RunCommand:
          Parameters:
            Operation: ['Install']
            RebootOption: ['RebootIfNeeded']
      
      # 対象インスタンスの指定
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref SSMMaintenanceWindowTarget
...

8. SSL/TLS対応とパフォーマンス向上

セキュアな通信とコンテンツ配信の最適化のため、CloudFrontとACMを組み合わせて実装しました。

Resources:
  MyCloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        # キャッシュ動作の設定
        DefaultCacheBehavior:
          TargetOriginId: !Sub ${DomainName}-origin
          ViewerProtocolPolicy: redirect-to-https  # HTTPSへの強制リダイレクト
          AllowedMethods:
            - GET
            - HEAD
            - OPTIONS
            - PUT
            - POST
            - PATCH
            - DELETE
        # SSL/TLS設定
        ViewerCertificate:
          AcmCertificateArn: !Ref MyACMCertificate
          SslSupportMethod: sni-only
          MinimumProtocolVersion: TLSv1.2_2021
...

最後に

今回のCloudFormationを使用したWordPress環境の構築を通じて、IaCの重要性を改めて実感しました。特に以下の点で大きな効果がありました。

作業時間の削減

  • エラー修正が容易になり、トラブルシューティング時間も短縮
  • 環境の複製が数クリックで完了
  • テスト環境の素早い構築が可能に

品質の向上

  • 設定ミスの防止により、本番環境での障害リスクを低減
  • 一貫性のある環境構築で、検証環境と本番環境の差異を排除
  • コードレビューによる品質管理の実現

ドキュメントとしての価値

  • インフラ構成の可視化により、システム理解が容易に
  • チーム内での知識共有が促進

保守性の向上

  • 変更履歴の管理により、構成変更の追跡が容易に
  • 設定変更の影響範囲の明確化
  • 段階的なアップデートの実現

今後の展望

この経験を通じて得られた知見を基に、以下のような改善を検討しています。

自動化の範囲拡大

  • 障害復旧プロセスの自動化
  • コスト最適化の自動化

モニタリングの強化

  • アプリケーションレベルの詳細な監視
  • セキュリティ監視の強化

セキュリティの強化

  • セキュリティテストの自動化
  • インシデントレスポンスの改善

パフォーマンスの最適化

  • キャッシュ戦略の最適化
  • コスト効率の向上

このテンプレートをベースに、さらなる改善や機能追加を行っていく予定です。また、この経験を活かして、IaCを積極的に活用していきたいと考えています。CloudFormationを使用したインフラのコード化は、単なる自動化ツールではなく、現代のクラウドインフラ管理における重要な戦略の一つとなっています。今後も継続的な改善を重ね、より効率的で安全なインフラ構築を目指していきます。

プロフィール
この記事を書いた人
imai

寿司が好きです。

imaiをフォローする
フェイスでは一緒に働く仲間を募集しています

フェイス・ソリューション・テクノロジーズ株式会社では、一緒に働いてくれる仲間を募集しています。
いろいろな案件があるので、いろいろなことに挑戦できる会社です。
「面白いこと」に積極的なので、あなたの「面白そうなことだからやってみたい」を形にできるチャンスがあります!

CloudFormation
フェイススタッフブログ

コメント

タイトルとURLをコピーしました