Route53のヘルスチェック情報で月間合計ダウンタイムと稼働率を計算してみた

はじめに AWSチームのすずきです。 AWSが提供するDNSサービスのRoute53が備えるヘルスチェックを利用して、 Webサービスの月間の合計ダウンタイム時間を求め、 SLAなどの基準となる月間稼働率の計算を試みる機 […] 続きを読む

【モバイル事業】Cloud Engineer, AWS

【必須】□AWS DynamoDB or RDS, EBS or S3, EC2, ElastiCache での、 クラウドネイティブの運用経験 □AWS CloudWatch, Config でのモニタリング経験【ドワンゴでエンジニアとして働く魅力】 □自宅にサーバーを立てたり、オープンソースコミュニティに参加する など、プライベートでも最新技術に触れている社員が数多く … 続きを読む

イントロダクション 練習問題 問8

前へ|次へ ▷ リソース使用率、アプリケーションパフォーマンス、およびヘルスチェックをシステム全体で把握するには、どのAWSクラウドサービスを利用すればよいですか? IAM CloudWatch CloudFormation SNS // 答え B 解説 IAMIAM(Identity and Access M… 続きを読む

AWS】CloudWatchでの監視項目まとめ – Qiita

… リリースされました! PHP7.0が入ってNginx 1.10になった。 よって以前書いた エントリ は使い物にならないので改めて書き直す。 その分いろいろ手間が省けて楽になったでいいけど。 sudo略。 AWS アカウント作成 AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ EC2(VPC) 0から始めるAWS入門①:V.. 続きを読む

CloudWatch Events と Systems Manager で EC2の起動/停止をスケジュール化する

はじめに

開発環境等のインスタンスは休日や夜間は停止しておくことが多いと思います。
CloudWatch Events と Lambda で実装する例も多くみかけますが、
Systems Managerと組み合わせてノンプログラミングで実装する方法もあります。

Systems Manager 単体でも Maintenance Windows を使用して設定することができますが、
これは別の記事でご紹介できればと考えています。

設定する

IAM ロールの設定と CloudWatch Events のルール作成が必要です。

IAMロールを作成する

EC2 の起動停止は SSM Automation の機能を利用します。
そのため CloudWatch Events が SSM を呼び出すための IAM ロールを作成します。

image.png

ここでは AWS 管理ポリシーの AmazonSSMAutomationRole をアタッチします。
EC2 起動停止するために必要な権限以外も含まれますので、必要に応じてカスタムポリシーを作成してください。
作成後、信頼関係から信頼されたエンティティに events.amazonaws.com を追加します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "events.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

image.png

CloudWatch Events を設定する

起動用ルールの作成

イベントソースの設定でスケジュールを選択し、Cron式でイベントスケジュールを設定します。
例えば平日の午前9時に指定したEC2を起動したい場合は、以下のように設定します。

0 0 ? * 2-6 *

※UTC で設定しますので、日本標準時との時差9時間を考慮する必要があります。

image.png

ルールのスケジュール式ついては以下ドキュメントにも詳細が記載されています。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html

次にターゲットの追加から SSM Automation 選択し、以下のように設定します。

  • Doclument: AWS-StartEC2Instance
  • Configure automation parameter(s)
    • InstanceId: 起動したいインスタンスのインスタンスID
  • 既存のロールの使用: 作成した IAM ロールを指定

ロールの作成手順で信頼されたエンティティに events.amazonaws.com を追加していないと、
既存のロールの選択肢に出てきませんので注意してください。

image.png

設定の詳細ボタンからステップ 2:に進み、

  • ルール名称(必須)
  • 説明(任意)

を入力し、ルールを作成すれば完了です。

停止用ルールの作成

起動用ルールと同じ流れですので、画面コピーは割愛します。

ここでは平日の18時に停止を行うと想定し、UTC で以下のように設定します。

0 9 ? * 2-6 *

ターゲットの追加から SSM Automation 選択し、以下のように設定します。

  • Doclument: AWS-StopEC2Instance
  • Configure automation parameter(s)
    • InstanceId: 停止したいインスタンスのインスタンスID
  • 既存のロールの使用: 作成した IAM ロールを指定

