AWS CDK(Python)だけでWordPressサイトをデプロイする(ELB,EC2,EFS,RDS)

もくじ

おさらい

前々回(第1回)の記事はこちらです。

前回(第2回)の記事はこちらです。

構成図

構成図は大事なので毎回記載します。完成形は以下です。

今回やること

今回はすべてのスタックをデプロイします。デプロイした後、カスタムAMIを作成します。

そしてCDKを修正して、EC2がカスタムAMIから起動されるように変更します。

また、WordPressの動作確認も行います。

デプロイ

準備

AWS CDKを使用するための前提条件は、AWS CDK Intro Workshopに詳しく書かれています。これから始める方はぜひ一度!

前提条件が書かれているリンクは下記です。

前提条件

Networkスタックをデプロイ

Networkスタックのデプロイを行ったときのターミナルです。カラフルで見やすいですね!

IAMやSecurity Groupなどセキュリティに関するものは、特にわかりやすくハイライトされています。

CDKをYAMLで表示したい場合はcdk synthコマンドをご利用ください。

Storageスタックをデプロイ

次にStorageスタックをデプロイします。

セキュリティグループに許可設定が入り、EC2とEFSの間で2049ポート通信が許可されています。

Databaseスタックをデプロイ

Databaseスタックをデプロイします。マルチAZ構成なので少し時間がかかります。(ここでは10分かかってます)

セキュリティグループに許可設定が入り、EC2とRDSの間で3306ポート通信が許可されています。

Computingスタックをデプロイ

最後にComputingスタックです。

動作確認(カスタムAMI設定前)

最終的にはカスタムAMIからEC2を起動するようにしますが、ここで一旦動作確認をします。

ELBのDNS名を確認

aws cliで確認します。

% aws elbv2 describe-load-balancers | grep DNSName
            "DNSName": "wp-dev-alb-XXXXXXXXX.ap-northeast-1.elb.amazonaws.com",

AWSコンソールから確認しても構いません。

WordPressにアクセス

ELBのDNS名でブラウザでアクセスします。

ページが表示できました。

WordPressへログイン

http://[ELBのDNS名]/wp-adminへアクセスしてみます。

CDKのコード上で指定したユーザー名とパスワードを入力します。

ログインできました。

カスタムAMIの設定

このままだと、Auto Scalingによって作成されるEC2すべてがユーザーデータを実行してしまうので、カスタムAMIからの起動にしていきます。

カスタムAMIの作成

現在起動しているEC2からカスタムAMIを作成します。

まずはEC2のインスタンスIDを取得します。AWSコンソールからでもOKです。

% aws ec2 describe-instances --filters Name=instance-state-name,Values=running | grep InstanceId 
                    "InstanceId": "i-XXXXXXXXXXXXXXXXX",

確認したインスタンスIDを指定してカスタムAMIを作成します。

% aws ec2 create-image --instance-id i-XXXXXXXXXXXXXXXXX --name "wp-dev-ami" --description "AMI for WordPress Server"
{
    "ImageId": "ami-XXXXXXXXXXXXXXXXX"
}

カスタムAMIのStateavailableになればCDKコードの修正に入ります。

% aws ec2 describe-images --filters Name=name,Values="wp-dev-ami" 
{
    "Images": [
        {
            "Architecture": "x86_64",
            "CreationDate": "2022-08-14T07:28:38.000Z",
            "ImageId": "ami-XXXXXXXXXXXXXXXXX",
            "ImageLocation": "XXXXXXXXXXXX/wp-dev-ami",
            "ImageType": "machine",
            "Public": false,
            "OwnerId": "XXXXXXXXXXXX",
            "PlatformDetails": "Linux/UNIX",
            "UsageOperation": "RunInstances",
            "State": "available",
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "SnapshotId": "snap-0fab3fef000ebe50a",
                        "VolumeSize": 8,
                        "VolumeType": "gp2",
                        "Encrypted": false
                    }
                }
            ],
            "Description": "AMI for WordPress Server",
            "EnaSupport": true,
            "Hypervisor": "xen",
            "Name": "wp-dev-ami",
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SriovNetSupport": "simple",
            "VirtualizationType": "hvm"
        }
    ]
}

