AWS SDK For Python (Boto3) で AWS Personal Health Dashboardの情報を取得する | Developers.IO

AWS Personal Health Dashboard (AWS Health) はAWSアカウントに影響のあるイベント情報が表示されます。Amazon CloudWatch Eventsを使用してもイベントのステータス変化を検出して対応することもできますが、Python (Boto3)で必要な情報を取得してみましたのでサンプルコードをご紹介します。 ※AWS Health … 続きを読む

AWS】DynamoDB Streams & Lambdaの関係

AWS DynamoDB SQS Lambda. LambdaとSQS,DynamoDBの連携について、メモがてら実際試したことを書きます。 よく構成としてEC2を起動させて、SQSをポーリングしたりするかと思いますが、 近年だとLambdaのCLoudwatch Eventsなどを使用して定期的にSQSをポーリングさせたりしています。 日頃の運用として、DB … 続きを読む

CloudFormationでCloudWatchイベントの実行間隔をパラメータで指定する時にrate式で1を設定するためのConditionsを書いてみた

こんにちは、臼田です。 みなさんLambdaしていますか? 今日はLambdaを導入する為に用意したCloudFormationで、特定のパラメータを指定すると失敗した経緯があり、回避策を吐き出そうと思ってブログにしまし […] 続きを読む

[アップデート]AWS BatchがCloudWatch Eventsに対応しました!

コンニチハ、千葉です。お久しぶりです。 本日は、AWS Batchのアップデート情報をお伝えします。AWS Batchはキューベースのジョブ実行サービスで高スケーラビリティなバッチをさくっと作ることができます。 キューにputすると、バッチが起動しなんらかの処理を行うことができます。例えば、API Gatewayをフロントにし、キュー … 続きを読む

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

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

続きを読む

[AWS] サインイン画面が重すぎたので、その対処

何があった?

AWSマネジメントコンソール(以下「マネコン」)のサインイン画面が重すぎ(遅すぎ)る。
ブラウザのアイコンがくるくる回り続け、数十秒かかって結局画面が開かず中断されることもある。
別ネットワークに切り替えたらそこまで遅いわけでもなかったので、単にプロバイダの問題かもしれない。でもやっぱりちょっと遅い。

ふと気づいた

https://us-east-1.console.aws.amazon.com/     → 遅い
https://ap-northeast-1.console.aws.amazon.com/   → 速い

当方、日本からの利用です。
わざわざアメリカまで行ってるから遅かったんですね。
というかマネコンって CloudFront で近場のエッジ使ってるものだと思ってた。サインイン画面は例外なのかな。

でもIAMユーザーでサインインするときって

「どのアカウントに」を毎回入力するのが面倒なので、IAM画面のダッシュボードに表示されている下記のサインインリンクを使ってます。

https://<Account-Alias>.signin.aws.amazon.com/console

しかしこれだと us-east-1 のサインイン画面に飛ばされてしまう。

対処法

https://<Account-Alias>.signin.aws.amazon.com/console?region=ap-northeast-1

後ろにリージョン情報 ?region=ap-northeast-1 をくっつけてみたら、そのリージョンのサインイン画面に飛ぶようになりました。
これで快適。

ちなみに

今回の件とはあまり関係なく考慮すべきことなんですが。
CloudTrail で ConsoleSignin のログを取る場合、リージョン別に出力されることに注意。
CloudWatch Events も各リージョンでイベントが発生します。
ConsoleSignin を検知して何かしようと思ったら、全リージョンにCloudTrailの設定が必要です。
CloudTrail は 全リージョン設定が一発で出来るようになってますが、CloudWatch Events のほうは各リージョンで個別に設定する必要があります。

続きを読む

[AWS][Terraform] Terraform で Amazon Inspector を導入する

TerraformAmazon Inspector を導入して、CloudWatch Events で定期実行させるための手順。
Terraform は v0.11.2 を使っています。

Inspector の導入

Inspector を導入するには、Assessment targets (評価ターゲット) と Assessment templates (評価テンプレート) を設定する必要があります。

Assessment targets の設定

Terraform で Assessment targets を設定するには、aws_inspector_resource_group, aws_inspector_assessment_target リソースを使用します。
こんな感じです。

inspector_target.tf
variable "project" { default = "my-big-project" }
variable "stage"   { default = "production" }

resource "aws_inspector_resource_group" "inspector" {
    tags {
        project   = "${var.project}"
        stage     = "${var.stage}"
        inspector = "true"
    }
}

resource "aws_inspector_assessment_target" "inspector" {
    name               = "my-inspector-target"
    resource_group_arn = "${aws_inspector_resource_group.inspector.arn}"
}

