MTI Engineer Blog

エムティーアイ エンジニアブログ

CloudFormationがCognito対応したので試してみた(前編)

こんにちは、抜歯直後で口内環境最悪なエンジニアの最上です。今回は、タイトル通り、CloudFormationがついに!待ちに待った!Cognito対応をしたので早速試してみました!

下記の通り、2段組で記事にしたいと思います。

CloudFormationとは

簡単に言うと、AWSのインフラをコードで書けるAWSのサービスです。Infrastructure as Codeなんて言われています。最近、私が所属しているチーム(って言ってもNaoya Kobayashiさんと2人チームですが)では、Infrastructure as Codeに取り組んでいます。私個人が感じているメリットは下記です。

  • ヒューマンエラーがほぼ撲滅できる
  • 一度書いてしまえば、何回でもコマンド1つで同じ環境が作れる
  • 新規案件にインフラコードを使いまわせる

これらのメリットを享受できるのは非常に大きいのではないでしょうか。

Cognitoとは

簡単に言うと、AWSの認証認可サービスの総称です。Cognitoを使うと、認証や認可機能を自サービスへそこそこ簡単に組み込むことが出来ます。Cognitoは下記2つのサービスを内包しています。

  • UserPools
    • 独自の認証基盤を提供できる
  • Federated Identities
    • 認証/未認証ユーザーへAWSリソースを認可できる
    • 認証基盤を選択でき、UserPoolsはもちろん、Facebook,Twitter,Amazon,Googleなどと組み合わせることも可能

今までは、Cognitoを画面ポチポチでつくっていました。それが非常にめんどくさく、特に手順書を書くのが非常にめんどくさかった。しかし!今回、CloudFormationが対応してくれたので、そのめんどくささから開放されます!わーい!

実践

前編では、UserPoolsのみを作成していきます。公式ドキュメントを参考につくってみるとこんな感じになりました。

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": {
    "PoolName": {
      "Description": "user pool name",
      "Type": "String"
    },
    "isUserCreatedByAdminOnly": {
      "Description": "is user account created by admin only?",
      "Type": "String",
      "AllowedValues": ["true", "false"],
      "Default": "true"
    }
  },
  "Resources": {
    "UserPool": {
      "Type": "AWS::Cognito::UserPool",
      "Properties": {
        "AdminCreateUserConfig": {
          "AllowAdminCreateUserOnly": {
            "Ref": "isUserCreatedByAdminOnly"
          },
          "InviteMessageTemplate": {
            "EmailMessage": "ID: {username}\nPassword: {####}",
            "EmailSubject": "Your Temporary Password"
          }
        },
        "AutoVerifiedAttributes": ["email"],
        "MfaConfiguration": "OFF",
        "Policies": {
          "PasswordPolicy": {
            "MinimumLength": 8,
            "RequireLowercase": true,
            "RequireUppercase": true,
            "RequireNumbers": true,
            "RequireSymbols": false
          }
        },
        "UserPoolName": {
          "Ref": "PoolName"
        },
        "Schema": [{
          "Name": "email",
          "Required": true
        }, {
          "Name": "name",
          "Required": true
        }]
      }
    }
  },
  "Outputs": {
    "UserPoolID": {
      "Description": "UserPoolID",
      "Value": {
        "Ref": "UserPool"
      }
    }
  }
}

Parametersに、「UserPoolの名前」と、「このPoolにユーザーを作っていいのは誰か」を取っています。後者は、SNSのような自由にSignUpができるようにしたい場合はfalse、管理ツールのような、管理者のみがユーザーアカウントを発行できるようにしたい場合はtrueにすればよいようになっています。個人的に、この部分を切り替えることが多いので、外出しておきました。

Resourcesは、他にも様々なPropertiesが存在しますが、ひとまず最低限の設定をしています。よく触りそうな部分としては、PoliciesやSchemaでしょうか。PoliciesはParametersに外出しても良いかもしれません。Schemaは、これこそParametersから与えられるようにしたい。ただ、SchemaはObjectの配列で、Parametersにはここに載っている型しか渡せないため、どうにもならん気がしています(各AttributeのRequiredを外出ししておけばやってやれないこともないか…?CustomAttributesに対応できないけど…)。

Outputsでは、CloudFormationによって作成されたUserPoolのIDを出力するようにしています。SDKに渡してあげるのはこの部分なので、出力しておきました。

コピペして使えるようになっているので、試してみたい方はJSONファイルとして保存して、CloudFormationに渡してあげてください。

おわりに

我々のチームでは、本当に待望していた部分なので、嬉しすぎて休日にも関わらず起きてすぐに試してしまっています。これから使い倒しちゃうぜー!

おわり。