CDKコード一部修正

Computingスタック修正

Computingを修正します。修正した箇所はハイライトしています。

from aws_cdk import (
    Duration,
    Stack,
    aws_ec2 as ec2,
    aws_elasticloadbalancingv2 as elbv2,
    aws_autoscaling as autoscaling,
    aws_iam as iam,
)
from constructs import Construct
import aws_cdk as cdk
from aws_cdk.aws_s3_assets import Asset

class ComputingStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        ##############################################
        ############### Import Section ###############
        ##############################################
        # Import VPC
        wp_vpc = ec2.Vpc.from_lookup(self, "Vpc",
            vpc_name="wp-dev-vpc"
        )

        # Import Security Group(EC2)
        wp_sg_ec2 = ec2.SecurityGroup.from_lookup_by_name(self, "SgEC2",
            vpc=wp_vpc,
            security_group_name="wp-dev-sg-ec2"
        )

        # Import Security Group(EFS)
        wp_sg_efs = ec2.SecurityGroup.from_lookup_by_name(self, "SgEFS",
            vpc=wp_vpc,
            security_group_name="wp-dev-sg-efs"
        )

        # Import Security Group(RDS)
        wp_sg_rds = ec2.SecurityGroup.from_lookup_by_name(self, "SgRDS",
            vpc=wp_vpc,
            security_group_name="wp-dev-sg-rds"
        )

        # Import Security Group(ELB)
        wp_sg_elb = ec2.SecurityGroup.from_lookup_by_name(self, "SgELB",
            vpc=wp_vpc,
            security_group_name="wp-dev-sg-elb"
        )

        # Import Secrurity Group(SSM)
        wp_sg_ssm = ec2.SecurityGroup.from_lookup_by_name(self, "SgSSM",
            vpc=wp_vpc,
            security_group_name="wp-dev-sg-ssm"
        )

        # Import IAM Role(EC2)
        wp_role_ec2 = iam.Role.from_role_name(self, "RoleEC2",
            role_name="wp-dev-role-ec2"
        )
        

        ##############################################
        ############### Server Section ###############
        ##############################################
        # Upload Shell Script(User Data) to s3
        # asset = Asset(self, "Asset",
        #     path="Computing/User_data.sh"
        # )

        # Create User Data Instance
        # wp_userdata = ec2.UserData.for_linux()

        # Launch Template
        wp_lt = ec2.LaunchTemplate(self, "LaunchTemplate",
            launch_template_name="wp-dev-lt",
            instance_initiated_shutdown_behavior=ec2.InstanceInitiatedShutdownBehavior.TERMINATE,
            security_group=wp_sg_ec2,
            instance_type=ec2.InstanceType.of(
                instance_class=ec2.InstanceClass.BURSTABLE2,
                instance_size=ec2.InstanceSize.MICRO
            ),
            role=wp_role_ec2,
            # user_data=wp_userdata,
            # machine_image=ec2.AmazonLinuxImage(                       
            #     generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2
            # ),
            # Set the AMI from EC2 after installed WordPress            
            machine_image=ec2.MachineImage.generic_linux(
                {"us-east-1": "ami-038b0c10ca70701f8"}
            )
        )
        # Grant Read to Role of Template
        # asset.grant_read(wp_lt.role)

        # Download Shell Script(User Data) to local path
        # wp_local_path = wp_userdata.add_s3_download_command(
        #     bucket=asset.bucket,
        #     bucket_key=asset.s3_object_key,
        #     region="us-east-1"
        # )

        # Add User Data to Template
        # wp_lt.user_data.add_execute_file_command(
        #     file_path=wp_local_path
        # )

        # Auto Scaling Group
        wp_asg = autoscaling.AutoScalingGroup(self, "Asg",
            vpc = wp_vpc,
            auto_scaling_group_name="wp-dev-asg",
            launch_template=wp_lt,
            health_check=autoscaling.HealthCheck.elb(
                grace=cdk.Duration.seconds(30)
            ),
            vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT),
            desired_capacity=2,
            min_capacity=2,
            max_capacity=4
        )

        
        #####################################################
        ############### Load Balancer Section ###############
        #####################################################
        # Application Load Balancer
        wp_alb = elbv2.ApplicationLoadBalancer(self, "Alb",
            vpc=wp_vpc,
            http2_enabled=False,
            ip_address_type=elbv2.IpAddressType.IPV4,
            security_group=wp_sg_elb,
            internet_facing=True,
            load_balancer_name="wp-dev-alb",
            vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC)
        )

        # Target Group
        wp_tg = elbv2.ApplicationTargetGroup(self, "TargetGroup",
            vpc=wp_vpc,
            port=80,
            target_group_name="wp-dev-tg",
            health_check=elbv2.HealthCheck(
                enabled=True,
                protocol=elbv2.Protocol.HTTP,
                port="80",
                path="/readme.html",
                timeout=cdk.Duration.seconds(25), # Defaultis 5
                unhealthy_threshold_count=5 # Default is 2
            ),
            target_type=elbv2.TargetType.INSTANCE
        )
        
        # Add Targets To Auto Scaling Group
        wp_tg.add_target(wp_asg)

        # Add Listner To ELB
        wp_alb.add_listener("AddListener",
            port=80,
            default_target_groups=[wp_tg]
        )


        ######################################################
        ############### Add Allow Rule Section ###############
        ######################################################
        # Add Allow Connection to EC2
        wp_lt.connections.allow_from(wp_sg_elb, ec2.Port.tcp(80)) # Allow HTTP from ALB
        wp_lt.connections.allow_to(wp_sg_ssm, ec2.Port.tcp(443)) # For Acces to EC2 by Sessions Manager
        # wp_lt.connections.allow_to_any_ipv4(ec2.Port.tcp(80)) # For EC2 installs some packages by User Data. Disable after installing wordPress.
        # wp_lt.connections.allow_to_any_ipv4(ec2.Port.tcp(443)) # For EC2 installs some packages by User Data. Disable after installing wordPress.

        # Add Allow Connection to ELB
        wp_alb.connections.allow_from_any_ipv4(ec2.Port.tcp(80))