設定の詳細ボタンからステップ 2:に進み、

  • ルール名称(必須)
  • 説明(任意)

を入力し、ルールを作成します。

動作確認

設定した時刻に指定したインスタンスが起動および停止することを確認します。
Automation の実行結果については、コンソールでの確認方法は現時点で2通りあり、
EC2コンソールの 自動化 または AWS Systems ManagerコンソールのAutomation から確認することができます。

image.png

CloudWatch Events で結果を監視する

せっかくなので Automation の実行結果についても CloudWatch Events で設定してみます。
新規にルールを作成し、スケジュールではなく、イベントパターンを選択します。
ここでは Automation の失敗またはタイムアウトを監視するため、以下のように詳細を設定します。

  • サービス名: EC2 Simple Systems Manager (SSM)
  • イベントタイプ: Automation
  • Specific detail type(S)

    • EC2 Automation Execution Status-change Notification
  • 特定のステータス

    • Failed, TimedOut

image.png

コンソールで設定できるのは上記項目のみであるため、このままの設定だと今回設定した EC2 起動停止用の
Automation だけでなく、SSM で実行される全ての Automation が監視対象となってしまいます。
条件を更に絞りたい場合は、イベントパターンのプレビューから直接 JSON の編集を行うことができます。

ここでは EC2 の起動停止を行う Automation のみを監視するため、
“detail.Definition” フィールドに Automation ドキュメント名を設定しました。
“resources” フィールドに対象ドキュメントの ARN を指定した場合も同様の結果になります。

{
  "source": [
    "aws.ssm"
  ],
  "detail-type": [
    "EC2 Automation Execution Status-change Notification"
  ],
  "detail": {
    "Definition": [
      "AWS-StartEC2Instance",
      "AWS-StopEC2Instance"
    ],
    "Status": [
      "Failed",
      "TimedOut"
    ]
  }
}

その他にどのような項目を指定できるかについては、以下のドキュメントの
Automation 実行ステータス変更の通知例をご参照ください。

サポートされている各サービスからの CloudWatch イベント イベントの例
AWS Systems Manager イベント
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/EventTypes.html#ssm_event_types

ターゲットの設定では検知した内容の通知方法を設定します。
ここでは SNS の Topic に登録した Email アドレスに通知するよう設定しました。
必要に応じて入力の設定で通知内容を定義します。

image.png

設定の詳細ボタンからステップ 2:に進み、

  • ルール名称(必須)
  • 説明(任意)

を入力し、ルールを作成すれば完了です。
参考になれば幸いです。

参考: イベントパターンにおける実行ロールの指定

前述のとおり、ドキュメントに記載されているイベント例に記載されている内容であれば
イベントパターンの手動編集で条件を絞り込むことができます。

Automation 実行ステータス変更の通知例をドキュメントから抜粋すると以下のとおりです。

{
  "version": "0",
  "id": "d290ece9-1088-4383-9df6-cd5b4ac42b99",
  "detail-type": "EC2 Automation Execution Status-change Notification",
  "source": "aws.ssm",
  "account": "123456789012",
  "time": "2016-11-29T19:43:35Z",
  "region": "us-east-1",
  "resources": ["arn:aws:ssm:us-east-1:123456789012:automation-execution/333ba70b-2333-48db-b17e-a5e69c6f4d1c", 
    "arn:aws:ssm:us-east-1:123456789012:automation-definition/runcommand1:1"],
  "detail": {
    "ExecutionId": "333ba70b-2333-48db-b17e-a5e69c6f4d1c",
    "Definition": "runcommand1",
    "DefinitionVersion": 1.0,
    "Status": "Success",
    "StartTime": "Nov 29, 2016 7:43:20 PM",
    "EndTime": "Nov 29, 2016 7:43:26 PM",
    "Time": 5753.0,
    "ExecutedBy": "arn:aws:iam::123456789012:user/userName"
  }
}