aws_inspector_resource_group では、対象となるインスタンスを特定するための条件を記述します。
上記の例だと、以下のタグが設定されているインスタンスを対象にします。

Name Value
project my-big-project
stage production
inspector true

aws_inspector_assessment_target では、aws_inspector_resource_group で定義した条件を元に Assessment targets を作成します。

Assessment templates の設定

Terraform で Assessment templates を設定するには、aws_inspector_assessment_template リソースを使用します。
こんな感じです。

inspector_template.tf
variable "inspector-rule" = {
    type = "list"
    default = [
        "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-7WNjqgGu",
        "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-bBUQnxMq",
        "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-gHP9oWNT",
        "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-knGBhqEu"
    ]
}

resource "aws_inspector_assessment_template" "inspector" {
    name       = "my-inspector-template"
    target_arn = "${aws_inspector_assessment_target.inspector.arn}"
    duration   = 3600

    rules_package_arns = [ "${var.inspector-rule}" ]
}

output "assessment_template_arn" {
    value = "${aws_inspector_assessment_template.inspector.arn}"
}

rules_package_arns では、利用可能な Inspector rule package の ARN を設定します。
variable にしておくと、後で rule package を変更したい時に楽ですね。
こんな感じで、使用する rule package を変更できます。

terraform.tfvars
"inspector-rule" = [
    "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-7WNjqgGu",
    "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-bBUQnxMq"
]

使用できる rule package は、aws-cli で取得してください。

# パッケージ一覧の表示
$ aws --region ap-northeast-1 inspector list-rules-packages
{
    "rulesPackageArns": [
        "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-7WNjqgGu",
        "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-bBUQnxMq",
        "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-gHP9oWNT",
        "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-knGBhqEu"
    ]
}
# 詳細を確認
$ aws --region ap-northeast-1 inspector describe-rules-packages 
  --rules-package-arns "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-7WNjqgGu"
{
    "rulesPackages": [
        {
            "description": "The CIS Security Benchmarks program provides well-defined, un-biased and consensus-based industry best practicesto help organizations assess and improve their security.nnThe rules in this package help establish a secure configuration posture for the following operating systems:nn  -   Amazon Linux version 2015.03 (CIS benchmark v1.1.0)n  n    ",
            "version": "1.0",
            "name": "CIS Operating System Security Configuration Benchmarks",
            "arn": "arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-7WNjqgGu",
            "provider": "Amazon Web Services, Inc."
        }
    ],
    "failedItems": {}
}

参考URL: Terraform v0.8.5でAWS Inspectorに対応します

これで terraform apply すれば Assessment targets, templates が作成されます。

動作確認

実際に Inspector が実施されるか確認して見ましょう。

$ aws inspector start-assessment-run 
  --assessment-template-arn arn:aws:inspector:ap-northeast-1:************:target/0-xxxxxxxx/template/0-xxxxxxxx
{
    "assessmentRunArn": "arn:aws:inspector:ap-northeast-1:************:target/0-xxxxxxxx/template/0-xxxxxxxx/run/0-7WNjqgGu"
}

実行状況の確認は aws inspector describe-assessment-runs

$ aws inspector describe-assessment-runs 
  --assessment-run-arns arn:aws:inspector:ap-northeast-1:************:target/0-QOvPswHA/template/0-uCIUy636/run/0-n9nnWOem

CloudWatch Events Schedule による定期実行

当初は CloudWatch Events で定期実行するには Lambda から呼び出すようにしなければいけませんでした。
しかし、CloudWatch Event から直接 Inspector を実行できるようになったため、Lambda を使用しなくても aws_cloudwatch_event_targetaws_cloudwatch_event_rule だけで定期実行設定が可能です。

CloudWatch Events で使用する IAM ロールの作成

まずは、CloudWatch Events で使用する IAM ロールを作ります。

cloudwatch-events-iam-role.tf
esource "aws_iam_role" "run_inspector_role" {
    name               = "cloudwatch-events-run-inspector-role"
    assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
POLICY
}

resource "aws_iam_policy" "run_inspector_policy" {
    name        = "cloudwatch-events-run-inspector-policy"
    description = ""
    policy      = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "inspector:StartAssessmentRun"
            ],
            "Resource": "*"
        }
    ]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "run_inspector_role" {
    role       = "${aws_iam_role.run_inspector_role.name}"
    policy_arn = "${aws_iam_policy.run_inspector_policy.arn}"
}

CloudWatch Events への登録

CloudWatch Events に登録するために aws_cloudwatch_event_target リソースと aws_cloudwatch_event_rule を作りましょう。

