ズンドコキヨシ with AWS CloudFormation

# 乗るしかない、このビッグウェーブに！

[ズンドコキヨシまとめ](http://qiita.com/shunsugai@github/items/971a15461de29563bf90 "まとめ")

とは言っても、大体の言語は網羅されているような気がするので、AWSのCloudFormationでやってみようかと思います。

## 必要なもの

AWSのアカウントが必要です。

# CloudFormation Lambda-backed カスタムリソース でやってみる

参考：[AWS CloudFormation ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/walkthrough-custom-resources-lambda-cross-stack-ref.html)

CloudFormationのtemplateの中でLambdaFunctionを作成し、`Custom::ZunDoCo`リソースから実行しています。


```javascript:ZunDoCo.json
{

  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"ZunDoCo Stack",
  "Parameters":{
    "Tries":{
      "Type":"Number",
      "MinValue":1
    }
  },
  "Resources":{
    "ZunDoCo":{
      "Type":"Custom::ZunDoCo",
      "Properties":{
        "ServiceToken":{"Fn::GetAtt":["ZunDoCoLambda","Arn"]},
        "Tries":{"Ref":"Tries"}
      }
    },
    "ZunDoCoLambda":{
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": {"Fn::Join": ["",[
            "var response = require('cfn-response');","\n",
            "exports.handler = function(event, context) {","\n",
            "    if(event.RequestType==='Delete'){","\n",
            "        response.send(event, context, 'SUCCESS');","\n",
            "        return;","\n",
            "    }","\n",
            "    var tries = Number(event.ResourceProperties.Tries);","\n",
            "    var success = false;","\n",
            "    var zunDoCoResult = '';","\n",
            "    var i = 0;","\n",
            "    for( ; i < tries && !success ; i++ ){","\n",
            "        for(var j = 0; j < 5; j++){","\n",
            "            zunDoCoResult += ['Zun', 'DoCo'][Math.random() * 2 | 0];","\n",
            "        }","\n",
            "        if(zunDoCoResult == 'ZunZunZunZunDoCo'){","\n",
            "            success = true;","\n",
            "        }else{","\n",
            "            zunDoCoResult = '';","\n",
            "        }","\n",
            "    }","\n",
            "    if(success){","\n",
            "        zunDoCoResult += ' ! KI-YO-SHI ! ';","\n",
            "        response.send(event, context, 'SUCCESS',{ZunDoCoResult:zunDoCoResult,Count:i + ''},'ZunDoCo');","\n",
            "    }else{","\n",
            "        response.send(event, context, 'FAILED',{Error:'You are not KIYOSHI.'},'ZunDoCo');","\n",
            "        //response.send(event, context, 'SUCCESS',{ZunDoCoResult:'You are not KIYOSHI.',Count:i + ''},'ZunDoCo');","\n",
            "    }","\n",
            "};","\n",
            ""
            ]]}
        },
        "Handler": "index.handler",
        "MemorySize": "128",
        "Runtime": "nodejs",
        "Timeout": "60",
        "Role": {"Fn::GetAtt": ["ZunDoCoLambdaRole","Arn"]}
      }
    },
    "ZunDoCoLambdaRole":{
      "Type": "AWS::IAM::Role",
      "Properties": {
        "Path": "/",
        "ManagedPolicyArns": ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              },
              "Effect": "Allow"
            }
          ]
        }
      }
    }
  },
  "Outputs":{
    "ZunDoCoResult":{
      "Value":{"Fn::GetAtt":["ZunDoCo","ZunDoCoResult"]}
    },
    "Count":{
      "Value":{"Fn::GetAtt":["ZunDoCo","Count"]}
    }
  }
}

```

`Parameters`の`Tries`の回数挑戦して、その回数の間にZunZunZunZunDoCoを達成すると、StackのOutputにあのフレーズを出力します。

<img width="733" alt="CloudFormation_Management_Console.png" src="https://qiita-image-store.s3.amazonaws.com/0/117772/913e33a6-07e6-9aad-fefe-79ac670db7d4.png">

上記の場合、４回目でキヨシを達成しています。

Triesまでにキヨシを達成できなかった場合は、StackのCreateまたはUpdateがエラーになります。

<img width="1056" alt="CloudFormation_Management_Console.png" src="https://qiita-image-store.s3.amazonaws.com/0/117772/609468c0-1d12-fb00-411e-4d6e0bf8d1a3.png">


# Update Stack

StackのUpdateで再挑戦する場合、同じjsonファイルをアップロードして、ParametersのTriesの数字を変更してください。　何も変更が無いとCloudFormationさんにエラー（何も変更がない）で怒られます。

# AWS利用料金について

ParametersのTriesにいくつを指定しても、Lambdaの実行回数は1回なので、大体の人は無料利用枠に収まっていると思います。