CloudFormation -> SNS -> Lambdaでスタック作成完了を拾おうとしたら辛かった話


CloudFormation -> SNSで飛んでくる情報ってJSONじゃないんですね・・・

##SNSからLambaにくる値サンプル
綺麗なJSONに見えますよね。
これなら簡単に処理できる。そう思っていました。

```
{
	"Records": [{
		"EventVersion": "1.0",
		"EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
		"EventSource": "aws:sns",
		"Sns": {
			Type: "Notification",
			MessageId: "59228c23-0c0d-5be3-8675-c3ec2e03ccbf", 
			TopicArn: "arn:aws:sns:us-east-1:213144662080:cfn_status",
			Subject: "AWS CloudFormation Notification",
			Message: "StackId=\'arn:aws:cloudformation:us-east-1:XXXXXXXXXX:stack/STACK_NAME/XXXX-XXXX-XXXX-XXXX-500c28903236\'\nTimestamp=\'2016-06-06T07:01:34.020Z\'\nEventId=\'8112f630-XXX-XXXX-XXXX-500c524294f2\'\nLogicalResourceId=\'Stack_Name\'\nNamespace=\'XXXXXXXXXXX\'\nPhysicalResourceId=\'arn:aws:cloudformation:us-east-1:XXXXXXXXXX:stack/STACK_NAME/XXXX-XXXX-XXXX-XXXX-500c28903236\'\nPrincipalId=\'AIDAJWZPQQKJL65BSP6G6\'\nResourceProperties=\'null\'\nResourceStatus=\'CREATE_COMPLETE\'\nResourceStatusReason=\'\'\nResourceType=\'AWS::CloudFormation::Stack\'\nStackName=\'STACK_NAME\'\n",
			Timestamp: "2016-06-06T07:01:34.177Z",
			SignatureVersion: "1",
			Signature: "CUyu+MTkfGba0R/DaRP9CD5zUJbzcLzROxPM83DOh7HDS8X24Yj9DWM08ucwqlgRPe+nwGxhOsFrSH6r83ANy5gMuJlanj6m6YT/TGqKHnnbTSJKDIR2bGfoG2trJu6NWZYNV+HDIYXSJ5QfS6m77AzeXfTKhCjJWztU5TW7jTm1P6bhCh++pET342EppxWtTEesCld/NpDl3i0wJWmZJLkZNKG1TLSOD6wGViSI077wskb+1N+UMnyU/jgL+7cEFrm9Ptnb3LfgoTQtf9OalgERTYmmt6Yyi4lk9v38rZRFvtv8kYmOBT9CKiI0RVqIpXSrduXZ0qnl/B7QgKMqng==", 
			SigningCertUrl: "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-bb750dd426d95ee9390147a5624348ee.pem", 
			UnsubscribeUrl: "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:213144662080:cfn_status:0c1d0e0f-ace4-4f9f-bdac-db75152aa500", 
			MessageAttributes: {}
		}
	}]
}
```

しかしよく見ると一番知りたい部分がstringになってるんです。

```
Message: "StackId=\'arn:aws:cloudformation:us-east-1:XXXXXXXXXX:stack/STACK_NAME/XXXX-XXXX-XXXX-XXXX-500c28903236\'\nTimestamp=\'2016-06-06T07:01:34.020Z\'\nEventId=\'8112f630-XXX-XXXX-XXXX-500c524294f2\'\nLogicalResourceId=\'Stack_Name\'\nNamespace=\'XXXXXXXXXXX\'\nPhysicalResourceId=\'arn:aws:cloudformation:us-east-1:XXXXXXXXXX:stack/STACK_NAME/XXXX-XXXX-XXXX-XXXX-500c28903236\'\nPrincipalId=\'AIDAJWZPQQKJL65BSP6G6\'\nResourceProperties=\'null\'\nResourceStatus=\'CREATE_COMPLETE\'\nResourceStatusReason=\'\'\nResourceType=\'AWS::CloudFormation::Stack\'\nStackName=\'STACK_NAME\'\n",
```

しかも別にJSON.parseとかで変換できる系でもないやつが入ってます。

結局splitで切り刻みまくってとりあえず対応しました。

```index.js
'use strict';
console.log('Loading function');

exports.handler = (event, context, callback) => {
    //console.log('Received event:', JSON.stringify(event, null, 2));
    var message = event.Records[0].Sns.Message;
    
    //Resouce Status
    var resourceStr = message.split( "ResourceStatus=\'" );
    console.log(resourceStr);
    resourceStr = resourceStr[1].split( "\'\nResourceStatusReason" );
    var resourceStatus = resourceStr[0];
    console.log(resourceStatus);
    
    //Resouce Type
    var resourceTypeStr = resourceStr[1].split( "ResourceType=\'" );
    resourceTypeStr = resourceTypeStr[1].split( "\'\nStackName=\'" );
    var resourceType = resourceTypeStr[0];
    
    //Stack Name
    var stackNameStr = resourceTypeStr[1].split( "'" );
    var stackName = stackNameStr[0];
    console.log(stackName);
    
    if ( resourceType == 'AWS::CloudFormation::Stack' && resourceStatus == 'CREATE_COMPLETE' ) {
        console.log('Stack: ' + stackName + ' is created!');
        //ここにスタック作成成功時にやりたいことを書く
    }
    
    callback(null, message);
};
```

あまり良い手ではないと思いますが、とりあえずしばらくこれでやってみます。