Alibab Cloud Terraformによる高速コンテンツ配信Webサイトの構築

作成日:2021/05/10この記事は最終更新日から1年以上が経過しています。

高速コンテンツ配信Webサイトの構築

  こちらはAlibabaCloud公式サイトにあるソリューション構築例を通じての紹介になります。従来のWebアプリケーションアーキテクチャでは、Webアプリケーションが大量のリクエストトラフィックを受け取ると、サーバーが過負荷になり、サイトが遅くなったりサーバーがクラッシュしたりする可能性があります。また地理的に異なる場所に分散していると、コンテンツが1か所から配信されるため、待ち時間の問題が発生する可能性があります。そのためにWebアプリケーションは高速でコンテンツ配信することが望ましいです。

  • グローバル配信が可能
  • 静的および動的コンテンツのアクセラレーション
  • 待ち時間の短縮などパフォーマンス改善

構成図

  TerraformでWebアプリケーションを作ってみます。ゴールの構成図は以下の通りです。

図 1

パラメータ構成

それぞれのパラメータは以下の通りです。

ネットワーク構成:

リソースリソース名パラメータ必須設定値内容
alicloud_vpcvpcvpc_name任意${var.project_name}-vpcVPC の名称。この例の場合、accelerated-content-delivery-for-terraform-vpc として表示されます。
vpccidr_block必須192.168.0.0/16VPC の CIDR ブロック
vpcdescription任意VPC for ${var.project_name}VPC の説明。この場合VPC for accelerated-content-delivery-for-terraform として表示されます。
alicloud_vswitchwebvswitch_name任意${var.project_name}-web-vswitchvswitch の名称。この例の場合、accelerated-content-delivery-for-terraform-web-vswitch として表示されます。
webvpc_id必須${alicloud_vpc.vpc.id}アタッチするVPCのID
webcidr_block必須192.168.1.0/24vswitch の CIDR ブロック
webzone_id必須${var.zone}使用するアベイラビリティゾーン
webdescription任意Enable Web-Application web vswitchvswitch の説明。
alicloud_vswitchappvswitch_name任意${var.project_name}-app-vswitchvswitch の名称。この例の場合、accelerated-content-delivery-for-terraform-app-vswitch として表示されます。
appvpc_id必須${alicloud_vpc.vpc.id}アタッチするVPCのID
appcidr_block必須192.168.2.0/24vswitch の CIDR ブロック
appzone_id必須${var.zone}使用するアベイラビリティゾーン
appdescription任意Enable Web-Application app vswitchvswitch の説明。
alicloud_vswitchdbvswitch_name任意${var.project_name}--db-vswitchvswitch の名称。この例の場合、accelerated-content-delivery-for-terraform-db-vswitch として表示されます。
dbvpc_id必須${alicloud_vpc.vpc.id}アタッチするVPCのID
dbcidr_block必須192.168.3.0/24vswitch の CIDR ブロック
dbzone_id必須${var.zone}使用するアベイラビリティゾーン
dbdescription任意Enable Web-Application db vswitchvswitch の説明。

WebのECSインスタンスセキュリティグループ構成:

リソースリソース名パラメータ必須設定値内容
alicloud_security_groupwebname任意${var.web_layer_name}-sgセキュリティグループ の名称。この例の場合、web-server_sgとして表示されます。
webvpc_id必須${alicloud_vpc.vpc.id}アタッチするVPCのID
alicloud_security_group_ruleallow_web_accesstype必須ingressセキュリティグループのタイプ。 ingress(受信) かegress(送信) のいずれかになります。
allow_web_accessip_protocol必須tcp通信プロトコル。 tcp, udp, icmp, gre, all のいずれかになります。
allow_web_accessnic_type必須intranetネットワークタイプ。 internet か intranet のいずれかになります。
allow_web_accesspolicy必須accept許可ポリシー。 acceptか drop のいずれかになります。
allow_web_accessport_range必須${var.web_instance_port}/${var.web_instance_port}通信プロトコルのポート範囲。値が「- 1/-1」の場合は無効になります。この場合、80/80になります。
allow_web_accesspriority必須1許可ポリシーの優先順位。
allow_web_accesssecurity_group_id必須${alicloud_security_group.web.id}アタッチするセキュリティグループのID
allow_web_accesscidr_ip任意0.0.0.0/0ターゲットとなるIPアドレス。デフォルトは「0.0.0.0/0」。値が「0.0.0.0/0」の場合は無制限状態となります。