最後の “detail.ExecutedBy” フィールドは実行されたユーザの ARN になっています。
今回のEC2起動停止では、”スケジュール実行で SSM Automation を実行するルール”を定義しているため、
この箇所はイベントルールに設定した実行ロールの assumed-role ARN が含まれる形になります。
これを指定すれば実行元のロールも監視条件に含めることができます。
ただし、実際の assumed-role ARN は以下の形式になります。

"arn:aws:sts::[account-id]:assumed-role/[role-name]/[role-session-name]"

ロールセッション名については、イベントルールの実行ロール設定時に AWS側で設定されるようです。
ロールセッション名がルールの実行毎に変わってしまうと、正常に監視できないことになりますが、
現状の挙動を観察する限りでは、実行ロールの変更を行わない限りは(時間によらず)変化しないようです。

ただしドキュメント等に記載されている仕様ではないため、今後予告なく挙動が変わる可能性が大いにあります。
プロダクション環境等での設定はおすすめできませんので参考情報として最後に記載させていただきました。

続きを読む

ローカルでLambdaのテストをする環境を作ったメモ

何?

Lambdaをテストする際、いちいちUPしてCloudWatchを確認して・・・とテストするのは辛いのでローカルでテストする環境を作る。
作ったメモ

検証環境

Mac: macOS Sierra
awscli: aws-cli/1.14.32 Python/2.7.13 Darwin/16.7.0 botocore/1.8.36
nodejs: v9.4.0
npm: 5.6.0
docker: Version 17.06.2-ce-mac27

ディレクトリ構成

.
├── docker-compose.yml
├── event.json
├── index.js
├── package.json
└── template.yml

aws-sam-localのインストール

npm i aws-sam-local -g

私はこいつはグローバルインストールしている

手順

作業ディレクトリの作成と移動

コマンド
mkdir test
cd test

npm install

npm init -y
npm i aws-sam-local aws-sdk --save-dev

sam-localが使用するYAMLの作成

template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  lambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs6.10

localstack用のYAMLファイル作成

docker-compose.yml
version: '2.1'
services:
  localstack:
    image: localstack/localstack
    ports:
      - 4567-4583:4567-4583
      - 8080:8080

スクリプトの用意

index.js
'use strict';

const AWS = require('aws-sdk');
const S3 = new AWS.S3({endpoint: 'http://<ローカル端末のIP>:4572', s3ForcePathStyle: true});


exports.handler = (event, context, callback) => {
    console.log(`EVENT is ${event}`);
    uploads3().then(() => {
        callback()
    });
};

const uploads3 = () => {
    return new Promise((resolve, reject) => {
        let param = {
            Bucket: "xxxxxxxxxxxxxbbb",
            Key: "test2.txt",
            Body: "fugafuga"
        };
        console.log(param);

        S3.putObject(param, (err, data) => {
            if (err) {
                console.log(err, err.stack);
            } else {
                console.log(data);
            }
            resolve();
        });
    });
};

ダミーイベント作成

コマンド
sam local generate-event dynamodb > event.json

local-stackの起動(バックグラウンド起動)

コマンド
docker-compose up -d

lambdaのローカル実行

コマンド
sam local invoke lambdaFunction -e event.json 
  • アップロード用のS3バケットのダミーは最初に作っておくこと。
  • samが呼んでくるlambda動かすdockerからlocalstackへのネットワーク疎通が通らなかったからEndpointは端末のIP指定している。

ローカルでCLI使ってlocalstackは疎通出来るのに、docker上で動いてるLambdaスクリプトから接続ができなくてすっごいハマった。

参考

[新ツール]AWS SAMをローカル環境で実行できるSAM Localがベータリリース

AWS SAM Local と LocalStack を使って ローカルでAWS Lambdaのコードを動かす

続きを読む

1ヶ月でAWS 認定ソリューションアーキテクトに合格した話

昨年(2017年)の8月にAWS 認定ソリューションアーキテクト – アソシエイトに合格しました。
ほぼゼロからの勉強でしたが、要点を抑えれば短期間でも合格できたので、やったことを紹介します。

