1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PolarDBなどのデータベースに関するTipsを記事投稿しよう by Alibaba CloudAdvent Calendar 2023

Day 17

Terrafromを使って、Alibaba Cloud ECS + RDS によるMagentoをさくっとデプロイしてみる

Last updated at Posted at 2023-12-17

はじめに

これはAlibaba CloudのkubernetesやServerless製品(SAEなど)でサービス立ち上げてみよう by Alibaba Cloud Advent Calendar 2023 の記事です。
私は日頃からAlibabaCloudによるソリューションや開発手法、展開に取り組んでおり、日々中国や全世界から最先端の技術取得に励んでいます。
そうした活動をもっと外部へと発信していこうと始めたのがこのAdventCalendarです。メンバー一人一人が書いた記事を通して、少しでも多くの方にAlibabaCloudの興味を持って頂ければ幸いです。
さて、本記事はTerrafromを使って、Alibaba Cloud ECS + RDS によるMagentoをさくっとデプロイしてみる話です。
Magento はオープンソースで人気のあるECプラットフォームです。Magento はオープンソース版もあり、必要なすべての e コマース機能が付帯されているため、スモールスタートから大規模Webサイト向けに使いやすく、色々な実績があります。

最近 この記事 を書いたのですが、よくよく考えてみたら、システム全体は、ACK(Alibaba Cloud Container Service for Kubernetes) 上にてWebサイトやデータベースをインストール、構築しています。そのため、メンテナンスや拡張には適していません。

なので、次の手順は ECS(Elastic Compute Service)インスタンスとApsaraDB RDS for MySQLインスタンスに基づいてMagentoWebサイトを構築します。必要なすべてのリソースは、一般的なインフラストラクチャ構成を迅速に展開するために使用します。といっても、コンソールでポチポチ操作するのも面倒なので、TerraformことInfrastructure as Codeベースで構築します。

このチュートリアルについて

対象となる方:

このガイドは、次の方を対象としています。

  • Alibaba Cloud, ECS(Elastic Compute Service), ApsaraDB RDS, VPC(Virtual Private Cloud) とMagento、Terraform に関する基本的な知識を持つこと

前提条件:

  • Alibaba cloud アカウントを持つこと
  • Alibaba CloudでECS(Elastic Compute Service), ApsaraDB RDS, VPC(Virtual Private Cloud) を有効化していること

terraformでリソースを準備

terraformにはAlibabaCloud Provider を参考しながら、AlibabaCloudの関連リソースを管理します。本記事は次のような構成図で作成を進めます。

image.png

作業環境にterraformをインストール

使用する OS に基づいて最新の terraform をインストールします。詳細については、Terraformのインストール を参照してください。

image.png

terraform構成ファイルを準備

今回、MagentoをAlibaba Cloud リソースとしてTerraformでデプロイするにあたり、Alibaba Cloud リソースとその依存関係を Alibaba Cloud Providerに基づいて以下の表のように定義し、設定します。

04_Terraform_Alibaba_Cloud_Provider_Dependency_Overview.png

以下のように関連する設定ファイルを準備します。 main.tfは、リソース情報と依存関係を定義します。

provider "alicloud" {
  access_key    = "${var.access_key}"
  secret_key    = "${var.secret_key}"
  region        = "${var.region}"
}

data "alicloud_instance_types" "ecs_types" {
  availability_zone     = "${var.zone}"
  cpu_core_count        = "${var.cpu_core_count}"
  memory_size           = "${var.memory_size}"
}

resource "alicloud_vpc" "vpc" {
  vpc_name      = "${var.project_name}-vpc"
  cidr_block    = "${var.vpc_cidr}"
  description   = "Magento demo vpc"
}

resource "alicloud_vswitch" "vsw" {
  vswitch_name      = "${var.project_name}-vswitch"
  vpc_id            = "${alicloud_vpc.vpc.id}"
  cidr_block        = "${var.vswitch_cidr}"
  zone_id           = "${var.zone}"
  description       = "Magento demo vswitch"
}