WebのECSインスタンス構成:

リソースリソース名パラメータ必須設定値内容
alicloud_instanceappinstance_name任意${var.web_layer_name}-${count.index}ECSインスタンスの名称。
webhost_name任意${var.web_layer_name}-${count.index}ECSインスタンスのHost名称。
webinstance_type必須${var.web_instance_type}ECSインスタンスのタイプ。
webimage_id必須${var.web_instance_image_id}ECSインスタンスのImageID。
websecurity_groups必須${alicloud_security_group.web.id}アタッチするセキュリティグループのID。
webavailability_zone必須${var.zone}使用するアベイラビリティゾーン。
webvswitch_id必須${alicloud_vswitch.web.id}アタッチするVSwitchのID。
webpassword任意${var.ecs_password}EC インスタンスのログインパスワード。
webinternet_max_bandwidth_out任意20パブリックネットワークへの最大帯域幅。デフォルトは0ですが、0より大きい値を入れるとパブリックIPアドレスがアタッチされます。
webuser_data任意${file("${var.web_instance_user_data}")}ECSインスタンス起動後に実行するshell内容もしくはファイル名。

WebのSLB構成:

リソースリソース名パラメータ必須設定値内容
alicloud_slb_load_balancerwebload_balancer_name任意${var.web_layer_name}-slbSLBの名称。
webvswitch_id任意${alicloud_vswitch.web.id}アタッチするVSwitchのID。
webaddress_type必須internetSLB addressのインターネットタイプ。internetのインターネットにするか、intranetのイントラネットいずれかになります。
webinternet_charge_type必須paybytrafficインターネットチェンジタイプ。PayByBandwidth、PayByTrafficのいずれかになります。
webbandwidth任意5最大帯域幅。
webload_balancer_spec任意slb.s2.smallSLBのタイプ。今回は slb.s2.smallを選定します。
alicloud_slb_listenerweb_listenerload_balancer_id必須${alicloud_slb_load_balancer.web.id}新しいリスナーを起動するために使用されるロードバランサID。
web_listenerbackend_port必須${var.web_instance_port}Server Load Balancerインスタンスバックエンドが使用するポート。
web_listenerfrontend_port必須${var.web_instance_port}Server Load Balancerインスタンスフロントエンドが使用するポート。
web_listenerhealth_check_type任意tcpヘルスチェックが使用するポート。health_check_typeの代わりに使用することも可能です。
web_listenerprotocol必須http使用するプロトコル。http、https、tcp、udpのいずれかになります。
web_listenerbandwidth任意5Listenerの最大帯域幅。
alicloud_slb_attachmentwebload_balancer_id必須${alicloud_slb_load_balancer.web.id}ロードバランサID。
webinstance_ids必須${alicloud_instance.web.*.id}アタッチするECSインスタンスID。

AppのECSインスタンスセキュリティグループ構成:

リソースリソース名パラメータ必須設定値内容
alicloud_security_groupappname任意${var.app_layer_name}-sgセキュリティグループ の名称。この例の場合、app-server_sgとして表示されます。
appvpc_id必須${alicloud_vpc.vpc.id}アタッチするVPCのID
alicloud_security_group_ruleallow_app_accesstype必須ingressセキュリティグループのタイプ。 ingress(受信) かegress(送信) のいずれかになります。
allow_app_accessip_protocol必須tcp通信プロトコル。 tcp, udp, icmp, gre, all のいずれかになります。
allow_app_accessnic_type必須intranetネットワークタイプ。 internet か intranet のいずれかになります。
allow_app_accesspolicy必須accept許可ポリシー。 acceptか drop のいずれかになります。
allow_app_accessport_range必須${var.app_instance_port}/${var.app_instance_port}通信プロトコルのポート範囲。値が「- 1/-1」の場合は無効になります。この場合、80/80になります。
allow_app_accesspriority必須1許可ポリシーの優先順位。
allow_app_accesssecurity_group_id必須${alicloud_security_group.app.id}アタッチするセキュリティグループのID
allow_app_accesscidr_ip任意0.0.0.0/0ターゲットとなるIPアドレス。デフォルトは「0.0.0.0/0」。値が「0.0.0.0/0」の場合は無制限状態となります。

