この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
前回「Amazon VPCを使ったサーバ環境をコマンドラインツールで構築する」はAWS EC2 Command Line Toolsを使って、VPC上にサブネットとEC2、RDSインスタンスを作成しました。
前回記事内にも書きましたがコマンドラインでAWSのサービスを作成する場合、各種IDを把握するのが大変でした。VPC IDやEC2インスタンスIDなど様々なIDをコマンド引数として指定する必要があり、慣れないと予想以上に構築に時間がかかってしまいます。
そこで今回からはCloudFormationという環境構築サービスを使って、環境構築を省力化してみたいと思います。
CloudFormerについて
「CloudFormer」というのは、すでに自分がAWSに構築済みの環境からCloudFormationのテンプレートを作成してくれるツールです。CloudFormationを使うにあたり、いきなり構築の元となる「テンプレート」を作成するのは敷居が高いので、今回はCloudFormerを使ってテンプレートを作ってみます。
CloudFormerでCloudFormationのテンプレートを作成する
作成するにあたっては、すでに弊社ブログで以前とりあげた記事を参考にしてください。
この記事通り、ツールが動作するEC2インスタンスを自環境に用意し、ブラウザでツールのページにアクセスし、テンプレート化したいEC2インスタンスの選択・・・など指示通りに回答していくだけで簡単にテンプレートを作ることができました。
CloudFormerが作成したテンプレートの問題点
CloudFormerを使ってCloudFormationのテンプレートを作れましたが、作成されたテンプレートには色々問題があります。
- PrivtiateIPアドレスが固定になっている
- sshのキー名(KeyName)が固定になっている
- VPCサブネットIDが固定になっている
- VPCやサブネットのリソース作成がテンプレートに含まれていない
- ルートテーブルも作成されないのでNATへのルーティング設定が自動化されていない
- AMIのIDが固定(リージョンごとに変更したい)
- セキュリティグループの通信元(Source)に別のセキュリティグループが設定されていない
- セキュリティグループがVPCに紐付けられていない
- RDSのデータベース名が"MyDatabase"固定になっている(???)
値が固定になっているものはテンプレートに手を加えてパラメータ化してあげれば良さそうです。VPC作成まではサポートしてくれない上、サブネットIDが固定なので、そのまま流用できそうにありません。「VPCを使わないEC2を使っていいのは小学生まで」なのでこれは困りました。VPCに対応していない部分については、今後テンプレートの書き方を覚え修正することにしましょう。
まとめ
さて今回はCloudFormerを使ってCloudFormationのテンプレートを作成しました。作成されたテンプレートは再利用性が低く、またVPCも考慮していないため残念ながら実用的には使えなさそうです。
ただ、すでに自分で作成し構成を把握している環境を基にテンプレートを作ってくれるので、テンプレート内でどのようにリソースを定義しパラメータを設定しているのかなんとなく読めるのではないかと思います。CloudFormationのテンプレートに慣れるためのステップとしてCloudFormerを試してみてはいかがでしょうか。
【おまけ】作成されたテンプレート
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"eip54249103142": {
"Type": "AWS::EC2::EIP",
"Properties": {
"InstanceId": {
"Ref": "instancei3f1fcb3d"
}
}
},
"instancei3f1fcb3d": {
"Type": "AWS::EC2::Instance",
"Properties": {
"AvailabilityZone": "ap-northeast-1a",
"DisableApiTermination": "FALSE",
"ImageId": "ami-173fbf16",
"InstanceType": "t1.micro",
"KernelId": "aki-44992845",
"KeyName": "my_keypair",
"Monitoring": "false",
"Tags": [
{
"Key": "Name",
"Value": "public"
}
],
"SubnetId": "subnet-2af6e843",
"PrivateIpAddress": "10.0.0.251"
}
},
"instancei2118cc23": {
"Type": "AWS::EC2::Instance",
"Properties": {
"AvailabilityZone": "ap-northeast-1a",
"DisableApiTermination": "FALSE",
"ImageId": "ami-173fbf16",
"InstanceType": "t1.micro",
"KernelId": "aki-44992845",
"KeyName": "my_keypair",
"Monitoring": "false",
"Tags": [
{
"Key": "Name",
"Value": "private"
}
],
"SubnetId": "subnet-22f6e84b",
"PrivateIpAddress": "10.0.1.80"
}
},
"instanceifdf92eff": {
"Type": "AWS::EC2::Instance",
"Properties": {
"AvailabilityZone": "ap-northeast-1a",
"DisableApiTermination": "FALSE",
"ImageId": "ami-12d86d13",
"InstanceType": "t1.micro",
"KernelId": "aki-d209a2d3",
"KeyName": "my_keypair",
"Monitoring": "false",
"Tags": [
{
"Key": "Name",
"Value": "nat"
}
],
"SubnetId": "subnet-2af6e843",
"PrivateIpAddress": "10.0.0.63"
}
},
"rdstestdb": {
"Type": "AWS::RDS::DBInstance",
"Properties": {
"AllocatedStorage": "5",
"BackupRetentionPeriod": "0",
"DBInstanceClass": "db.t1.micro",
"DBName": "MyDatabase",
"DBParameterGroupName": "my-dbpg-test-mysql55",
"Engine": "mysql",
"EngineVersion": "5.5.27",
"MasterUsername": "testuser",
"MasterUserPassword": "testuser",
"Port": "3306",
"PreferredBackupWindow": "17:33-18:03",
"PreferredMaintenanceWindow": "fri:20:11-fri:20:41"
}
},
"sgmysgtestnat": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "SG for NAT (public subnet)",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80"
},
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22"
}
]
}
},
"sgmysgtestmysql": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "SG for test mysql (private subnet)",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "3306",
"ToPort": "3306"
}
]
}
},
"sgmysgtestpub": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "SG for test (public subnet)",
"SecurityGroupIngress": [
{
"IpProtocol": "icmp",
"FromPort": "-1",
"ToPort": "-1",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"sgmysgtestpri": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "SG for test (private subnet)",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22"
},
{
"IpProtocol": "udp",
"FromPort": "161",
"ToPort": "161"
}
]
}
}
},
"Description": "VPC environment with Public/Private subnets.\r\n1 EC2 instance and 1 RDS instance in Private Subnet.\r\n2 EC2 instances (Web and NAT) in Public subnet.",
"Outputs": {
"rdstestdbEndpoint": {
"Value": {
"Fn::GetAtt": [
"rdstestdb",
"Endpoint.Address"
]
}
}
}
}