1. 前提知識

趣味で触ったことがあるもの。※どれも軽く触った程度

  • EC2
  • ELB
  • S3
  • Lambda (試験には出ない)
  • API Gateway (試験には出ない)

2. 対策内容

2-1. AWS Summit Tokyo 2017 セッション資料・動画

オススメ度: ★★★★★

一番オススメです。
「試験範囲の動画を見る → 実際にAWS上でやってみる」で大体雰囲気つかめました。
各サービスの「入門」だけで十分だと思います。
(話すペースがゆっくりなので、1.5倍速ぐらいで見ないと眠くなります。)

2-2. AWS Black Belt

オススメ度: ★★★★☆

安定の公式資料集です。
そこそこボリュームあるので、自分は理解の浅いサービスに絞って読みました。
(試験範囲の資料は一通り目を通した方が良いのかも?)

2-3. 参考書

オススメ度: ★★★☆☆

唯一の対策本なので、読んでおいて損はないと思います。
ただ情報量は少なめなので、概要をつかむ程度に使いました。

オススメ度: ★★☆☆☆

ハンズオン形式で進めるので、イメージがつきやすいです。
ただこちらも情報量としては足りてないので、合わせて他の対策も必要です。

2-4. AWS WEB問題集

オススメ度: ★★★☆☆

無料枠のみ解きました。
本番と似たような問題が出題されるので、そこそこ参考になります。
(何問かは本番とまったく同じ問題でした。運が良かっただけかも?)

3-5. それっぽい構成で作ってみる

オススメ度: ★★★★☆

ある程度理解が進んだら、サービスを複数組み合わせて何か作ってみるのがオススメです。
自分の場合は以下の構成で、Hello Worldをブラウザから表示するぐらいの簡単なものを作りました。

 VPC + ELB + EC2 + AutoScaling + CloudWatch + Route53

3. 結果

正答率(模擬試験): 75%
正答率(実試験): 72%

試験当日は、そこそこ感触が良かったのですが、思ったより点数が伸びず^^;
何はともあれ、一発合格できて一安心でした。

4. 感想

  • 実際に手を動かすことが一番タメになりました。やってみないとわからないことがけっこうあります。
  • ある程度知識が付いた段階で、模擬試験を受けることがオススメです。雰囲気つかめます。
  • セキュリティグループとネットワークACLに関する問題が多く出題された気がします。
  • とにかく試験会場が暑かった。。。

続きを読む

Cognitoユーザープールからの送信メールをカスタマイズする

サービスの認証にCognitoユーザープールを使用する際、確認コードや、初回ログインパスワードなどをメールでお知らせする場合があると思います。

Cognitoのデフォルト設定だとこんなメールが届きます。

Your confirmation code is 927173
Your username is xxxx and temporary password is xxxxxx.

このメールタイトル、本文をカスタマイズする方法です。

カスタムメッセージが設定できるイベント

公式ドキュメントからの抜粋です。
以下がカスタムメッセージが設定できるイベントの一覧です。

AWS Lambda トリガーのリクエストおよびレスポンスパラメータ

triggerSource 値 トリガーイベント
CustomMessage_AdminCreateUser カスタムメッセージ – 新規ユーザーに一時パスワードを送信するため.
CustomMessage_ResendCode カスタムメッセージ – 既存ユーザーに確認コードを再送するため.
CustomMessage_ForgotPassword カスタムメッセージ – 忘れたパスワードのリクエスト用の確認コードを送信するため.
CustomMessage_UpdateUserAttribute カスタムメッセージ – ユーザーの E メールまたは電話番号が変更されると、このトリガーは確認コードをそのユーザーに自動的に送信します。他の属性には使用できません。
CustomMessage_VerifyUserAttribute カスタムメッセージ – ユーザーが手動で新しい E メールや電話番号の認証コードをリクエストすると、このトリガーからユーザーに認証コードが送信されます。
CustomMessage_Authentication カスタムメッセージ – 認証時に MFA コードを送信するため.

