LoginSignup
5
5

More than 5 years have passed since last update.

KinesisRecorder + CognitoのIAM Roleでハマった

Last updated at Posted at 2015-01-11

この記事は個人のメモであり、私の所属する組織を代表するものではありません。また、記事中のコード片はすべてMITライセンスのもの提供されるものとします。

背景

KinesisRecorder + Cognitoを利用してデータをPutする際に以下のようなIAM Roleのパーミッション設定をしてたらハマったのでメモ。このパーミッションだと、Androidでは動くけどiOSではIAMの権限不足のエラーが発生する。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1420887713000",
      "Effect": "Allow",
      "Action": [
        "kinesis:PutRecord"
      ],
      "Resource": [
        "arn:aws:kinesis:ap-northeast-1:YOUR_ACCOUNT_ID:stream/YOUR_STREAM"
      ]
    }
  ]
}

iOSのKinesisRecorderはPutRecordsを使っていた!

コードを見てみたら、Android版のKinesisRecorderはPutRecord API、iOS版のKinesisRecorderはPutRecords APIを使っているというオチだった。冒頭に書いたIAM RoleのパーミッションだとPutRecords APIは許可されていないのでうまく動いていなかったという話だった。

Android
https://github.com/aws/aws-sdk-android/blob/9d5728c355c4d7510ae161b95f40092fa34be117/src/com/amazonaws/mobileconnectors/kinesis/kinesisrecorder/KinesisRecorder.java#L177

iOS
https://github.com/aws/aws-sdk-ios/blob/master/Kinesis/AWSKinesisRecorder.m#L309

解決策

なんてほどのたいそうなものではないけど、当該IAM Roleに対してPutRecord、PutRecords両方とも実行パーミッションを与えておけばOKという話でした。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1420887713000",
      "Effect": "Allow",
      "Action": [
        "kinesis:PutRecord",
        "kinesis:PutRecords"
      ],
      "Resource": [
        "arn:aws:kinesis:ap-northeast-1:YOUR_ACCOUNT_ID:stream/YOUR_STREAM"
      ]
    }
  ]
}

参考

検証につかったコードを貼っておく

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    AWSCognitoCredentialsProvider *credentialsProvider = [AWSCognitoCredentialsProvider
                                                          credentialsWithRegionType:AWSRegionUSEast1
                                                          accountId:@"YOUR_ACCOUNT_ID"
                                                          identityPoolId:@"YOUR_IDENTITY_POOL_ID"
                                                          unauthRoleArn:@"YOUR_ROLE_ARN"
                                                          authRoleArn:nil];

    AWSServiceConfiguration *configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionAPNortheast1
                                                            credentialsProvider:credentialsProvider];
    [AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
    self.kinesis = [AWSKinesis defaultKinesis];
    self.kinesisRecorder = [AWSKinesisRecorder defaultKinesisRecorder];
}

- (IBAction)putRecord:(id)sender {   
    NSMutableArray *tasks = [NSMutableArray new];
    for (int32_t i = 0; i < 100; i++) {
        [tasks addObject:[self.kinesisRecorder saveRecord:[[NSString stringWithFormat:@"TestString-%02d", i] dataUsingEncoding:NSUTF8StringEncoding]
                                          streamName:@"YOUR_STREAM"]];
    }
    [[[BFTask taskForCompletionOfAllTasks:tasks] continueWithSuccessBlock:^id(BFTask *task) {
        return [self.kinesisRecorder submitAllRecords];
    }] continueWithBlock:^id(BFTask *task) {
        if (task.error) {
            NSLog(@"Error: [%@]", task.error);
        }
        return nil;
    }];
}

@end
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5