Computingスタック修正箇所

  • 66〜71行目
    UserDataを生成する必要がなくなったためコメントアウトしています。
     
  • 83〜86行目
    起動テンプレートにUserDataを指定する必要がなくなったためコメントアウトしています。
    また、AMIはカスタムAMIを使用するためコメントアウトしています。
     
  • 88〜90行目
    先ほど作ったカスタムAMIを指定しています。
     
  • 93〜105行目
    UserDataのダウンロードや実行の指定は必要がなくなったためコメントアウトしています。
     
  • 116〜118行目
    Auto Scalingの容量を変更しています。
    EC2がマルチAZで配置されるようにするため、希望容量と最低容量を2にしています。最大容量はここでは4を指定しています。(実際に使うのであれば負荷テスト実施後になると思いますが)
      
  • 168〜169行目
    今のところEC2がインターネットに接続する必要はなくなるため、EC2からのHTTP(80)とHTTPS(443)のアウトバウンド許可を削除します。

再デプロイ(Computingスタック)

差分を比較してみます。cdk diffコマンドです。

EC2のセキュリティグループの一部が削除されること、EC2の起動に使用されるAMIが変更されること、Auto Scalingの容量が変更されることが表示されています。

再デプロイします。

デプロイ成功しました。

カスタムAMIではないEC2を削除

EC2がもう1台起動して2台構成になっていると思いますが、片方だけカスタムAMIからの起動になっています。最初に起動したEC2は終了します。

希望容量を2台としているのでもう1台起動して、カスタムAMIから起動したEC2でマルチAZ構成となりました。

動作確認(カスタムAMI設定後)

カスタムAMI設定後もWordPressが正常にホストされているか確認します。

ELBのDNS名でアクセスして正常に画面が表示されました。管理画面にもログインすることができました。

Nat Gatewayについて

Nat Gatewayが1台起動しています。

起動しているだけで料金がかかってしまうので、AWSコンソールから削除することをおすすめします。

また、それに紐づくEIPも開放しておいたほうがよいと思います。アタッチされていないと料金が発生してしまうので。

参考サイト

WordPressをコマンドラインでインストールしたい

Welcome to WP-CLI!

1 2 3

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

もくじ
閉じる