AppのECSインスタンス構成:

リソースリソース名パラメータ必須設定値内容
alicloud_instanceappinstance_name任意${var.app_layer_name}-${count.index}ECSインスタンスの名称。
apphost_name任意${var.app_layer_name}-${count.index}ECSインスタンスのHost名称。
appinstance_type必須${var.app_instance_type}ECSインスタンスのタイプ。
appimage_id必須${var.app_instance_image_id}ECSインスタンスのImageID。
appsecurity_groups必須${alicloud_security_group.app.id}アタッチするセキュリティグループのID。
appavailability_zone必須${var.zone}使用するアベイラビリティゾーン。
appvswitch_id必須${alicloud_vswitch.app.id}アタッチするVSwitchのID。
apppassword任意${var.ecs_password}EC インスタンスのログインパスワード。
appinternet_max_bandwidth_out任意5パブリックネットワークへの最大帯域幅。デフォルトは0ですが、0より大きい値を入れるとパブリックIPアドレスがアタッチされます。
appuser_data任意${file("${var.app_instance_user_data}")}ECSインスタンス起動後に実行するshell内容もしくはファイル名。

AppのSLB構成:

リソースリソース名パラメータ必須設定値内容
alicloud_slb_load_balancerappload_balancer_name任意${var.app_layer_name}-slbSLBの名称。
appvswitch_id任意${alicloud_vswitch.web.id}アタッチするVSwitchのID。
appaddress_type必須intranetSLB addressのインターネットタイプ。internetのインターネットにするか、intranetのイントラネットいずれかになります。
appinternet_charge_type必須paybytrafficインターネットチェンジタイプ。PayByBandwidth、PayByTrafficのいずれかになります。
appbandwidth任意5最大帯域幅。
appload_balancer_spec任意slb.s2.smallSLBのタイプ。今回は slb.s2.smallを選定します。
alicloud_slb_listenerapp_listenerload_balancer_id必須${alicloud_slb_load_balancer.app.id}新しいリスナーを起動するために使用されるロードバランサID。
app_listenerbackend_port必須${var.web_instance_port}Server Load Balancerインスタンスバックエンドが使用するポート。
app_listenerfrontend_port必須${var.web_instance_port}Server Load Balancerインスタンスフロントエンドが使用するポート。
app_listenerhealth_check_type任意tcpヘルスチェックが使用するポート。health_check_typeの代わりに使用することも可能です。
app_listenerprotocol必須tcp使用するプロトコル。http、https、tcp、udpのいずれかになります。
app_listenerbandwidth任意5Listenerの最大帯域幅。
alicloud_slb_attachmentappload_balancer_id必須${alicloud_slb_load_balancer.app.id}ロードバランサID。
appinstance_ids必須${alicloud_instance.app.*.id}アタッチするECSインスタンスID。

RDS構成:

リソースリソース名パラメータ必須設定値内容
alicloud_db_instancedb_instanceengine必須${var.db_engine}データベースタイプ。MySQL、SQLServer、PostgreSQL、PPASのいずれかになります。
db_instanceengine_version必須${var.db_engine_version}データベースのバージョン。
db_instanceinstance_type必須${var.db_instance_type}DBインスタンスタイプ。
db_instanceinstance_storage必須${var.db_instance_storage}DBインスタンスのストレージ領域。
db_instancevswitch_id必須${alicloud_vswitch.db.id}アタッチするVSwitchのID。
db_instancesecurity_ips任意10.0.2.0/24データベースへのアクセスが許可されているIPアドレスのリスト。
alicloud_db_databasedefaultname必須${var.db_layer_name}RDSの名称。この例の場合、RDS-Sample-for-Terraform として表示されます。
defaultinstance_id必須${alicloud_db_instance.db_instance.id}データベースを実行するインスタンスのID。
defaultcharacter_set必須utf8文字セット。
alicloud_db_accountdefaultdb_instance_id必須${alicloud_db_instance.db_instance.id}データベースを実行するインスタンスのID。
defaultaccount_name必須${var.db_user}運用アカウント名。
defaultaccount_password必須${var.db_password}運用アカウント名に対するパスワード。
alicloud_db_account_privilegedefaultinstance_id必須${alicloud_db_instance.db_instance.id}データベースを実行するインスタンスのID。
defaultaccount_name必須${alicloud_db_account.default.name}運用アカウント名。
defaultdb_names必須${alicloud_db_database.default.name}データベース名。
defaultprivilege必須ReadWriteアクセス権限。ReadOnly、ReadWriteのいずれかになります。
alicloud_db_connectiondefaultinstance_id必須${alicloud_db_instance.db_instance.id}データベースを実行するインスタンスのID。
defaultconnection_prefix必須alicloud-databaseインターネット接続プレフィックス。
defaultport任意3306インターネット接続ポート。

CDN構成:

リソースリソース名パラメータ必須設定値内容
alicloud_cdn_domain_newdomaindomain_name必須terraform.test.webapplication.netドメインの名称。
domaincdn_type必須webCDNのタイプ。web、download、videoのいずれかになります。
domainscope必須overseasCDNドメインの範囲。domestic、overseas、globalのいずれかになります。
domainsources必須${alicloud_slb_load_balancer.web.address}高速ドメインの送信元アドレスリスト。 リストタイプで記載。
alicloud_cdn_domain_configconfigdomain_name必須${alicloud_cdn_domain_new.domain.domain_name}ドメインの名称。
configfunction_name必須ip_allow_list_setドメイン設定の名前。
configfunction_args必須ip_list,${alicloud_slb_load_balancer.web.address}ドメイン構成の引数。

OSS構成:

リソースリソース名パラメータ必須設定値内容
alicloud_oss_bucketossbucket任意${var.project_name}-bucketバケットの名称。
ossacl任意privateアクセス制御リスト(ACL)の権限設定。

ソース

ソースは以下になります。

注意として、OSSのbucket名およびdomainは(他ユーザ含め)まだ使われてないユニーク名が必須となっていますので、各自オリジナル名称へ変更するなど調整してください。

main.tf