cloudwatch-events.tf
variable "schedule"    { default = "cron(00 19 ? * Sun *)" }

resource "aws_cloudwatch_event_target" "inspector" {
  target_id = "inspector"
  rule      = "${aws_cloudwatch_event_rule.inspector.name}"
  arn       = "${aws_inspector_assessment_template.inspector.arn}"
  role_arn  = "${aws_iam_role.run_inspector_role.arn}"
}

resource "aws_cloudwatch_event_rule" "inspector" {
  name        = "run-inspector-event-rule"
  description = "Run Inspector"
  schedule_expression = "${var.schedule}"
}

schedule_expression の cron() は UTC で設定する必要があるので注意してください。
記述方法は、以下を参考に
参考URL: Rate または Cron を使用したスケジュール式

EC2 への IAM Role の設定と、ユーザーデータによる Inspector エージェントのインストール

評価ターゲットとなる EC2 には、Inspector エージェントがインストールされていて、適切なインスタンスロールが設定されている必要があります。
導入するには、こんな感じ

インスタンスロール

inspectora エージェントを使用するために必要なポリシーをアタッチしたインスタンスロールの作成はこんな感じです。

ec2-instance-role.tf
resource "aws_iam_role" "instance_role" {
    name               = "my-ec2-role"
    path               = "/"
    assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
POLICY
}

resource "aws_iam_instance_profile" "instance_role" {
    name = "my-ec2-role"
    role = "${aws_iam_role.instance_role.name}"
}

resource "aws_iam_policy" "inspector" {
    name        = "my-ec2-iam-policy-inspector"
    description = ""
    policy      = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeCustomerGateways",
                "ec2:DescribeInstances",
                "ec2:DescribeTags",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeNatGateways",
                "ec2:DescribeNetworkAcls",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribePrefixLists",
                "ec2:DescribeRegions",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcEndpoints",
                "ec2:DescribeVpcPeeringConnections",
                "ec2:DescribeVpcs",
                "ec2:DescribeVpn",
                "ec2:DescribeVpnGateways",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeLoadBalancerAttributes",
                "elasticloadbalancing:DescribeRules",
                "elasticloadbalancing:DescribeTags",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeTargetHealth"
            ],
            "Resource": "*"
        }
    ]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "inspector" {
    role       = "${aws_iam_role.instance_role.name}"
    policy_arn = "${aws_iam_policy.inspector.arn}"
}

ユーザーデータによる inspector エージェントのインストール

OS は Amazon Linux を想定してます。
ユーザーデータに書いておけば、インスタンス起動直後に inspector エージェントインストールできますね。
参考URL: Amazon Inspector エージェントをインストールする

ssh-key.pemssh-key.pem.pubssh-keygen で適当に作っておきましょう。

ec2.tf
## AMI
##
data "aws_ami" "amazonlinux" {
    most_recent = true
    owners      = ["amazon"]

    filter {
        name   = "architecture"
        values = ["x86_64"]
    }

    filter {
        name   = "root-device-type"
        values = ["ebs"]
    }

    filter {
        name   = "name"
        values = ["amzn-ami-hvm-*"]
    }

    filter {
        name   = "virtualization-type"
        values = ["hvm"]
    }

    filter {
        name   = "block-device-mapping.volume-type"
        values = ["gp2"]
    }
}

## SSH Key Pair
##
resource "aws_key_pair" "deployer" {
    key_name   = "ssh-key-name"
    public_key = "${file(ssh-key.pem.pub)}"
}

## EC2
##
resource "aws_instance" "ec2" {
    ami                         = "${data.aws_ami.amazonlinux.id}"
    instance_type               = "t2.micro"
    key_name                    = "${aws_key_pair.deployer.key_name}"
    iam_instance_profile        = "${aws_iam_instance_profile.instance_role.name}"

    user_data                   = <<USERDATA
#!/bin/bash
# install inspector agent
cd /tmp
/usr/bin/curl -O https://d1wk0tztpsntt1.cloudfront.net/linux/latest/install
/bin/bash install -u false
/bin/rm -f install
USERDATA

    tags {
        project   = "${var.project}"
        stage     = "${var.stage}"
        inspector = "true"
    }
}

現場からは以上です。

続きを読む

PIXTAにおけるAWS Lambdaの活用事例

新年明けましておめでとうございます。 開発部のもりと申します。 本年も”てくすた”をよろしくお願いします。 今回のテーマはPIXTAにおけるAWS Lambdaの活用事例として、CloudWatch EventsをトリガーにしたEBSボリュームのスナップショットの取得と、CodeCommitをトリガーにしたOpsWor… 続きを読む