resource "alicloud_security_group" "magento_server" {
  name          = "${var.project_name}-security-group"
  description   = "Enable HTTP access via port 80"
  vpc_id        = "${alicloud_vpc.vpc.id}"
}

resource "alicloud_security_group_rule" "allow_ssh" {
  type              = "ingress"
  ip_protocol       = "tcp"
  nic_type          = "intranet"
  policy            = "accept"
  port_range        = "22/22"
  priority          = 1
  security_group_id = "${alicloud_security_group.magento_server.id}"
  cidr_ip           = "${var.allow_ssh_ip}"
}

resource "alicloud_security_group_rule" "allow_http" {
  type              = "ingress"
  ip_protocol       = "tcp"
  nic_type          = "intranet"
  policy            = "accept"
  port_range        = "80/80"
  priority          = 1
  security_group_id = "${alicloud_security_group.magento_server.id}"
  cidr_ip           = "0.0.0.0/0"
}

resource "alicloud_instance" "magento_instance" {
  availability_zone          = "${var.zone}"
  security_groups            = ["${alicloud_security_group.magento_server.id}"]
  instance_type              = "${data.alicloud_instance_types.ecs_types.instance_types.0.id}"
  system_disk_category       = "cloud_efficiency"
  image_id                   = "centos_7_9_x64_20G_alibase_20210824.vhd"
  instance_name              = "${var.project_name}-ecs"
  vswitch_id                 = "${alicloud_vswitch.vsw.id}"
  internet_max_bandwidth_out = 5
  instance_charge_type       = "PostPaid"
  key_name                   = "${var.ecs_key_name}"
  user_data                  = "${file("magento.sh")}"
}

resource "alicloud_db_instance" "magento_db" {
  engine                    = "MySQL"
  engine_version            = "5.7"
  zone_id                   = "${var.zone}"
  instance_type             = "${var.db_instance_type}"
  instance_storage          = "30"
  instance_charge_type      = "Postpaid"
  instance_name             = "${var.project_name}-rds-mysql"
  vswitch_id                = "${alicloud_vswitch.vsw.id}"
  security_ips              = ["${alicloud_instance.magento_instance.private_ip}"]
  monitoring_period         = "60"
}

resource "alicloud_db_account" "account" {
  db_instance_id      = "${alicloud_db_instance.magento_db.id}"
  account_name        = "${var.db_account}"
  account_password    = "${var.db_password}"
  account_description = "Magento demo db account"
}

resource "alicloud_db_database" "db" {
  instance_id = "${alicloud_db_instance.magento_db.id}"
  name        = "${var.database_name}"
  description = "Magento demo database"
}

resource "alicloud_db_account_privilege" "privilege" {
  instance_id  = "${alicloud_db_instance.magento_db.id}"
  account_name = "${var.db_account}"
  db_names     = ["${var.database_name}"]
  privilege    = "ReadWrite"
}

variables.tfは変数とデフォルト値(存在する場合)を定義します。

variable "access_key" {

}

variable "secret_key" {

}

variable "region" {
    default = "ap-northeast-1"
}

variable "zone" {
    default = "ap-northeast-1a"
}

variable "cpu_core_count" {
    default = "2"
}

variable "memory_size" {
    default = "4"
}

variable "project_name" {
    default = "magento-demo"
}

variable "vpc_cidr" {
  default = "172.16.0.0/12"
}

variable "vswitch_cidr" {
  default = "172.16.0.0/21"
}

variable "allow_ssh_ip" {
    
}

variable "ecs_key_name" {

}

variable "db_instance_type" {
    default = "mysql.n2.medium.1"
}

variable "db_account" {
    default = "magento"
}

variable "db_password" {

}

variable "database_name" {
    default = "magento"
}