provider "alicloud" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
resource "alicloud_vpc" "default" {
vpc_name = "${var.project_name}-vpc"
cidr_block = "192.168.0.0/16"
description = "VPC for ${var.project_name}"
}
resource "alicloud_vswitch" "web" {
vswitch_name = "${var.project_name}-web-vswitch"
description = "Enable Web-Application web vswitch"
vpc_id = "${alicloud_vpc.default.id}"
cidr_block = "192.168.1.0/24"
zone_id = "${var.zone}"
}
resource "alicloud_vswitch" "app" {
vswitch_name = "${var.project_name}-app-vswitch"
description = "Enable Web-Application app vswitch"
vpc_id = "${alicloud_vpc.default.id}"
cidr_block = "192.168.2.0/24"
zone_id = "${var.zone}"
}
resource "alicloud_vswitch" "db" {
vswitch_name = "${var.project_name}-db-vswitch"
description = "Enable Web-Application db vswitch"
vpc_id = "${alicloud_vpc.default.id}"
cidr_block = "192.168.3.0/24"
zone_id = "${var.zone}"
}
resource "alicloud_instance" "web" {
count = "${var.web_instance_count}"
instance_name = "${var.web_layer_name}-${count.index}"
host_name = "${var.web_layer_name}-${count.index}"
instance_type = "${var.web_instance_type}"
system_disk_category = "cloud_efficiency"
image_id = "${var.web_instance_image_id}"
availability_zone = "${var.web_availability_zone}"
vswitch_id = "${alicloud_vswitch.web.id}"
security_groups = ["${alicloud_security_group.web.id}"]
internet_max_bandwidth_out = 5
password = "${var.ecs_password}"
user_data = "${file("${var.web_instance_user_data}")}"
}
resource "alicloud_slb_load_balancer" "web" {
load_balancer_name = "${var.web_layer_name}-slb"
address_type = "internet"
internet_charge_type = "paybytraffic"
vswitch_id = "${alicloud_vswitch.web.id}"
load_balancer_spec = "slb.s2.small"
bandwidth = 5
}
resource "alicloud_slb_listener" "web_listener" {
load_balancer_id = "${alicloud_slb_load_balancer.web.id}"
backend_port = "${var.web_instance_port}"
frontend_port = "${var.web_instance_port}"
protocol = "http"
bandwidth = 5
health_check_type = "tcp"
}
resource "alicloud_slb_attachment" "web" {
load_balancer_id = "${alicloud_slb_load_balancer.web.id}"
instance_ids = "${alicloud_instance.web.*.id}"
}
resource "alicloud_oss_bucket" "oss"{
bucket = "${var.project_name}-bucket"
acl = "private"
}
resource "alicloud_cdn_domain_new" "domain" {
domain_name = "terraform.test.webapplication.net"
cdn_type = "web"
scope="overseas"
sources {
content = "${alicloud_slb_load_balancer.web.address}"
type = "ipaddr"
priority = "20"
port = 80
weight = "15"
}
}
resource "alicloud_cdn_domain_config" "config" {
domain_name = "${alicloud_cdn_domain_new.domain.domain_name}"
function_name = "ip_allow_list_set"
function_args {
arg_name = "ip_list"
arg_value = "${alicloud_slb_load_balancer.web.address}"
}
}
resource "alicloud_security_group" "web" {
name = "${var.web_layer_name}-sg"
vpc_id = "${alicloud_vpc.default.id}"
}
resource "alicloud_security_group_rule" "allow_web_access" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "${var.web_instance_port}/${var.web_instance_port}"
priority = 1
security_group_id = "${alicloud_security_group.web.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_instance" "app" {
count = "${var.app_instance_count}"
instance_name = "${var.app_layer_name}-${count.index}"
host_name = "${var.web_layer_name}-${count.index}"
instance_type = "${var.app_instance_type}"
system_disk_category = "cloud_efficiency"
image_id = "${var.app_instance_image_id}"
availability_zone = "${var.app_availability_zone}"
vswitch_id = "${alicloud_vswitch.app.id}"
security_groups = ["${alicloud_security_group.app.id}"]
internet_max_bandwidth_out = 5
password = "${var.ecs_password}"
user_data = "${file("${var.app_instance_user_data}")}"
}
resource "alicloud_slb_load_balancer" "app" {
load_balancer_name = "${var.app_layer_name}-slb"
address_type = "intranet"
internet_charge_type = "paybytraffic"
vswitch_id = "${alicloud_vswitch.app.id}"
load_balancer_spec = "slb.s2.small"
bandwidth = 5
}
resource "alicloud_slb_listener" "app_listener" {
load_balancer_id = "${alicloud_slb_load_balancer.app.id}"
backend_port = "${var.app_instance_port}"
frontend_port = "${var.app_instance_port}"
protocol = "tcp"
bandwidth = 5
health_check_type = "tcp"
}
resource "alicloud_slb_attachment" "app" {
load_balancer_id = "${alicloud_slb_load_balancer.app.id}"
instance_ids = "${alicloud_instance.app.*.id}"
}
resource "alicloud_security_group" "app" {
name = "${var.web_layer_name}-sg"
vpc_id = "${alicloud_vpc.default.id}"
}
resource "alicloud_security_group_rule" "allow_app_access" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "${var.app_instance_port}/${var.app_instance_port}"
priority = 1
security_group_id = "${alicloud_security_group.app.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_db_instance" "db_instance" {
engine = "${var.db_engine}"
engine_version = "${var.db_engine_version}"
instance_type = "${var.db_instance_type}"
instance_storage = "${var.db_instance_storage}"
vswitch_id = "${alicloud_vswitch.db.id}"
security_ips = ["10.0.2.0/24"]
}
resource "alicloud_db_database" "default" {
name = "${var.db_layer_name}"
instance_id = "${alicloud_db_instance.db_instance.id}"
character_set = "utf8"
}
resource "alicloud_db_account" "default" {
db_instance_id = "${alicloud_db_instance.db_instance.id}"
account_name = "${var.db_user}"
account_password = "${var.db_password}"
}
resource "alicloud_db_account_privilege" "default" {
instance_id = "${alicloud_db_instance.db_instance.id}"
account_name = "${alicloud_db_account.default.name}"
db_names = ["${alicloud_db_database.default.name}"]
privilege = "ReadWrite"
}
resource "alicloud_db_connection" "default" {
instance_id = "${alicloud_db_instance.db_instance.id}"
connection_prefix = "alicloud-database"
port = "3306"
}

