はじめに
Lambdaを使って別アカウントのDynamoDBにputItemする際にハマったことをメモ。
DynamoDBにputItemするのは初めてだったので、
事前に同一アカウントのDynamoDBにputItemをした。
やったこと
- Lambdaから同一アカウントのDynamoDBにputItem
- LambdaからSTSを使って別アカウントのDynamoDBにputItem
Lambdaから同一アカウントのDynamoDBにputItem
AWS.DynamoDBクラスを使用
const AWS = require('aws-sdk');
exports.handler = async (event, context) => {
const dynamodb new AWS.DynamoDB()
const param = {
TableName: "テーブル名",
Item: {
"name": { S: "tuaaasa" },
"age": { N: 23 }
}
};
await dynamodb.putItem(param, (err, data) => {
if(err) console.log(err);
else console.log(data);
});
};
問題なく送信されました。
LambdaからSTSを使って別アカウントのDynamoDBにputItem
今回は別アカウントのため、STSを使い別アカウントから許可されたロールを利用する。
AWS.DynamoDB.DocumentClientクラスを使用して、こんな感じで実装。
const AWS = require('aws-sdk');
const arn = "別アカウントから許可されたロールARN";
const myAccountId = '自分のアカウントID';
exports.handler = async (event, context) => {l;
const sts = new AWS.STS();
const role = await sts.assumeRole({
RoleArn: '別アカウントから許可されたロールARN',
RoleSessionName: 'test'
});
const credentials = new AWS.Credentials(
role.Credentials.AccessKeyId,
role.Credentials.SecretAccessKey,
role.Credentials.SessionToken
);
const dynamodb new AWS.DynamoDB.DocumentClient({ credentials });
const param = {
TableName: "テーブル名",
Item: {
"name": { S: "tuaaasa" },
"age": { N: 23 }
}
};
await dynamodb.putItem(param, (err, data) => {
if(err) console.log(err);
else console.log(data);
});
};
TypeError: dynamodb.putItem is not a function
で怒られた。
ドキュメントをよくみてみると、
DocumentClient
の場合はput
メソッドのようだ。
...
const param = {
TableName: "テーブル名",
Item: {
"name": { S: "tuaaasa" },
"age": { N: 23 }
}
};
await dynamodb.put(param, (err, data) => { // putに修正
if(err) console.log(err);
else console.log(data);
});
今度はこんなエラーで怒られた。
"One or more parameter values were invalid: Type mismatch for key id expected: S actual: M","code":"ValidationException"
Itemの型が合っていない模様。
しかしname
は文字列型でage
は数値型で間違っているはずがない...
ハマりポイント
AWS.DynamoDB.DocumentClientクラスをよく見ると、param
で指定するItem
のJSON構造が違った。
// AWS.DynamoDBクラスの場合
const param = {
TableName: "テーブル名",
Item: {
"name": { S: "tuaaasa" },
"age": { N: 23 }
}
};
// AWS.DynamoDB.DocumentClientクラスの場合
const param = {
TableName: "テーブル名",
Item: {
"name": "tuaaasa",
"age": 23
}
};
AWS.DynamoDB.DocumentClient
クラスを扱う場合はItem
に型と値のオブジェクトにしないことです。
おわりに
ちゃんとドキュメントは読みましょう(自戒)。