outputs.tfは作成プロセスが完了後の出力値を定義します。 Magentoを手動で構成するため、以下の情報を知っておく必要があります。

  • ECS(Elastic Compute Service) インスタンスのパブリックIPアドレス
  • ECS(Elastic Compute Service) インスタンスのプライベートIPアドレス
  • RDSMySQLインスタンスの接続情報
output "Magento-Server-Public-IP" {
  value = "${alicloud_instance.magento_instance.public_ip}"
}

output "Magento-Server-Private-IP" {
  value = "${alicloud_instance.magento_instance.private_ip}"
}

output "Magento-DB-Connection-String" {
  value = "${alicloud_db_instance.magento_db.connection_string}"
}

versions.tfはterraformのバージョン要件を定義します。

terraform {
  required_version = ">= 1.6.6"
}

config.tfvarsはデフォルト値を持たない変数の特定の値を定義します。この時点で、情報が不明の場合はあとから入力することもできますが、その際にインタラクティブ入力とすることもできます。

access_key = "xxxxxxxxxxxxxx"
secret_key = "xxxxxxxxxxxxxx"
allow_ssh_ip = "xxxxxxxxxxxxxx"
ecs_key_name = "xxxxxxxxxxxxxx"
db_password = "xxxxxxxxxxxxxx"

image.png

これらのterraform構成ファイルに加えて、ECS(Elastic Compute Service)インスタンスの準備ができたら、Magento作業環境の初期操作を定義するシェルスクリプトファイルも必要です。

Magentoクイックインストール に従って、最新のMagentoを必要に応じて更新できます。 たとえば、Alibaba Help Doc に基づいたMagento2.1.0を例とします。

#!/bin/bash

# Install Apache
echo "Apache phase" > /root/test.log
yum install httpd -y
httpd -v >> /root/test.log

# Update Apache configuration file - httpd.conf
line=`sed -n '/conf.modules.d/=' /etc/httpd/conf/httpd.conf`
sed -i "${line}a LoadModule rewrite_module modules/mod_rewrite.so\n" /etc/httpd/conf/httpd.conf
sed -i "/\"\/var\/www\/html\">/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/" /etc/httpd/conf/httpd.conf


# Start Apache service
systemctl start httpd
systemctl enable httpd

# Install PHP
echo "Php phase" >> /root/test.log
yum -y install https://repo.ius.io/ius-release-el7.rpm https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm unzip
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
yum -y install php70w php70w-pdo php70w-mysqlnd php70w-opcache php70w-xml php70w-gd php70w-mcrypt php70w-devel php70w-intl php70w-mbstring php70w-bcmath php70w-json php70w-iconv php70w-soap

php -v >> /root/test.log

# Update PHP configuration file - php.ini
sed -i '$a\\nmemory_limit = 1024M\ndate.timezone = Asia\/Tokyo' /etc/php.ini

# Restart Apache
systemctl restart httpd

# Install Composer
echo "Composer phase" >> /root/test.log
wget https://getcomposer.org/download/latest-1.x/composer.phar
chmod +x composer.phar
cp composer.phar /usr/bin/composer

# Install Git
echo "Git phase" >> /root/test.log
yum -y install git