variables.tf

variable "access_key" {}
variable "secret_key" {}
variable "region" {}
variable "zone" {}
variable "project_name" {}
variable "ecs_password" {}
variable "db_user" {}
variable "db_password" {}
variable "web_layer_name" {}
variable "web_instance_count" {}
variable "web_availability_zone" {}
variable "web_instance_type" {}
variable "web_instance_port" {}
variable "web_instance_image_id" {}
variable "web_instance_user_data" {}
variable "app_layer_name" {}
variable "app_instance_count" {}
variable "app_availability_zone" {}
variable "app_instance_type" {}
variable "app_instance_port" {}
variable "app_instance_image_id" {}
variable "app_instance_user_data" {}
variable "db_layer_name" {}
variable "db_availability_zone" {}
variable "db_engine" {}
variable "db_engine_version" {}
variable "db_instance_type" {}
variable "db_instance_storage" {}

confing.tfvars

access_key = "xxxxxxxxxxxxxxxx"
secret_key = "xxxxxxxxxxxxxxxx"
region = "ap-northeast-1"
zone = "ap-northeast-1a"
project_name = "accelerated-content-delivery-for-terraform"
ecs_password = "!Password2019"
db_user = "test_user"
db_password = "!Password2019"
web_layer_name = "web-server"
web_availability_zone = "ap-northeast-1a"
web_instance_count = 3
web_instance_type = "ecs.sn1ne.large"
web_instance_port = 80
web_instance_image_id = "centos_7_06_64_20G_alibase_20190218.vhd"
web_instance_user_data = "provisioning.sh"
app_layer_name = "app-server"
app_availability_zone = "ap-northeast-1a"
app_instance_count = 3
app_instance_type = "ecs.sn1ne.large"
app_instance_port = 5000
app_instance_image_id = "centos_7_06_64_20G_alibase_20190218.vhd"
app_instance_user_data = "provisioning.sh"
db_layer_name = "db-server"
db_availability_zone = "ap-northeast-1a"
db_engine = "MySQL"
db_engine_version = "5.7"
db_instance_type = "rds.mysql.s1.small"
db_instance_storage = 10

output.tf

output "slb_web_public_ip" {
value = "${alicloud_slb_load_balancer.web.address}"
}
output "ECS_instance_app_ip" {
value = "${alicloud_instance.app.*.public_ip}"
}
output "ECS_instance_web_ip" {
value = "${alicloud_instance.web.*.public_ip}"
}
output "rds_host" {
value = "${alicloud_db_instance.db_instance.connection_string}"
}

provisioning.sh

#!/bin/sh
yum install -y httpd
systemctl start httpd
systemctl enable httpd

実行

  ソースの準備ができたら実行します。

terraform init
terraform plan -var-file="confing.tfvars"
terraform apply -var-file="confing.tfvars"

これで完了です。問題なく実行できたら、ECSとSLBそれぞれのIP、RDS Hostが表示されます。

Close

Alibaba Cloudを始めてみましょう

ソフトバンクは、Alibaba Cloudのアカウント開設から、サービス展開までをお手伝いします。
Hatena
このページは参考になりましたか?