AWS SDK for JavaからCloudFormationを使ってみる#1

2013.08.17

CloudFormationの基本

以前はプロジェクト毎に、(似たような構成であるにも関わらず)EC2インスタンス作ったりAutoScale設定したり
RDSのインスタンス作ったり等々の処理をAWSコンソールやコマンドラインから手動で実行していました。
しかし、このCloudFormationを使用すれば、そういった作業のかなりの部分を自動化できます。
今回はこのCloudFormationをJava APIから使用してみます。

なお、CloudFormationについてはここで基本から説明していますが、簡単におさらいを。

CloudFormationとは

CloudFormationとは、AWSのサービス(EC2とかSQS等)をテンプレートとして記述することにより、
いちいち各サービスを設定する手間を省略し、汎用化することが可能なサービスです。
いままで、「このAMIでEC2インスタンスつくって、RDSのつないで、セキュリティグループはこんな感じで・・・」とAWSコンソールで
毎回設定していましたが、テンプレートを用意して実行することにより、すぐに一連のシステム(スタック)として立ち上がるわけです。

CloudFormationテンプレート

CloudFormation用テンプレートは、JSON形式のテキストファイルです。
「リソース」という単位で各AWSサービスに対して処理を記述したり、任意の値を「パラメータ」として渡すことができます。
このへんも、このあたりで詳細に説明していますので、ご確認ください。

テンプレートを用意してAWSコンソールから実行することもできますが、
今回はAWS SDK for JavaのAPIを用いて、S3上に保存してあるテンプレートを実行してみましょう。

環境構築

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.5
  • AWS SDK for Java: v1.5.3

AWSアカウントは使える状態にしておいてください。

Java APIからCloudFormationテンプレートを実行

テンプレート作成

まずは、サンプルとなるテンプレートを作成しましょう。 下記のような、シンプルなテンプレートを用意します。

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters" : {
    "ParamMessage" : {
      "Type" : "String",
      "Description" : "input the message.",
      "Default"     : "defaultMessage"
    }
  },
  "Resources": {
    "createS3Bucket" : {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
      }
    }
  },
  "Outputs" : {
    "StackRegion" : {
      "Value" : { "Ref" : "AWS::Region" }
    },
    "S3BucketOutput" : {
      "Value" : { "Ref" : "createS3Bucket" }
    },
    "Message" : {
      "Value" : { "Ref" : "ParamMessage" }
    }
  }
}

Parameters要素は、AWSコンソールやAPIから受け取ることのできる動的なパラメータです。
ここでは、String型の「ParamMessage」という名前のパラメータを受け取ることが可能です。

Resourcesという要素が、CloudFormationで最低限必要な要素です。
ここのTypeプロパティで「EC2を起動する」とか「S3のバケットを作成する」という命令を記述します。
サンプルでは「AWS::S3::Bucket」というType要素を使用してS3のバケットを作成しています。

Outputs要素は、Cloudformationの実行結果を出力します。
AWSコンソールのCloudFormation画面のOutputsタブで確認することができます。
cloudformation-output

Javaから実行

次に、先ほど作成したテンプレートをS3にアップロードしておきましょう。
アップロード先は
https://s3-ap-northeast-1.amazonaws.com/pathyourbucket/hello.template
としておきます。

アップロードしたテンプレートを使用して、CloudFormationを実行するJavaクラスを下記のように作成します。
※AWS SDK for Javaをクラスパスに通しておいてください

import java.util.List;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.handlers.AsyncHandler;
import com.amazonaws.services.cloudformation.AmazonCloudFormationAsyncClient;
import com.amazonaws.services.cloudformation.model.CreateStackRequest;
import com.amazonaws.services.cloudformation.model.CreateStackResult;
import com.amazonaws.services.cloudformation.model.Parameter;

public class Main {

  public static void main(String[] args) {
    AWSCredentials credentials = new BasicAWSCredentials("アクセスキー","シークレットキー");
    AmazonCloudFormationAsyncClient cli = 
      new AmazonCloudFormationAsyncClient(credentials);
    cli.setEndpoint("cloudformation.ap-northeast-1.amazonaws.com");

    CreateStackRequest req = new CreateStackRequest();
    req.setStackName("hello-stack");
    req.setTemplateURL("S3に保存しているテンプレートのパス");

    List<Parameter> params = new ArrayList<Parameter>();
    Parameter param1 = new Parameter();
    param1.setParameterKey("ParamMessage");
    param1.setParameterValue("hello");
    params.add(param1);
    req.setParameters(params);
    
    cli.createStackAsync(req, 
      new AsyncHandler<CreateStackRequest, CreateStackResult>() {
	@Override
	public void onError(Exception e) {
	  e.printStackTrace();
	}
	@Override
	public void onSuccess(CreateStackRequest req, CreateStackResult res) {
	  System.out.println(req.toString());
	}
      });
   }
}

上記Javaプログラムでは、createStackAsyncメソッドを実行したとき、
「hello-stack」という名前で、S3上にあるテンプレートを指定してCloudformationを実行します。
※非同期で実行されます

また、Parameterクラスにkeyとvalueを指定して渡すことで、任意の値をCloudFormationテンプレートに渡すことができます。
hello.templateでは、渡されたParamMessageパラメータをOutputsで表示していますね。
※Refを使用すると、他の要素の値を参照することができます

実際にプログラムを実行してみてください。CloudFormationの実行が完了すると、S3にバケットが作られています。
バケット名については、CloudFormationが指定した名前になるので、作成したバケット名に依存する場合、
Outputsでやっているように、「{ "Ref" : "createS3Bucket" }」として作成されたバケット名を取得してください。

まとめ

今回はシンプルなテンプレートを作成して、JavaからCloudFormationを実行してみました。
CloudFormationを利用することで、AWSの環境構築も、同じことを繰り返さなくてすみますね。
また、JavaプログラムやシェルからCloudFormationを実行すれば、もっと便利に使えるので、活用してみてください。

参考サイトなど