今回はtriggerSource値がCustomMessage_AdminCreateUserの場合(Cognitoユーザープールのポリシーに「管理者のみにユーザーの作成を許可する」を設定していて、管理者がユーザーを作成した際にユーザーに送信されるメール)のカスタマイズを例にします。

手順

  1. Lambdaファンクションの作成
  2. Cognitoユーザープールに1.で作成したファンクションを登録

1. Lambdaファンクションの作成

Python3.6での例です。
ファンクションのIAMロールにはCloudwatchログ出力権限の付与だけでOKです。以下IAMポリシーの例です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        }
    ]
}

Lambdaファンクションで受け取るイベントをログ出力するとこのような感じ。

{
    "version": "1",
    "region": "ap-northeast-1",
    "userPoolId": "ap-northeast-1_xxxxxxxxx",
    "userName": "hogee",
    "callerContext": {
        "awsSdkVersion": "aws-sdk-js-2.176.0",
        "clientId": "CLIENT_ID_NOT_APPLICABLE"
    },
    "triggerSource": "CustomMessage_AdminCreateUser",
    "request": {
        "userAttributes": {
            "sub": "bf6e9c66-0a69-476e-bfd8-724d38e6555f",
            "cognito:email_alias": "hoge@example.com",
            "email_verified": "True",
            "cognito:user_status": "FORCE_CHANGE_PASSWORD",
            "name": "hoge",
            "email": "hoge@example.com"
        },
        "codeParameter": "{####}",
        "usernameParameter": "{username}"
    },
    "response": {
        "smsMessage": "None",
        "emailMessage": "None", # ここをカスタムした本文に変える
        "emailSubject": "None" # ここをカスタムしたタイトルに変える
    }
}

このイベントをそのままreturn eventとするとデフォルト設定が適用されたメールが送られます。カスタマイズするにはresponseのフィールド内をカスタマイズしたい内容に書き換えてリターンします。

cognito_custom_message.py
# -*- coding:utf-8 -*-

def handler(event, context):
    if event['triggerSource'] == 'CustomMessage_AdminCreateUser':
        customed_event = custom_message_admin_create_user(event)

    return customed_event


def custom_message_admin_create_user(event):

    email_message = '''
{username} 様
<br>
<br>
管理者から招待されました。
<br>
<br>
ログインメールアドレス:{mail}
<br>
初回ログインパスワード:{password}
'''.format(username='{username}',
           mail=event['request']['userAttributes']['email'],
           password='{####}')

    event['response']['emailSubject'] = '仮パスワード発行のお知らせ'
    event['response']['emailMessage'] = email_message

    return event

{username}にユーザーネーム、{####}にパスワードが入ってメールが送信されることになります。
triggerSourceによって本文に含めなくてはいけないコードパラメータは異るため先ほどの公式ドキュメントで確認してください。
triggerSourceがCustomMessage_AdminCreateUserの場合、メッセージ本文に{username}{####}が入っていないとエラーになります。

もし追加で他のカスタムメッセージイベントにも対応したい場合、handler()

    elif event['triggerSource'] == 'CustomMessage_ForgotPassword':
        customed_event = custom_message_forgot_password(event)

とやると対応できます。

2. Cognitoユーザープールに1.で作成したファンクションを登録

Lambdaファンクション作成後はCognitoユーザープールのコンソールにいき、トリガーカスタムメッセージから作成したLambdaファンクションを指定します。

スクリーンショット 2018-02-03 20.03.27.png

serverless frameworkではこのようになります。

serverless.yml
<略>
functions:
  cognitoCustomMessage:
    handler: functions/cognito_custom_message.handler
    role: CognitoCustomMessageRole
    events:
      - cognitoUserPool:
          pool: UserPool
          trigger: CustomMessage
resources:
  Resources:
    CognitoUserPoolUserPool:
      <以下略>

設定後、アプリケーションからユーザーを登録してみると、

スクリーンショット_2018-02-03_20_27_35.png

カスタマイズされたメールが届きました。

以上です。

続きを読む