AWS SDK for Javaを使ってIAM Roleの動作確認をする

IAM Roleの動作確認

以前、dynodeなどの非AWS謹製SDKを使ってIAM Roleの動作確認をしようとおもったら、やはりよろしく対応してくれていなくて困りました。そこで、今回は、AWS謹製のAWS SDK for Javaを使ってIAM Roleを使うと本当にCredential指定が必要ないのか!?を検証したいと思います。動作確認するEC2インスタンスは、事前にIAM Role指定で起動しておいてください。ポリシーは無しでお願いします。

AWS SDK for Javaのセットアップ

まずはJava開発用のインストール

$ sudo yum install ant
$ sudo yum install java-1.6.0-openjdk-devel
$ javac -version
javac 1.6.0_22

そして、AWS SDK for Javaのダウンロード

$ wget http://sdk-for-java.amazonwebservices.com/latest/aws-java-sdk.zip
$ unzip aws-java-sdk.zip

これで下準備完了です。

Credential指定を外す

AWS SDK for Javaのサンプルプログラムを例にCredential指定を外したいと思います。今回は、DynamoDBのサンプルであるAmazonDynamoDBSample.javaを例にとります。

$ cd aws-java-sdk-1.3.11/samples/AmazonDynamoDB/
$ vi AmazonDynamoDBSample.java

initメソッドの中でCredential指定している部分をコメントアウトします。次に、ついでにEndpointを東京リージョンにします。って、リージョン指定もよろしく同じにしてほしいところです。

    private static void init() throws Exception {
        //AWSCredentials credentials = new PropertiesCredentials(
        //AmazonDynamoDBSample.class.getResourceAsStream("AwsCredentials.properties"));
        //dynamoDB = new AmazonDynamoDBClient(credentials);
        
        dynamoDB = new AmazonDynamoDBClient();
        dynamoDB.setEndpoint("https://dynamodb.ap-northeast-1.amazonaws.com");
    }

Antで実行

そしてAntコマンドを実行すると、以下のようにエラーになりました。AccessDeniendということで期待通りです。これは、IAM Roleの設定をしていないからです。

$ ant                                
Buildfile: build.xml                                                            

run:
      Caught an AmazonServiceException, which means your request made it to AWS, but was rejected with an error response for some reason.
      Error Message:    
      HTTP Status Code: 400
      AWS Error Code:   AccessDeniedException
      Error Type:       Client
      Request ID:       ME2HGJS27FC67AKJKV4MRBBGB3VV4KQNSO5AEMVJF66Q9ASUAAJG

BUILD SUCCESSFUL
Total time: 3 seconds

以下はIAM Roleの画面でEC2インスタンスに付与したRoleのポリシー一覧です。何もありません。

そこで、DynamoDBへのアクセスポリシーを追加します。

ポリシー一覧からDynamoDBへのアクセス権限をもったポリシーを作成します。

はい、ポリシー付与完了です。

それでは、改めてantを使って動作確認します。

$ ant
Buildfile: build.xml

run:
      Created Table: {TableName: my-favorite-movies-table, KeySchema: {HashKeyElement: {AttributeName: name, AttributeType: S, }, }, TableStatus: CREATING, CreationDateTime: Thu Jun 21 18:53:12 UTC 2012, ProvisionedThroughput: {ReadCapacityUnits: 10, WriteCapacityUnits: 10, }, }
      Waiting for my-favorite-movies-table to become ACTIVE...
        - current state: CREATING
        - current state: ACTIVE
      Table Description: {TableName: my-favorite-movies-table, KeySchema: {HashKeyElement: {AttributeName: name, AttributeType: S, }, }, TableStatus: ACTIVE, CreationDateTime: Thu Jun 21 18:53:12 UTC 2012, ProvisionedThroughput: {ReadCapacityUnits: 10, WriteCapacityUnits: 10, }, TableSizeBytes: 0, ItemCount: 0, }
      Result: {ConsumedCapacityUnits: 1.0, }
      Result: {ConsumedCapacityUnits: 1.0, }
      Result: {Items: [{fans={SS: [James, Sara], }, name={S: Bill & Ted's Excellent Adventure, }, year={N: 1989, }, rating={S: ****, }}], Count: 1, ScannedCount: 2, ConsumedCapacityUnits: 0.5, }

BUILD SUCCESSFUL
Total time: 44 seconds

成功しましたね〜

まとめ

Credential指定無しで確かにアクセスすることができました!一切Credential情報を記述する事無く、起動するインスタンス毎にIAM Roleでポリシーを設定できるので、自作AMI公開時に機密情報が漏れる心配もありません。益々使いやすくなりましたね。今回、実はAWS Beanstalkでやろうと思ったのですが、IAM Roleの設定項目を管理コンソールから確認できなくてJavaの設定から行いました。Javaってクラスパスの設定が面倒ですね。Ant書くのも面倒。サクっと全自動でできないものでしょうか。最近はnode.jsに慣れすぎたかなw

参考資料

AWS SDK for Java

【AWS発表】IAM roles for EC2 instances – シンプルに安全にEC2からAWSサービスのAPIにアクセス可能に