# Install Magento
echo "Magento phase" >> /root/test.log
cd /var/www/html/
git clone https://github.com/magento/magento2.git
cd magento2 &&  git checkout tags/2.1.0 -b 2.1.0
shopt -s dotglob nullglob && mv /var/www/html/magento2/* /var/www/html/ && cd ..
chown -R :apache /var/www/html
find /var/www/html -type f -print0 | xargs -r0 chmod 640
find /var/www/html -type d -print0 | xargs -r0 chmod 750
chmod -R g+w /var/www/html/{pub,var}
chmod -R g+w /var/www/html/{app/etc,vendor}
chmod 750 /var/www/html/bin/magento

# Check Apache service status
systemctl status httpd >> /root/test.log
echo "Done Successfully" >> /root/test.log
echo "Please run 'cd /var/www/html/ && composer install' manually to finish magento installation." >> /root/test.log

terraformで実行

上記ファイルの設定が全て整ったら、次のように6ファイルあると思います。
image.png

terraform initを実行して、必要なプロバイダーをダウンロードし、作業ディレクトリを初期化します。

image.png

terraform plan -var-file="config.tfvars" でアクションプランを生成します。

image.png

上記、terraform planが問題なければ。今度は terraform apply -var-file="config.tfvars" でアクションプランを実行します。

image.png

実行が問題なく完了したら、以下のようなメッセージが出力されます。

......
Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

Outputs:

Magento-DB-Connection-String = "rm-xxxxxxxxxxx.mysql.japan.rds.aliyuncs.com"
Magento-Server-Private-IP = "xxxxx"
Magento-Server-Public-IP = "xxxxx"

image.png

このTerrafromによる実行が、Alibaba Cloud関連リソースでちゃんと反映されてるか、1つ1つずつ確認してみます。

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

Alibaba Cloud関連リソースもちゃんと作成されていますね。
それでは早速作成したECSのPublic IPをコピーしながら、Webブラウザに貼り付けてPort80で開いてみます。すると、「Autoload error Vendor autoload is not found. Please run 'composer install' under application root directory.」という画像のようなエラーが発生します。

image.png

上記で定義した allow_ssh_ipから ECS へログインします。 他のIPアドレスを使用している場合は、セキュリティグループによってブロックされます。なので、最初に ECS の /root/test.log のログを確認しておく必要があります。

image.png

ログから、「Please run 'cd /var/www/html/ && composer install' manually to finish magento installation.」 とあったので、 cd /var/www/html/ && composer installを実行して、Magentoのインストール処理を完了させます。

image.png

Magentoのインストール処理が完了したら、systemctl status httpd でステータスを確認します。無事 active (running) であれば、次のステップへ進みます。

image.png

作成したECSのPublicIPを80ポートで再度アクセスすると、Magentoセットアップウィザードが表示されます。

image.png

Magentoサーバーをインストール

Magentoセットアップウィザードの [Agree and Setup Magento] ボタンをクリックします。

image.png

Step 1の画面に入ります。[Start Readiness Check] ボタンをクリックして、 準備チェックを開始します。

image.png

Nextボタンをクリックし、Step 2の画面に入ります。Add a Databaseで、先ほどのデータベースサーバーホストの出力で Magento-DB-Connection-Stringを使用して、データベース接続を構成します。もし値を忘れた場合は、RDSインスタンス管理ページから取得できます。Database名、User、Passowordは上記のterraformの変数として定義されていますので、それに合わせて入力します。

image.png

Step 3 でWeb構成を行い、管理者アドレスを更新し、セッション情報をDBに保存します。Advanced Optionsボタンもクリックし、「Session Save」を Db に選定します。

image.png

Step 4 で構成を好きに設定します。今回はデフォルト値を使用します。

image.png

Step 5 で管理者アカウントを作成します。

image.png

tep 6、上記の構成で問題なければ、Magentoをインストールします。

image.png

インストールが無事成功したら、次のような画面になります。

image.png

Magentoストアのホームページを確認します。まだ設定していない状態なので、以下のようなページになっていると思います。

image.png

Magento の管理者管理ページを確認し、上記の手順で作成した管理者アカウントでログインします。

image.png

ログイン成功したら、このような Dashboard が表示されます。

image.png

さいごに

今回はECSとApsaraDB RDS for MySQLを使って構築しましたが、スケーラビリティを考えるなら、SAE + PolarDB、 コストを考えると、SAE + サーバレスRDSという組み合わせが良いかもしれません。Alibaba CloudでMagentoを利用をする際は、本記事を参考にいただければ幸いです。
※本当は全てSAEで構築したかったけど、SAEでTerraformに対する理解がまだ追いついてなかったので、そこは次に向けて学習中。。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?