[新機能] AWS OpsWorksをCloudFormationでまとめて作成する
ども、大瀧です。
今朝かた、AWSコンポーネントを自動作成するAWS CloudFormationがAWS OpsWorksをサポートしました。
「CloudFormationとOpsWorksって役割がかぶってない?」と思われる方もいるかもしれませんが、おおむね管理するレイヤーによって棲み分けができていて、両方を上手く組み合わせることが可能です。以下の図のように、OpsWorksはEC2の内部で構成するLinux/ミドルウェア/アプリケーションをChefで効率よく管理することができ、CloudFormationはRDS/DynamoDB(データベース)やS3(ストレージ)、VPC(ネットワーク)など複数のAWSサービスを管理するのに向いています *1。
従来はOpsWorksを利用するために事前にVPCやセキュリティグループなどを準備する必要があり、その整合性も管理者が自分で調整する必要がありました。今回の連携によって、OpsWorksはより密接にAWSの全体構成と連携することができるようになります。工夫すれば、CloudFormationでRDSやS3を作り、それらへの接続設定をOpsWorksでアプリに自動デプロイするなんてことも仕組みとして実装できそうです。
サンプルテンプレート
AWSより、OpsWorksの各コンポーネントを作成するサンプルテンプレートが公開されています。こちらを試してみました。
https://s3.amazonaws.com/cloudformation-templates-us-east-1/OpsWorks.template
{ "AWSTemplateFormatVersion": "2010-09-09", "Description" : "AWS CloudFormation Sample Template: Launches OpsWorks stack, layer, instances and associated resources to run a PHP application. ** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.", "Resources": { "myStack": { "Type": "AWS::OpsWorks::Stack", "Properties": { "Name": { "Ref": "AWS::StackName" }, "ServiceRoleArn": { "Fn::GetAtt": [ "OpsWorksServiceRole", "Arn"] }, "DefaultInstanceProfileArn": { "Fn::GetAtt": [ "OpsWorksInstanceProfile", "Arn"] } } }, "myLayer": { "Type": "AWS::OpsWorks::Layer", "DependsOn": "myApp", "Properties": { "StackId": { "Ref": "myStack" }, "Name": "MyPHPApp", "Type": "php-app", "Shortname": "php-app", "EnableAutoHealing": "true", "AutoAssignElasticIps": "false", "AutoAssignPublicIps": "true" } }, "myInstance1": { "Type": "AWS::OpsWorks::Instance", "Properties": { "StackId": { "Ref": "myStack" }, "LayerIds": [ { "Ref": "myLayer" } ], "InstanceType": "m1.small" } }, "myInstance2": { "Type": "AWS::OpsWorks::Instance", "Properties": { "StackId": { "Ref": "myStack" }, "LayerIds": [ { "Ref": "myLayer" } ], "InstanceType": "m1.small" } }, "myApp": { "Type": "AWS::OpsWorks::App", "Properties": { "StackId": { "Ref": "myStack" }, "Name": "MyPHPApp", "Type": "php", "AppSource": { "Type": "git", "Url": "git://github.com/amazonwebservices/opsworks-demo-php-simple-app.git", "Revision": "version1" }, "Attributes": { "DocumentRoot": " " } } }, "OpsWorksServiceRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "opsworks.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/", "Policies": [ { "PolicyName": "opsworks-service", "PolicyDocument": { "Statement": [ { "Effect": "Allow", "Action": [ "ec2:*", "iam:PassRole", "cloudwatch:GetMetricStatistics", "elasticloadbalancing:*" ], "Resource": "*" } ] } } ] } }, "OpsWorksInstanceRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/" } }, "OpsWorksInstanceProfile": { "Type": "AWS::IAM::InstanceProfile", "Properties": { "Path": "/", "Roles": [ { "Ref": "OpsWorksInstanceRole" } ] } } }, "Outputs" : { "StackId" : { "Value" : { "Ref" : "myStack" } }, "AppId" : { "Value" : { "Ref" : "myApp" } } } }
テンプレートの実行は、従来のCloudFormationの操作と特に変わりません。
CloudFormationスタックが作成されると、OpsWorksの各コンポーネントが作成されていきます。「スタック」というコンポーネントはCloudFormationとOpsWorks両方にあり(どちらも最上位のコンテナを指す)、今後はCFnスタック、OWスタックなどと区別して呼ばないと大混乱を招きそうですw
CloudFormationのリソース一覧画面
もちろん、OpsWorksの画面でもちゃんと確認できます。
OpsWorksのスタック管理画面
...ん、最後のデプロイは手動でやるしかないのかな?また、Update Stackする場合のOpsWorks側の動きは検証する必要がありそうです。あと、地味にすごいのがリージョンを意識する必要がない点です。AMIは各レイヤーで吸収できますし、セキュリティグループもOpsWorks既定のグループが各リージョンに作成されているためです。もちろん、カスタマイズしたAMIやセキュリティグループを使う場合は、実行するリージョンに事前作成する必要があります。
CloudFormationリファレンスを見ましょう
具体的に、どんな構成ができるのかはCloudFormationのテンプレートリファレンスを参照しましょう。
OpsWorksのスタック、レイヤー、インスタンス、アプリケーションなどの定義をそれぞれ確認できます。
まとめ
CloudFormationテンプレートにOpsWorksを定義する様子をご紹介しました。なかなか作り込みが大変なサービスだとは思いますが、一度作ってしまえば運用が格段に楽になる仕組みだと思いますので、みなさんもぜひ評価してみてください!
また、最近公開されたKumogataなどのツールと組み合わせてもいいかもしれません。
参考URL
脚注
- CloudFormationにも、ユーザーデータやCfn-initなどLinux/ミドルウェアを管理する仕組みがあります。 ↩