Quantcast
Channel: 技術 –サーバーワークスエンジニアブログ
Viewing all 1210 articles
Browse latest View live

定型運用の現場改善 –工数集計で定量的な議論をする

$
0
0

こんにちは。マネージドサービス課の橋本です。所謂「定型運用」の現場に関わっています。

それなりに私自身の知見も溜まってきましたので、より良い現場を形成するためのノウハウ的なことを紹介したいと思います。

この記事では、「定量化」にまつわる取り組みとその成果の話をします。対象読者は似たような定型運用の現場に携わるエンジニアの方々です。

背景

こういう現場にいるこういう人間が書いています、という前置きです。

現場

こんな感じ。この記事を読んでくれた方の中にも、似たような案件を持っている方もいらっしゃるかと思います。

  • とある業務パッケージシステムの「定型運用」を実施
  • 作業を行う環境はすべてAWS上のリソース、OSログインを伴う作業も行う
  • 障害対応は別働隊の管轄
  • 担当プリセールス(もしくはTAM)、あるいはエンドユーザーからの依頼ベースで作業を実施する
  • 運用チーム内の役割は以下
    • オペレーター
    • ディスパッチャー(依頼作業をオペレーターに割り振ったり、トラブル事象をエスカレーションしたり)

日々のタスク管理にはRedmineを使用していました。今回紹介する定量化に不可欠な要素ですので、どういった数字が取れていたか紹介します。

  •  依頼作業1件 ≒ 1チケット
    • 事前準備作業やパラメータシートの作成など、サブタスクはある程度の粒度で子チケットに分割
  • オペレーターの工数記録
    • 記録は子チケットの単位で行っている
    • Redmine上で工数記録できていない業務もある
  • カスタムフィールド(一部)
    • 作業種別
    • 予定工数(見積もり工数の意味で利用、作業種別ごとに固定値) 

筆者

  • AWS … ちょっとわかる
  • 記述統計 … 平均・中央値・分散、などの基本統計量は理解している
  • 役割は当初オペレーター、その後は現場管理的なことをしていた
  • 予算や人員を動かす権限は持たない

当初の問題意識とアプローチ

オペレーターの負荷が高いことでした。チーム全体の稼働時間があまり許容したくない水準に到達しており、負荷的にも採算的にも問題視していました。

作業種別によっては、1タスクにかかる工数が大きいものや、トラブルの発生しやすい傾向が高いものがありました。そこでまず、現場の感覚ベースで「トラブルが起きやすく工数がかさみやすい」作業に当たりをつけ、これに関する負荷を減らしていくために動きました。

やったことは、現場の数字をしかるべき人に示し、事態を動かすように働きかける、という流れです。

  • 問題意識を考察できる軸でいくつか集計を行う
  • 負担がかかっている現状を示す結果が出る
  • 数字の解釈、集計条件、結果の解釈、集計上の仮定、提示する改善案に至る筋道、これらに明らかな矛盾がないか確認する
  • 定例会議等で発表し、議論する(リソースの裁量権を持つ人が出席している場だと好ましい)

数字の集計と考察だけでも良いのですが、私としては「改善のための次アクション」に関するドラフト、ないしは大まかな方向性を添えることを強く推奨したいです。議論の方向性をリードする立場の方が色々と事態を動かしやすいので、次アクションに繋がる議論はこちらで用意したレールの上から始めるのが上策だと考えます。

アウトプットしたもの

実施した集計はいくつかありますが、主要なものは次のような切り口です。

  • Redmine上の作業工数のボリューム
    • 月間での推移
    • 作業カテゴリ別で集計した予定工数/実績工数
    • 負荷がかかりがちな特定の作業に関して、トラブル発生の割合とその推定原因の内訳(トラブル原因は集計時にチケットのメモ欄を見つつ人力でカテゴリ分けした)
  • 勤怠管理上の実労働時間(Redmineに乗らない工数も存在するため)

アウトプットしたのは次のような内容です。

[1] 他のチーム(主に開発)に向けて

  • 特定の作業についてトラブル率が高く予定より工数を取られがちであること、トラブルの原因はツール関係の不具合が多いことが判明した
    • 不必要な負荷が増えており、加えて作業品質の低下を招いている現状を説明
    • ツール改修やデプロイの安定化など、優先的に改善アクションの実施が必要であると説明

[2] マネジメント層に向けて

  • 作業の実工数と勤怠上の労働時間を突合し、月次の推移を見た。作業ボリュームは増加傾向であり、労働時間としても許容水準を超えている現状が明らかになった
    • 現状アサインしているリソースに不足があり、今後も不足傾向が加速する見通しを説明
    • 不足する工数の見積を概算し、工数をどの程度追加アサインする必要があるか説明

幸い、これらの主張は概ね受け入れられ、改善アクションが取られました。

注意したこと

故意かどうかに関わらず、数字で嘘をつかないよう注意を払うこと、これに尽きると思います。

「(自分を含む)運用現場の負荷を減らしたい」というゴールありきで始めた集計ではありましたが、目先の利益を求めるあまり虚偽のレポートを申告するようでは逆効果です。たとえ故意によるものではなかったとしても、ミスリードした結論が顧客・自社双方に損失をもたらすこともありえます。数字の妥当性や解釈にはかなり気を遣いました。

取得しづらいデータに対する考え方

理想的にはすべての業務工数が望ましい粒度で計測できているとよいのですが、現実的にはなかなかそう都合よくはいきません。

このへんは得たい情報の重要性と実務上の負担のトレードオフだと思います。新しい数字を管理するために実務上の煩雑さが大幅に増えるようでは本末転倒ですので、ほどほどに。

適当な仮定を置くことで穴埋めできることもありますし、問題意識のコアに関係ない数字ならば「計測できない」として割り切ってしまっても良い。必要なら概算ベースの見積もりで補完すればいい。

概算ベースの見積もり ってなんぞやと思われるかもしれませんが、これは単価×数量の要領で参考値が出せればそれでOKだと考えます。運用の作業工程であるならば、単価はオペレーターの作業工数でありヒアリングベースで確認、数量は日当たりの平均的な件数をRedmineなどから抜いてこればOKです。もちろん見積根拠は提示します。

まとめ

私のケースはかなりうまく話が転がったほうだと思いますが、これは現場に恵まれた側面も大きいと思っています。まず、この案件に関する私の上長のスタンス(当時)として、短期的な損失よりも今はテコ入れをして将来の収益改善を、という意向がありました。リソース増強に関しては受け入れられやすい下地がありました。また、開発チーム側にもOpsに協力的な方がおられたことも幸いしたと思います。

このような良い条件の下なし得た結果ですので、すべての現場で同様のやり方がうまくいくとは保証できません。しかしながら、ここで紹介したような定量的な議論がなければ運用側の主張が伝わることもなかっただろう…とも思います。アプローチは読者の現場にもいくらか応用できる余地があろうかと思います。

さて、今回のネタをまとめると、拠り所とする前提を固めたうえで定量的なデータを活用した議論をしよう、というお話でした。いかがだったでしょうか?「数字って役に立つやん」って思っていただければ幸いです。


Terraformを使ってACMのDNS認証を行う

$
0
0

こんにちは、技術1課の岩本です。

AWSを利用する際にAWS発行のSSL証明書を利用する機会も多いと思います。

ACMではSSL証明書の認証のためメールやDNSを用いますが、
マネジメントコンソール、もしくはメール受信などの承認プロセスなどが別途必要となります。

Terraformを用いると、Terraform内だけでACMの承認が行えます。

やってみた

provider "aws" {
    region = "ap-northeast-1"
}

resource "aws_acm_certificate" "cert" {
    domain_name       = "*.iwamoto.example.com."
  validation_method = "DNS"
}

data "aws_route53_zone" "zone" {
    name         = "iwamoto.example.com."
  private_zone = false
}

resource "aws_route53_record" "cert_validation" {
  name    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
  type    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
  zone_id = "${data.aws_route53_zone.zone.id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl     = 60
}

resource "aws_acm_certificate_validation" "cert" {
  certificate_arn         = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]
}

解説

  • aws_acm_certificate で対象となるドメイン用のSSL証明書を作成しています。
  • data "aws_route53_zone" とすることで、既存の(同一アカウントのRoute53に存在する)HostedZone名を指定しています。
    • 新規でHostedZoneを作成するのであればresourceと記載します。
  • aws_route53_recordにて、生成された認証用のDNSレコードを追加しています。

参考aws_acm_certificate_validation

まとめ

aws_acm_certificate_validation を使うことで、SSL証明書の作成がTerraform内で完結できます。

ALBなどを作成する際などに、SSLリスナーを作る場合は、事前にSSL証明書の作成などが必要でしたが、

aws_acm_certificate_validationを用いることで、証明書の作成からALBへの割り当てまでを一括で行えるようになります。

[運用Tips] EC2やRDSのメンテナンス通知をSlackに連携する

$
0
0

PS課佐竹です。
最近「CloudWatchのイベント通知を設定していて良かったな」と思うことがあったので、その内容を紹介させて頂きます。

はじめに

今回は、AWSから定期的に来る「メンテナンス通知」をSlackに連携する方法について記載します。

メンテナンス通知とは

EC2やRDS等のサービスでは、定期的にインスタンス(仮想マシン)が動作しているハイパーバイザーやハードウェアレベルでのメンテナンスが行われます。そのメンテナンスのタイミングで、メンテナンス対象となったハイパーバイザー(ハードウェア)上で動作するインスタンス(仮想マシン)を利用中の各ユーザに通知が行われます。

特に設定をしていない場合、連絡が来るのは以下の2つの方法となります。

  1. Personal Health Dashboard で通知が来る
  2. メールアドレスにメールが送付される

このうちの2つ目「メールアドレスにメールが送付される」ですが、以下のような件名と内容で連絡が来ます。

[件名] Amazon EC2 Maintenance – Maintenance [AWS Account: XXXXXXXXXXXX]
 
Dear Amazon EC2 Customer,
 
One or more of your Amazon EC2 instances is scheduled for maintenance on 2019-02-15 for 2 hours starting at 2019-02-15 04:00:00 UTC. During this time, the following instances in the ap-northeast-1 region will be unavailable and then rebooted:
 
i-[instance id]
 
During the scheduled maintenance window, your instance will undergo a reboot. The instance will retain its IP address, DNS name, and any data on local instance-store volumes. Please note that any reboot you perform on your own will not alleviate the need for this maintenance.
 
However, you can complete this maintenance at a time of your choosing by stopping and restarting your instance at any time prior to the scheduled maintenance window. Please note that the data on your local instance-store volume will not be persisted if you stop and start your instance.

しかし、このメールが確実に来る保証は実はされていない場合もあるのです。それにメールはやはり見逃します。
加えて、Personal Health Dashboard はその確認において、マネジメントコンソールにログインして閲覧するという能動的な動きを行う必要があります。そのため、弊社ではこの運用対応においてSlackに通知するという仕組みを採用することにしてみました。

前準備1:Slackで通知用のメールアドレスを取得する

まずは、以下の手順に従って、Slackの機能を用いて連絡用のメールアドレスを取得してください。

⑤メールアドレスをコピーします。このアドレスへ送られたメールはご希望のチャンネルまたは DMに投稿されます。

上記の手順で得たメールアドレスを、この後の手順で利用します。

前準備2:SNSでTopicを作成する

SNSでTopicを作成します。Topic nameとDisplay nameを入れてCreate topicするだけで作成できます。Display nameは10文字の制限があり、この名称がメールのFromにそのまま表示されます。

Topicを作成したらそのTopicにSubscriptionを作成します。
今回、このProtocolにEmailを選択し、そのEndpointとなるメールアドレスには、先ほど取得したSlackのメールアドレスを入力します。

ここまでで、前準備は完了となります。

CloudWatchでスケジュールされたメンテナンスをSNSで通知する

CloudWatch Eventsの画面で通知の設定を行います。
公式ドキュメントは「Amazon CloudWatch Events での AWS Health イベントのモニタリング」になります。

左端のメニュー「Events」を押下すると、上の画像と同じ画面が表示されますので、Get Startedを押下してください。以下のCreate ruleの画面に遷移します。

赤枠で囲ったところを設定してください。今回は「EC2」をターゲットとした設定を行います。

  1. Service Name で [Health] を選択します
  2. Event Typeで[Specific Health events]を選択します ※All Eventsだと全ての通知が来てしまいノイズになるため
  3. [Specific service(s)] を選択し、リストから [EC2] を選択します ※複数のサービスをまとめて選択はできません
  4. [Specific event type category(s)] を選択し、リストから [scheduledChange] を選択します

この選択を終えると、以下のJsonが完成します。

{
  "source": [
    "aws.health"
  ],
  "detail-type": [
    "AWS Health Event"
  ],
  "detail": {
    "service": [
      "EC2"
    ],
    "eventTypeCategory": [
      "scheduledChange"
    ]
  }
}

JsonはEditボタンから直接編集することも可能ですので、設定をImportすることも可能です。

{
  "source": [
    "aws.health"
  ],
  "detail-type": [
    "AWS Health Event"
  ],
  "detail": {
    "service": [
      "RDS"
    ],
    "eventTypeCategory": [
      "scheduledChange"
    ]
  }
}

RDSで設定すると上記のようになります。他のサービスでもscheduledChangeで気になるものがあれば、そのサービス分だけ設定をされると良いでしょう。

最後にTargetsの設定画面にて、SNSのTopicと連携する設定をして完了です。 [Configure Details] を押下した次の画面にて、作成したruleに名前を付けて [Create rule] を押下してください。なお、Targetsの設定は必須となりますので、この設定が完了しない限り画面右下の [Configure Details]ボタンは押下できません。

今回は、EC2に関連したruleの作成方法を紹介しましたが、RDSでも必要な場合は、もう1つRDS用のrule作成が必要となります。ELASTICACHEが必要であれば、ELASTICACHE用にもう1つruleが必要・・・と、メンテナンス通知を取得したいサービスごとにruleが増えて行きます。

流れ

整理のために記載しますと [CloudWatch Events]→[SNS topic]→[SlackのE-mail Adress]→[Slack]という流れで連携されます。

実際のSlackの画面

この設定の困った点の1つは、設定が正しく行われているのかの確認が、実際にメンテナンスがスケジュールされるまでわからないというところです。そこで、例として実際にメンテナンス通知がSlackの画面に登場したらどうなるのか、キャプチャしてきました。

SNSからは、Jsonでメールが届くので、はっきり言って可読性はかなり悪いです。ですが、「気付く」ことは十分に可能です。

まとめ

今回、CloudWatch EventsからSlackにSNSを使ってメンテナンス通知を連携する方法を記載させて頂きました。
先に記載した通り、可読性は少々低い通知にはなるのですが、Slackに連携されると高確率で気付くことができます。詳しい内容は、Personal Health Dashboardを確認すれば問題ありません。それに実装が非常に簡単です。Lambdaなどを間に挟むことでSlackでメンションをしたりすることで、さらに利便性を高めることは可能なのですが、お手軽にSlackに連携するという敷居の低さが魅力だと思います。
またメールが確実に送られることが無い、というときでもCloudWatch Eventsなら確実に通知してくれるのです!

この設定がいろんな案件で設定されることで、メンテナンス通知の抜け漏れが減り、お客様の満足度が少しでも上がればと思いながら以上でこの記事を終わりにいたします。

カスタムバンドルに規定のアプリ設定を含めてWorkSpacesを展開する

$
0
0

こんにちは、技術4課の城です。
掲題の件、カスタムバンドルからWorkSpaceを展開するにあたり、少々ハマったので、小ネタですが備忘として記録しておきます。

やること

まとめると、グループポリシーを利用して、展開したWorkSpaceに設定を投入します。
通常やるように既定のアプリの設定をしたのみでは、展開後のWorkSpaceには設定が反映されません。
今回はイメージ取得用のマスターWorkSpaceのローカルグループポリシーの設定を紹介します。
手順はイメージ取得前にマスターWorkSpaceにて実行します。

既定のアプリ設定(Windows 10)

[設定] > [システム] > [既定のアプリ]にて既定のアプリを設定します。

Dism.exeを利用して、設定をエクスポート

管理者権限でコマンドプロンプトを起動し、次のコマンドを実行します。

Dism.exe /Online /Export-DefaultAppAssociations:C:\DefaultApp.xml

ローカルグループポリシーの設定

ファイル名を指定して実行にて、gpedit.mscを実行します。
[コンピューターの構成] > [管理用テンプレート] > [Windowsコンポーネント] > [エクスプローラー]の
「既定の関連付け構成ファイルの設定」を開きます。

【有効】にチェック、【既定の関連付け構成ファイル】をC:\DefaultApp.xmlとします。

※注意事項

Active DirectoryのドメインやOUのグループポリシーに同一項目の設定がある場合は、上書きされるので注意しましょう。

さいごに

以上の設定を行って、イメージ取得、カスタムバンドル作成し、そのカスタムバンドルからWorkSpaceを作成すれば、既定のアプリ設定が反映されます。
小ネタではありますが、どなたかの助けになれば幸いです。

Cloud Automatorで対象リソース、操作権限を限定したユーザーを利用する

$
0
0

こんにちは、技術4課の城です。
今回は掲題のCloud Automator(以降、CA)の利用方法を紹介します。

やりたいことと条件

  • 個別のシステム担当者に対し、EC2、RDS(Aurolaを除く)の起動、停止ジョブのみ設定可能
  • 担当している以外のシステムの起動、停止は不可
  • Applicationタグにてシステムが判別

実現方法

  • CAのグループ機能を利用
  • グループに割り当てるクレデンシャルのIAMポリシーにて権限制御
    • 多雨小リソースの限定についてはIAMポリシーのCondition要素を利用

具体例のイメージ

  • システム担当者のCAユーザーAはCAのグループ:Alfaに属している
  • CAグループAlfaにはEC2,RDSのApplicationタグがAlfaであるリソースの起動、停止が許可されたクレデンシャルを登録
  • システムAlfaのEC2:ServerAlfaに対する起動ジョブは成功する
  • システムBetaのEC2:ServerBetaに対する起動ジョブはジョブ作成はできるもののIAMポリシーの権限不足により失敗する

IAM設定

CAはアクセスキー、シークレットアクセスキーを必要とするのでIAMユーザーを利用します。
管理をシンプルにするため、ポリシー変数を利用して共用できる形を検討しました。
利用するリソース数としては、下記のようになります。

・IAMポリシー:1
・IAMグループ:1
・IAMユーザー:システム数

IAMポリシー

下記のアクセス権限にて作成します。
アプリケーションタグのValueがIAMユーザー名と一致していればEC2,RDSの起動、停止が可能な内容です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/Application": "${aws:username}"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "rds:StopDBInstance",
                "rds:StartDBInstance"
            ],
            "Resource": "arn:aws:rds:*:*:db:*",
            "Condition": {
                "StringEquals": {
                    "rds:db-tag/Application": "${aws:username}"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "rds:DescribeDBInstances"
            ],
            "Resource": "*"
        }
    ]
}

IAMグループ

CA用のIAMグループを一つ作成します。
作成したIAMポリシーをアタッチします。
各システムのCAグループ用のIAMユーザーは全てこちらに所属させます。

IAMユーザー

各システムに設定しているApplicationタグのValueをユーザー名とします。
今回はApplication:Alfaのリソースを操作したいので、Alfaとしました。
プログラムによるアクセスにチェックをしておき、アクセスキー、シークレットアクセスキーを記録しておきます。

CAの設定

ユーザーの追加

システム担当者のユーザーを追加します。
ユーザー追加についてはマニュアル:ユーザー管理を参考にしてください。

グループの追加

グループを追加し、前項のユーザーをグループメンバーに追加します。
グループの管理についてはマニュアル:グループの管理を参考にしてください。
アクセスキー、シークレットアクセスキーは前項にて作成したIAMユーザーのものを利用します。

ジョブを作成

イメージ図のServerAlfa、ServerBetaに対する起動ジョブを作成しみます。
EC2インスタンス起動ジョブ作成については[マニュアル:EC2:インスタンスを起動]を参考にしてください。
今回はそれぞれ即時実行ジョブを作成してみます。
【ServerAlfaの起動ジョブ】

【ServerBetaの起動ジョブ】

実行結果

想定通りですが、ServerAlfaの起動ジョブは成功し、ServerBetaの起動ジョブは失敗します。
【ServerAlfaのジョブ実行結果】

【ServerBetaのジョブ実行結果】
実行結果を見ると、エラーメッセージ: UnauthorizedOperation: You are not authorized to perform this operation.と出力されているので、意図した通り権限不足でジョブ実行が失敗しています。

さいごに

CAのグループ機能とIAMポリシーを利用しての権限制御を紹介しました。
IAMポリシーでは色々な形で権限制御が可能です。
権限を適切に設定することで、情報システム全体の管理者からシステム担当者へ利用権限を委任することが出来るかと思います。

最後にちょっと宣伝ですが、Cloud AutomatorはAMIの取得、インスタンスタイプ変更などをスケジューリングできたりと、手前味噌ながら便利なツールとなっています。
是非、利用してみてはいかがでしょうか。

どなたかの助けになれば幸いです。

RSSをBacklogに自動で投稿する仕組みを作ってみた

$
0
0

PS課の杉村です。RSSという仕組みは便利です。AWSに関して言うと、けっこう重要な情報がRSSで配信されていたりします。
日々のアップデート情報はもちろん、Redshiftのメンテナンス予告(新バージョンのリリース)等が配信されていたりするのです。

例えば以下のRSSフィードでは、Redshiftに関するアナウンス(新バージョンリリース情報含む)を取得することができます。
https://forums.aws.amazon.com/rss/rssannounce.jspa?forumID=155

RSSをBacklog課題に自動でコメントを追記する

弊社ではプロジェクト管理ツールとしてBacklogを使っています。(Redmineのようなもの。SaaS。)
このBacklogのチケットにうまいことRSSを連携させるため、Zapierという複数のSaaS等を連携させるためのサービスを使いました。
機能は限定されますが無料プランもあり、今回は無料プランを利用してみました。
Plans

今回は以下のような自動化の仕組みを実装しました。

  1. Redshiftに関する公式アナウンスのRSSが投稿される
  2. Zapierが1をトリガとして起動
  3. アクションとしてBacklog課題(=チケット)にAPI経由でRSSの内容を追記

1. Backlog APIキーの発行

BacklogのAPIを叩くためのキーを入手します。

Backlogにログインし、右上の自分のアバターをクリックして出るメニューから「個人設定」を選択。

左部のメニューから「API」を選択。
メモを入力して「登録」ボタンを押下。
下にAPIキー(ランダムな英数字の文字列)が出現するため、文字列をコピーします。

2. ZapierのZapの作成

Zapierのアカウントを作成します。ガイダンスに従えば、簡単に作れると思います。
右上の「Make a Zap!」ボタンを押下。
Zapとは「トリガ(何をきっかけとするか)~フィルタ(きっかけをフィルタする)~アクション(何をするか)」の設定のセットのことです。

トリガ(Zap発動のきっかけ)を選択します。
テキストフィールドにrssと入力するとサジェストされる RSS by Zapier を選択します。

New Item in Feedを選択します。(新しいFeedが来たら発動、という意味ですね)
Save + Continueを押下します。

Feed URLの欄にトリガにしたいRSSのURLを入力します。その他の欄は触らなくてもよいです。
Continueを押下します。

Item A/B/Cというのは後のステップでテスト投稿するときに使う、直近のRSS Feedです。右の▽を押すと展開されて内容が表示されますので、好きなサンプルを選びましょう。
Continueを押下します。

これでトリガの作成は完了です。次はアクションの作成です。
1. Your Zap currently lacks an Action step. Add one now!
というリンクをクリックし、アクション作成に移ります。

テキストフィールドにWebhookと入力するとサジェストされる Webhook by Zapier を選択します。
Webhookは任意のHTTPリクエストを実行できるアクションです。

POSTを選択し、Continueを押下します。(Backlogの課題追記APIはPOSTリクエストです)

URL欄に以下のように記載します。太字のyour-backlog-subdomain、your-ticket-key、your-api-keyの部分はお使いの環境・チケット名等に合わせて変更してください。

https://your-backlog-subdomain.backlog.jp/api/v2/issues/your-ticket-key/comments?apiKey=your-api-key

ここでは既存のチケットにコメントを追記するAPIとなっていますが、もちろん新規チケット起票等もできます。Backlog APIに関しては以下をご参照ください。
Backlog API とは

Payload TypeはBacklog APIの仕様に基づきFormとします。
contentには投稿に含めたい情報を入れます。右側の+ボタンを押すと、TitleやLink、DescriptionといったRSSの要素を追加することができます。テキストフィールド内で改行することで投稿内容にも改行を入れることができます。例のスクリーンショットでは「<Title>+改行++改行+」を入れています。
一番下までスクロールしてContinueボタンを押下します。

3. テスト投稿とZapの有効化

次の画面ではテストを実施することができます。
Send Test To Webhooks by Zapierを押下することで先ほどテスト用に選択したサンプルフィードを投稿することができます。
対象のBacklog課題をチェックすると、確かにコメントが追記されているはずです。

Finishを押下します。

次の画面でYour Zap is ONとします。
これで、RSSに配信があるとBacklog課題にコメントが追記されるようになります。

ポイント

・Zapierを利用することでRSSをトリガとするアクションを実行することができる
・BacklogはAPIでアクションを実行できるためZapierと組み合わせてRSSフィードの自動投稿が可能

[MSP/AWS運用代行] アラート発生件数の時系列データから、異常傾向にある環境を検出する

$
0
0

[MSP/AWS運用代行] チケットシステムのデータから、異常事態にある案件or環境を検出する

こんにちは、マネージドサービス課の橋本です。

先日執筆した[MSP/AWS運用代行] 簡単なデータ集計と可視化を使って運用の改善を考えるの関連記事です。データで運用を改善しようぜ、っていう趣旨のシリーズとして御覧いただけると幸いです。

今回も運用現場の方が対象読者です。

この記事では、ごく簡単な外れ値検出を実際の運用現場のデータに応用してみました。

前置き

CPUやメモリ、ディスクなど、所謂「リソース系」のアラートって多いですよね。当社のMSPサービスでもそうです。

リソース系アラートにおいて、即応レベルの事象が発生することは(発生頻度的に)稀です。本当にアラートして欲しいのは真に対応の必要な障害事象、もしくは深刻なリソース不足を引き起こす「予兆」などであり、リソース状況そのものではないはずなのですが、そうした理想の監視(業務フローへの反映まで含めて)実装するのはハードルあるよねぇ、などなど諸般あって簡単にはいかないことも多いかと思います。

依然として、「大量発生する緊急度低のリソースアラート」とは当面お付き合いを続ける必要がありそうです。とはいえ、それらを毎日全部パトロールする…というのも、進んでやりたいことではないです。緊急度が低いアラートであれば、必要がありそうなときだけチェックするという感じで処理できると実務的にはありがたいのかなと思います。

この「必要がありそうなときだけ」というシーンを、機械的にうまいこと判別できないだろうか?というのが本記事のテーマです。

やったこと

上で述べた前置きを実現するひとつのアプローチとして、今回はアラート発生件数の時系列データを使った外れ値検出をやってみました。平常時よりもアラートが多く発生している状態を検知します。

このネタは、「平常時より明らかに多くのアラートが挙がっている状態」を「何らかの異変の可能性」として仮定しています。大量のリソースアラートをノーヒントで眺めるよりは、見るべき対象を絞り込むのに役立つかなと。一方で、アラート件数を一度集計する必要があることから即時性には欠けます。障害対応の用途で役立つものではないので、そこはまた別な議論が必要かなと思っています。

使用したデータですが、案件ごとに日次アラート発生件数をカウントした時系列データを使っています(※)。データの粒度は好きなように設定して良いです。当社はMSPベンダーなのでひとまずは「案件ごと」を集計単位としましたが、システム単位で見ても同じ理屈は成立します。ただし、0件ばかりが並ぶ時系列データになってしまうようだと機能しづらいので、ある程度コンスタントに件数が取れる粒度であるほうが望ましいです。

※ … 厳密にはアラート件数そのものではなく、チケット管理システム(Zendesk)上に起票されたアラートのチケットを数え上げています。このあたりは以前の記事でもご紹介した、S3+Athenaを中心とするデータ基盤の存在が前提となっています。

判定ロジックはかなりシンプルです。判定対象日から起算して過去N日(Nは任意の非負整数)のチケット発生数を抜き取り、その平均と標準偏差を出します。平均±標準偏差×α (αは偏差の許容範囲を意味する任意の実数)の範囲を正常値とし、実際の観測値がその範囲外であれば外れ値として扱う。これだけです。

下記が実際の図。横軸は日付、縦軸はアラートの発生数です。 x がついている場所が外れ値判定された日を示します。ここではN=7としており、8日目以降に対して外れ値判定を適用しています。

プロトタイピング

上記のような感じで、検知のロジック部分は実装することができました。次は現場に見える形でそれをアウトプットする必要があるので、ごく簡単なプロトタイピングを行ってみました。

時系列のデータ収集&整形と検知ロジックを実装したローカル用のコマンドラインツールを作成し、そのツールが生成する結果をSlackにポストしてみました。遡る過去期間の幅や外れ値判定の範囲などは引数でコントロール可能な作りになっています。

検知された環境についてはできるだけ実際のアラート本文を確認し、簡単に私なりのコメントを入れてみるようにしています。関係者のアンテナに引っかかりやすくなったらいいな、という意図です。

理想的には全部LambdaやらDynamoやらに乗せて全自動にしたいところですが、有用性が示せないうちから実行環境に手をかけすぎてもしょうがないので、今は手作りの感あふれるスクリプトを片手に毎日手作業で検知と通知を行っています。

所感とあとがき

気持ち程度に数学要素を書いておきます(はいえ筆者は数学にさほど明るくないので、識者の方からのツッコミがあればぜひお伺いしたいです)。

まずは外れ値の判定部分について。

執筆当時のやり方では、対数系列をベースにして平均と分散を算出し、分散値を元に正常範囲を上下で決めていました。対数系列を取ったのは観測値が(上方向に)ピーキーな変動を取ることが割とあることを鑑みたものですが、今はまた違うやり方になっています。

今のロジックでは、使用するのは原系列です。外れ値判定には 観測値 >= (平均 + 許容偏差) という式を使っています(「許容偏差」は平均値の平方根に対して任意の実数係数を掛けたもの)。この式にした意図は次の2点です。

  • 関心があるのは「普段より異常に多い」状態のみなので、下側(減少)の変動を判定に加味する必要がない
  • 発生頻度の分布がポアソン分布に近いことを仮定した(許容偏差の部分に反映されている)

※ポアソン分布の分散は平均に等しいです。よって標準偏差は「平均値の平方根」となり、これを「許容偏差」の部分に当てはめています。

きれいなポアソン分布にならない環境も多々ありましたが・・・とりあえず今はこの仮定のもとでやっています。サンプルによってはパラメータの異なるポアソン分布を重ねたような、多峰性の分布が得られることもあります。

今後のアクションですが、とりあえず最低限のプロトタイピングは作ってしまったのでしばらくは様子見です。検知されるのを待ちつつ実際の現場にフィットするかどうか、実地検証で有用性を測ってみようと思います。

Codebuild上でクレデンシャルが必要なコマンドを実行したい

$
0
0

こんにちは、技術1課の岩本です。
Codebuild大好き。某メガネのCM風で始まりました今回ですが、
Codebuildは柔軟に色々なコマンドが実行できるので、便利なサービスです。

今回は、Codebuild上でコマンドを実行する際に、クレデンシャルを取得する方法を記載します。

まず結論から

buildspec.ymlには以下のように記載します。
(コマンドの実行に必要なRoleは事前にCodebuildProject自体に付与しておいてください)

---
version: 0.2

phases:
  install:
    commands:
      - apk --update add curl
      - apk --update add py-pip
      - apk --update add jq
      - pip install awscli
  pre_build:
    commands:
      - curl -qL -o aws_credentials.json 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI > aws_credentials.json
      - aws configure set region $AWS_REGION
      - aws configure set aws_access_key_id `jq -r '.AccessKeyId' aws_credentials.json`
      - aws configure set aws_secret_access_key `jq -r '.SecretAccessKey' aws_credentials.json`
      - aws configure set aws_session_token `jq -r '.Token' aws_credentials.json`
  build:
      commands:
      - echo "hello"
  post_build:
    commands:
      - echo "hollo"

解説

  • クレデンシャル取得には、以下のコマンドが必要となります、DockerImageに含まれていない場合は、Codebuild上でインストールします。
    • curl
    • awscli
    • jq
  • 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI にアクセスしMetaDataを取得します。
  • MetaDataはJson形式のため、Jqコマンドを使って必要な情報を取得します。

まとめ

上記を利用することで、PackerTerraformまた、CodenizeToolをパイプラインの一部として利用ができます。

ぜひご活用ください。


オンラインワークショップでAWS CDK を体験する

$
0
0

こんにちは、技術4課の多田です。

昨年、「AWS Cloud Development Kit」(以下、AWS CDK) が開発者プレビューですが、発表されました。

AWS CDK 開発者プレビュー

GitHub – awslabs/awscdk

AWS CDK」の特徴は、プラグラマブルに CloudFormation のプロビジョングができるので、アプリケーションの開発からインフラまで一貫した開発を行えるのがメリットになります。

今回は CDK Workshop を使って、「AWS CDK」を使ってみます。

普段は CloudFormaiton を使ってプロビジョニングを行なっているので、 CloudFormation との使いっぷりを気にしつつ触っていきます。

TL;DR

  • CDK のワークショップを使って、 CDK を実践した
    • サンプルプロジェクトとサーバーレス構成を作った
  • CDK を使ってみて CloudFormation との比較をした

AWS CDK の概要

AWS CDK」 はコードでクラウドインフラストラクチャを定義し、CloudFormation でプロビジョニングするためのオープンソースのソフトウェア開発フレームワークです。

サポートされている言語は以下の通りです。今後は Python もサポート予定とのことです。

  • TypeScript
  • JavaScript
  • Java
  • .Net

AWS CDK の実践

準備作業

環境は、AWS Cloud(以下、Cloud9) を使います。「AWS CDK」には以下の要件が必要です。

  • AWS CLI
  • Node.js (バージョンが8.11以上)

Cloud9 には AWS CLI がインストールされているのでインストール不要です。

また、Cloud9 のデフォルトの Node.js ではバージョンが満たしてないため、バージョンをあげます。

ワークショップでは、バージョンを「v8.12.0」にする必要があるため左記バージョンまでアップデートします。

$ node -v
v6.16.0
$ nvm install v8.12.0
Downloading https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.xz...
####################################################################################################################################################################### 100.0%
Now using node v8.12.0 (npm v6.4.1)

$ node -v
v8.12.0

次に、「AWS CDK」も導入します。ワークショップでは、バージョンを意図的に「0.22」を指定しています。

$ npm install -g aws-cdk@0.22.0
/home/ec2-user/.nvm/versions/node/v8.12.0/bin/cdk -> /home/ec2-user/.nvm/versions/node/v8.12.0/lib/node_modules/aws-cdk/bin/cdk
+ aws-cdk@0.22.0
added 276 packages from 255 contributors in 18.188s

$ cdk --version
0.22.0 (build 644ebf5)

東京リージョンにリソースを作りたいので、「AWS_DEFAULT_REGION」の変数をセットします。

AWS CDK」のコマンドで cdk doctor コマンドを打つと現状の設定を確認できて便利なので、上記の変数をセットした後確認します。

$ export AWS_DEFAULT_REGION=ap-northeast-1
$ cdk doctor
ℹ️ CDK Version: 0.22.0 (build 644ebf5)
ℹ️ AWS environment variables:
- AWS_DEFAULT_REGION = ap-northeast-1
- AWS_CLOUDWATCH_HOME = /opt/aws/apitools/mon
- AWS_PATH = /opt/aws
- AWS_AUTO_SCALING_HOME = /opt/aws/apitools/as
- AWS_ELB_HOME = /opt/aws/apitools/elb
ℹ️ No CDK environment variables

AWS CDK プロジェクトの作成

次に TypeScript のサンプルプロジェクトを作成していきます。

$ mkdir cdk-workshop && cd cdk-workshop
$ cdk init sample-app --language typescript
Applying project template sample-app for typescript
Initializing a new git repository...
Executing npm install...
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN cdk-workshop@0.1.0 No repository field.
npm WARN cdk-workshop@0.1.0 No license field.

# Useful commands

* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template

プロジェクト関連ファイルについて解説があったためまとめます。

  • lib/cdk-workshop-stackts.ts はCDKアプリケーションのメインスタックが定義される
  • bin/cdk-workshop.ts はCDKアプリケーションのエントリポイントになる
  • lib/cdk-workshop-stack.ts で定義されているスタックをロードされる
  • package.json はnpmモジュールのマニフェストファイルである
  • cdk.json はツールキットにアプリの実行方法を指示する
    • 今回は node bin/cdk-workshop.js になる
  • tsconfig.json はTypeScriptの設定が定義される
  • node_modules ディレクトリにはnpmによって管理され、プロジェクトのすべての依存関係を含まれる

サンプルプロジェクトでは、以下のリソースを作ります。

  • SQS キュー
  • SNS トピック
  • SQS キューを SNS トピックでサブスクライブ

import sns = require('@aws-cdk/aws-sns');
import sqs = require('@aws-cdk/aws-sqs');
import cdk = require('@aws-cdk/cdk');

export class CdkWorkshopStack extends cdk.Stack {
 constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
  super(scope, id, props);

  const queue = new sqs.Queue(this, 'CdkWorkshopQueue', {
  visibilityTimeoutSec: 300
});

  const topic = new sns.Topic(this, 'CdkWorkshopTopic');

  topic.subscribeQueue(queue);
 }
}

アプリケーションコードから CloudFormation テンプレートの確認とデプロイ

cdk synth を実行すると CDK で作る、 CloudFormation のテンプレートを確認できます。

$ cdk synth
Resources:
  CdkWorkshopQueue50D9D426:
    Type: AWS::SQS::Queue
    Properties:
      VisibilityTimeout: 300
    Metadata:
      aws:cdk:path: CdkWorkshopStack/CdkWorkshopQueue/Resource
  CdkWorkshopQueuePolicyAF2494A5:
    Type: AWS::SQS::QueuePolicy
    Properties:
      PolicyDocument:
        Statement:
          - Action: sqs:SendMessage
            Condition:
              ArnEquals:
                aws:SourceArn:
                  Ref: CdkWorkshopTopicD368A42F
            Effect: Allow
            Principal:
              Service: sns.amazonaws.com
            Resource:
              Fn::GetAtt:
                - CdkWorkshopQueue50D9D426
                - Arn
        Version: "2012-10-17"
      Queues:
        - Ref: CdkWorkshopQueue50D9D426
    Metadata:
      aws:cdk:path: CdkWorkshopStack/CdkWorkshopQueue/Policy/Resource
  CdkWorkshopTopicD368A42F:
    Type: AWS::SNS::Topic
    Metadata:
      aws:cdk:path: CdkWorkshopStack/CdkWorkshopTopic/Resource
  CdkWorkshopTopicCdkWorkshopQueueSubscription88D211C7:
    Type: AWS::SNS::Subscription
    Properties:
      Endpoint:
        Fn::GetAtt:
          - CdkWorkshopQueue50D9D426
          - Arn
      Protocol: sqs
      TopicArn:
        Ref: CdkWorkshopTopicD368A42F
    Metadata:
      aws:cdk:path: CdkWorkshopStack/CdkWorkshopTopic/CdkWorkshopQueueSubscription/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Modules: aws-cdk=0.22.0,@aws-cdk/aws-cloudwatch=0.22.0,@aws-cdk/aws-iam=0.22.0,@aws-cdk/aws-kms=0.22.0,@aws-cdk/aws-s3-notifications=0.22.0,@aws-cdk/aws-sns=0.22.0,@aws-cdk/aws-sqs=0.22.0,@aws-cdk/cdk=0.22.0,@aws-cdk/cx-api=0.22.0,jsii-runtime=node.js/v8.12.0

 

続いて、CloudFormation のデプロイを行なっていきます。

AWS CDK」アプリを初めてデプロイするときに「bootstrap stack」をインストールする必要があります。

bootstrap stack」では、CloudFormation テンプレートを格納する S3 が用意されます。

$ cdk bootstrap
Bootstrapping environment xxxxxxxxxxx/ap-northeast-1...
CDKToolkit: creating CloudFormation changeset...
0/2 | 04:30:07 | CREATE_IN_PROGRESS | AWS::S3::Bucket | StagingBucket 
0/2 | 04:30:09 | CREATE_IN_PROGRESS | AWS::S3::Bucket | StagingBucket Resource creation Initiated
1/2 | 04:30:30 | CREATE_COMPLETE | AWS::S3::Bucket | StagingBucket 
2/2 | 04:30:32 | CREATE_COMPLETE | AWS::CloudFormation::Stack | CDKToolkit 
Environment xxxxxxxxxxx/ap-northeast-1 bootstrapped.

コマンドが成功すると、 CloudFormation スタックが作成されS3バケットが作成されます。

$ cdk deploy
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

~中略~~

CdkWorkshopStack

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxx:stack/CdkWorkshopStack/a5bd1260-31a4-11e9-87b8-0ec110ab8a1e

 CloudFormation のコンソールを確認するとスタックが出来上がっているのを確認できました。 

次の作業のためにサンプルで作成したリソースを削除します。

lib/cdk-workshop-stack.tsを以下のように編集します。

import cdk = require('@aws-cdk/cdk');

export class CdkWorkshopStack extends cdk.Stack {
 constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
 super(scope, id, props);

 }
}

変更後のリソースの変化の確認の仕方は、cdk diff で確認可能です。

$ cdk diff
IAM Statement Changes
~中略~

Resources
[-] AWS::SQS::Queue CdkWorkshopQueue50D9D426 destroy
[-] AWS::SQS::QueuePolicy CdkWorkshopQueuePolicyAF2494A5 destroy
[-] AWS::SNS::Topic CdkWorkshopTopicD368A42F destroy
[-] AWS::SNS::Subscription CdkWorkshopTopicCdkWorkshopQueueSubscription88D211C7 destroy

変更内容が問題なければ、再度 cdk deploy を実行します。

$ cdk deploy
CdkWorkshopStack: deploying...
CdkWorkshopStack: creating CloudFormation changeset...
~中略~

CdkWorkshopStack

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxx:stack/CdkWorkshopStack/a5bd1260-31a4-11e9-87b8-0ec110ab8a1e

Lambda と API Gateway の構成方法

次に、AWS Lambda(以下、Lambda)、Amazon API Gateway(以下、APIGW)のサーバーレス構成を CDK で行います。

まず最初に、Lambda のコードを作成します。

binやlibと同じ階層に lambda/hello.js を作成し、以下のコードを記載します。

APIGW の URI にアクセスすると、「Hello, CDK! You’ve hit /(アクセスしたパス)」と返すコードになります。

exports.handler = async function(event) {
 console.log('request:', JSON.stringify(event, undefined, 2));
 return {
  statusCode: 200,
  headers: { 'Content-Type': 'text/plain' },
  body: `Hello, CDK! You've hit ${event.path}\n`
 };
};

加えて、 Constructs ライブラリを追加します。このライブラリは AWS サービスごとにあり、AWSのベストプラクティスに従った設定を内包しています。

今回でいうと、 Lambda を定義したり、 APIGW を定義するには上記のライブラリをインストールする必要があります。

$ npm install @aws-cdk/aws-lambda@0.22.0
npm WARN cdk-workshop@0.1.0 No repository field.
npm WARN cdk-workshop@0.1.0 No license field.

+ @aws-cdk/aws-lambda@0.22.0
updated 1 package and audited 1901 packages in 3.194s
found 0 vulnerabilities
$ npm install @aws-cdk/aws-apigateway@0.22.0
npm WARN cdk-workshop@0.1.0 No repository field.
npm WARN cdk-workshop@0.1.0 No license field.

+ @aws-cdk/aws-apigateway@0.22.0
added 1 package from 1 contributor and audited 2476 packages in 6.122s
found 0 vulnerabilities

 

APIGW と Lambda を統合するコードを lib/cdk-workshop-stack.tsに追記します。

cdk diff で変更箇所の確認してみます。

$ cdk diff
The CdkWorkshopStack stack uses assets, which are currently not accounted for in the diff output! See https://github.com/awslabs/aws-cdk/issues/395
IAM Statement Changes
~中略~

Outputs
[+] Output Endpoint/Endpoint Endpoint8024A810: {"Value":{"Fn::Join":["",["https://",{"Ref":"EndpointEEF1FD8F"},".execute-api.",{"Ref":"AWS::Region"},".",{"Ref":"AWS::URLSuffix"},"/",{"Ref":"EndpointDeploymentStageprodB78BEEA0"},"/"]]},"Export":{"Name":"CdkWorkshopStack:Endpoint8024A810"}}

それでは、デプロイしてみます。

$ cdk deploy
Do you wish to deploy these changes (y/n)? y
CdkWorkshopStack: deploying...
Updated: lambda (zip)
CdkWorkshopStack: creating CloudFormation changeset...

~中略~

CdkWorkshopStack

Outputs:
CdkWorkshopStack.Endpoint8024A810 = https://vam8k4pk2e.execute-api.ap-northeast-1.amazonaws.com/prod/

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/CdkWorkshopStack/a5bd1260-31a4-11e9-87b8-0ec110ab8a1e

デプロイされたエンドポイントに対して、アクセスしてみたら想定通りの結果が帰ってきました。

$ curl https://vam8k4pk2e.execute-api.ap-northeast-1.amazonaws.com/prod/
Hello, CDK! You've hit /

DynamoDB リソースの追加

次に、Amazon DynamoDB(以下、DynamoDB)のリソースを追加します。

アクセスした URI のパスを DynamoDB のテーブルに記録する処理を定義するものを定義します。

まずは、DynamoDB の Constructs ライブラリをインストールします。

$ npm install @aws-cdk/aws-dynamodb@0.22.0
npm WARN cdk-workshop@0.1.0 No repository field.
npm WARN cdk-workshop@0.1.0 No license field.

+ @aws-cdk/aws-dynamodb@0.22.0
added 3 packages from 1 contributor and audited 2564 packages in 10.132s
found 0 vulnerabilities

lambda/hitcounter.js に以下のコードを追加します。

const { DynamoDB, Lambda } = require('aws-sdk');

exports.handler = async function(event) {
  console.log("request:", JSON.stringify(event, undefined, 2));

  // create AWS SDK clients
  const dynamo = new DynamoDB();
  const lambda = new Lambda();

  // update dynamo entry for "path" with hits++
  await dynamo.updateItem({
    TableName: process.env.HITS_TABLE_NAME, # DynamoDBテーブルの名前
    Key: { path: { S: event.path } },
    UpdateExpression: 'ADD hits :incr',
    ExpressionAttributeValues: { ':incr': { N: '1' } }
  }).promise();

  // call downstream function and capture response
  const resp = await lambda.invoke({
    FunctionName: process.env.DOWNSTREAM_FUNCTION_NAME, #Lambda関数名
    Payload: JSON.stringify(event)
  }).promise();

  console.log('downstream response:', JSON.stringify(resp, undefined, 2));

  // return response back to upstream caller
  return JSON.parse(resp.Payload);
};

lib/hitcounter.ts は次のように編集します。

import cdk = require('@aws-cdk/cdk');
import lambda = require('@aws-cdk/aws-lambda');
import dynamodb = require('@aws-cdk/aws-dynamodb');

export interface HitCounterProps {
  /** the function for which we want to count url hits **/
  downstream: lambda.Function;
}

export class HitCounter extends cdk.Construct {
  /** allows accessing the counter function */
  public readonly handler: lambda.Function;

  constructor(scope: cdk.Construct, id: string, props: HitCounterProps) {
    super(scope, id);

    const table = new dynamodb.Table(this, 'Hits');
    table.addPartitionKey({ name: 'path', type: dynamodb.AttributeType.String });

    this.handler = new lambda.Function(this, 'HitCounterHandler', {
      runtime: lambda.Runtime.NodeJS810,
      handler: 'hitcounter.handler',
      code: lambda.Code.asset('lambda'),
      environment: {
        DOWNSTREAM_FUNCTION_NAME: props.downstream.functionName,
        HITS_TABLE_NAME: table.tableName
      }
    });

    // grant the lambda role read/write permissions to our table
    table.grantReadWriteData(this.handler.role);

    // grant the lambda role invoke permissions to the downstream function
    props.downstream.grantInvoke(this.handler.role);
  }
}

lib/cdk-workshop-stack.ts は次のように編集します。

import cdk = require('@aws-cdk/cdk');
import lambda = require('@aws-cdk/aws-lambda');
import apigw = require('@aws-cdk/aws-apigateway');
import { HitCounter } from './hitcounter';

export class CdkWorkshopStack extends cdk.Stack {
 constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
  super(scope, id, props);

  const hello = new lambda.Function(this, 'HelloHandler', {
  runtime: lambda.Runtime.NodeJS810,
  code: lambda.Code.asset('lambda'),
  handler: 'hello.handler'
  });

  const helloWithCounter = new HitCounter(this, 'HelloHitCounter', {
  downstream: hello
  });

  // defines an API Gateway REST API resource backed by our "hello" function.
  new apigw.LambdaRestApi(this, 'Endpoint', {
  handler: helloWithCounter.handler
  });
 }
}

それではデプロイします。

$ cdk deploy
~中略~

CdkWorkshopStack

Outputs:
CdkWorkshopStack.Endpoint8024A810 = https://vam8k4pk2e.execute-api.ap-northeast-1.amazonaws.com/prod/

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/CdkWorkshopStack/a5bd1260-31a4-11e9-87b8-0ec110ab8a1e

URI にアクセスしてみます。

$ curl -i https://vam8k4pk2e.execute-api.ap-northeast-1.amazonaws.com/prod/
Hello, CDK! You've hit /
$ curl -i https://vam8k4pk2e.execute-api.ap-northeast-1.amazonaws.com/prod/hello
Hello, CDK! You've hit /hello
$ curl -i https://vam8k4pk2e.execute-api.ap-northeast-1.amazonaws.com/prod/test
Hello, CDK! You've hit /test

3回アクセスしたので、 DynamoDB のテーブルに3つレコードが登録されていることを確認できました。最後は、作ったリソースを削除しますが、cdk destroy を実行します。

$ cdk destroy
Are you sure you want to delete: CdkWorkshopStack (y/n)? y
CdkWorkshopStack: destroying...
~中略~
CdkWorkshopStack: destroyed

AWS CDK と CloudFormation の比較考察

AWS CDK」を使ってみてのメリット/デメリットを CloudFormation を使う場合と比較してみます。

AWS CDK と CloudFormation を比較してみて感じたメリット

  • 普段書き慣れている言語であれば、YAML や JSON の CloudFormation よりは書きやすい
  • 感覚的にリソースのデプロイが CloudFormation よりは簡易
    • !Ref のような関数を使わなくても関連リソースの定義ができるのはよかった
    • 例えば、Lambda の IAM ロール設定が table.grantReadWriteData(this.handler.role); だけなので、CloudFormation のように ARN を指定しなくていいのでシンプルだと感じた
  • IDEで書いているため、コードの中でのライブラリ定義の参照元などをすぐに調べやすい

AWS CDK と CloudFormation を比較してみて感じたデメリット

  • サポートされてる言語の習得が必須であること
  • 自由度が高く CloudFormation テンプレートを書けるのでプロジェクト内での運用ルールを考える必要はありそう
  • CloudFormation のサポートしている JSON や YAMLの方が開発者が馴染むのなら CloudFormation の方が良い

まとめ

AWS CDK」を使った AWS リソース構成の実践と、 CloudFormation との使い分けを自分なりに考察してみました。

現状サポートされている言語が少ないものの、個人的には今後の Python サポートが楽しみです。

プログマブルに条件分岐や繰り返しの処理などを組み合わせて、 CloudFormation だけではできなかった運用ができそうです。

なお、 Constructs ライブラリのレファレンスはこちらです。

本リリースまでに CloudFormation で作ったソースを置き換えたりしてみて更に使い込んでみたいです。

【EC2】T系ファミリーの概要と、T2,T3の仕様の違いについてのまとめ

$
0
0

こんにちは、技術4課の城です。
先日JAWSDAYS2019に当日スタッフとして参加してきました。
セッションスタッフでしたのでセッションを聞くこともでき、とてもいい経験をさせていただきました。

その中で、JAWS初心者支部 武田さんのセッションでT2のCPUCreditについてお話をされてまして、自分も整理しないとなと思い、このブログでアウトプットします。

T系ファミリーとは

ドキュメントではバーストパフォーマンスインスタンスと表現されています。
ここでのバーストとはベースラインパフォーマンスからのバーストを意味しています。
例えばt3.microの1vCPU当たりのベースラインパフォーマンスは10%ですが、CPUCreditを利用することでそれ以上のCPU性能を利用することが出来ます。
概要イメージは下記となります。

参考ページ:バースト可能パフォーマンスインスタンスの CPU クレジットおよびベースラインパフォーマンス
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/burstable-credits-baseline-concepts.html

CPUCredit

CPUCreditとはT系のインスタンスにおいてCPUを利用する権利のようなものです。
1CPUCreditで1つのvCPUを使用率100%で1分間実行することが出来ます。
1つのvCPUを50%で2分間、2つのvCpu25%で2分間など、どちらも等しく1CPUCreditを消費します。
イメージ図では「水」がCPUCreditを表しています。

時間(ミリ秒レベルの細かさ)でCPUCreditを獲得し、CPUリソースを使用するとCPUCreditが消費されます。

ベースラインパフォーマンス

ベースラインパフォーマンスとはイメージ図のところのバケツ内の水の量が変わらないCPU使用率を表します。
具体的には下記が成立する状態です。

獲得CPUCredit = CPUCreditUsage(利用したCPUCredit)

実際のCPU使用率がベースラインパフォーマンスを下回っていれば、獲得CPUCreditの方が多くなるため、CPUCreditを蓄積することが出来ます。

蓄積可能な最大CPUCredit

蓄積可能な最大CPUCreditとはイメージ図のところのバケツの容量です。
24時間分のCPUクレジット獲得量となっています。
これを超えた分については蓄積されずに破棄されます。

T2,T3の仕様の違い

旧世代のT2と最新世代のT3ですが、仕様として違いがありますのでまとめてみます。

スペックの違い

まず、スペックの違いについて比較表を作ってみました。

※コストはWindowsで記載しています。
※セルの背景色については単純にその項目のみで比較して、「対T2で優位=青」、「対T2で劣位=赤」としています。

大きく違うところと言えば、nano,micro,smallについてはvCPU数が増えていて、その分CPUCredit関連も増えています。
コストは微増と言ったところでしょうか。
medium,largeについては同スペックですが、コストが削減されています。
xlarge,2xlargeについてはCPUCredit関連が増強されており、コストも微増です。

起動クレジット

T2ファミリーには起動クレジットという概念があります。
これはインスタンスのローンチ時、及び、スタート時にvCPU あたり 30の起動クレジットを獲得できます。
T3インスタンスには起動クレジットは存在せず、初回ローンチ時はCPUCreditは0となります。
ただし、T3インスタンスのデフォルト設定はunlimitedオプションがオンになっているため、オフにしなければ、初回ローンチ時からCPUリソースをゴリゴリ利用することができます。
また、T2インスタンスであってもunlimitedオプションをオンにすると起動クレジットを獲得できなくなりますので、ご注意ください。

起動クレジット
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/burstable-performance-instances-standard-mode.html#launch-credits

バーストパフォーマンスインスタンスの無制限モード
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/burstable-performance-instances-unlimited-mode.html

CPUCreditの失効

実行中のインスタンスのCPUCreditは失効しませんが、T2,T3それぞれ下記の条件でCPUクレジットが失効します。

T2:インスタンスを停止した場合
T3:インスタンス停止後、7日間経過

T2は停止した時点でCPUCreditが失われてまうので注意が必要です。

まとめ

今回はT系インスタンスの概要とT2,T3の世代間での仕様の違いをまとめてみました。
T系ファミリーはその他のファミリーと比べ、コストが低く、人気が高いかと思われますが、本番利用する場合はCPUCreditの仕様等に注意し、安全に利用しましょう。

どなたかの助けになれば幸いです。

AWSサポートの『技術的なお問い合わせに関するガイドライン』を読もう!

$
0
0

こんにちは、PS課のミネです。

普段からAWSを利用しているとドキュメント記載されていない仕様についての問い合わせや障害時のトラシュで、AWSサポートに問い合わせることはあるかと思います。

しばらく前に技術的なお問い合わせに関するガイドラインが公開されました。ここにかいてあることが守れていれば、よい問い合わせといえるのではないでしょうか。

今回はよりよい問い合わせをするために、『技術的なお問い合わせに関するガイドライン』読んでみました。

件名や本文に「緊急」等と記載されても、緊急度は上がりません。

でしょうね、という感じです。

緊急度を設定できるので、問い合わせする際は適切な緊急度を設定しましょう。

解決したい課題を明確にする

  • 解決したい課題を明確にご記載ください
  • 障害と判断した状況をご共有ください
  • 最終的に実現したいことと現在の状況を詳しくご共有ください

せやな、という感じです。

「(あれ?ELBにアクセスできひんなぁ。ワシがした設定には問題ないはずやけど、どないなってんねんやろ?)いま、ELBはメンテナンス中ですか?」と含みを持たせるのではなく、「ELBのhogehogeに、外部からアクセスできなくなりました。」と直球で解決したい課題を投げてほしいとのこと。

状況を正確に共有する

  • 対象リソースとリージョンを明記してください
  • 事象の発生時刻(TimeZone 付き)と継続状況についてお知らせください
  • ログ類や画面キャプチャの共有をご検討ください

そやな、という感じです。

「いつ」・「どれ」がわからないとサポートする側も調査も何もしようがありません。

経緯を共有する

  • 事象を再現する手順の共有をお願いいたします
  • すでに試した対応策があればご教示ください

何か手順に従って作業を実施しているなら、その手順があるとサポートする側も検証しやすいでしょう。
試した対応策も伝えると二度手間になりません。

まとめ

その他にもちょっとしたTIPSやサポートへの評価についての記載もあります。また、AWSサポートからの案内が難しい質問についても記載があります。ガイドラインの内容は、AWSサポートによく問い合わせをする人はもちろん読んで頭に入れておいた方が良いでしょう。初めて問い合わせをする人にとっては、どんな内容を入れればよいか参考になると思います。

このガイドラインに載っていることはAWSサポートだけでなく、他のサービスでも意識すべきことかもしれません。

ちなみに…

このガイドライン、日本語だけで公開されているようです。ガイドラインのページを他の言語に変えると、404エラーでページが表示されません。

日本語の特性なのか日本人の国民性なのか、抽象的であまりよろしくない問い合わせが多かったのかも…

PowerShellでLambdaを実装しよう!~SlackのBotを実装してみた~

$
0
0

技術4課のPowerShellおじさんこと、鎌田です。社内でPowerShellを実装できる人が増えてきたので、ちょっと焦りも感じつつ。

先のブログで、LambdaをPowerShellで実装しデプロイまでを解説しました。
せっかくLambdaをPowerShellで実装できる準備をしたので、SlackのBotを実装してみることにしました。

PowerShellがSlackに投稿するための準備

Slackに対してPowerShellが投稿するためには、Slack側でIncoming WebHooksのURLの用意が必要です。

SlackのWorkSpaces名をクリックし、メニューから「Customize Slack」をクリック。

左のメニューから「Configure apps」をクリック。

左のメニューから「Custom Ontegraions」をクリックし、Incomming WebHooks」をクリック。

「Add Configuration」をクリック。

ポストするチャンネルを聞かれるので、チャンネルを選びましょう。チャンネルを選んだら、「Add Incoming WebHooks integration」をクリック

Webhook用のURLが生成されます。Webhook URLをコピーして、後ほどのコードに埋め込みます。

ここまで出来たら、準備完了です。

実際に実装してみた

「もう定時だよ、帰らないの?」と通知してくれるBotのコードはこんな感じです。

function convert_text($before_text) {
    $enc = [System.Text.Encoding]::GetEncoding('ISO-8859-1')
    $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($before_text)
    return $enc.GetString($utf8Bytes)
}

$slack_hook_url = "先程取得したIncoming WebHooksのURL"

$payload_array = @{
    text = convert_text("もう定時だよ、帰らないの?");
    username = convert_text("定時お知らせくん");
    channel = "投稿したいSlackチャンネル"
}

Invoke-WebRequest -Method Post -Uri $slack_hook_url -Body (ConvertTo-Json $payload_array)

IncommingWebHookに対してJsonでパラメタを渡しますが、渡すパラメタを配列で作って、PowerShellからInvokeでURLをリクエストする時に、ConvertoTo-JsonでJsonに変換をかけています。
PowerShellではそのまま日本語をJSONで送ってはエラーになるため、変換処理を挟んでいます。
少し処理を変えることで、botを改変できるので、投稿するテキストやユーザー名などは、色々と調整してみてください!

実際にPowerShellを実行してみた

Lambdaでデプロイ後、実際に起動してみると、以下のようにSlackへ投稿されます。

意外と簡単に作れますね。

終わりに

SlackBotをPowerShellで実装したものをご紹介しました。
PowerShellでもサーバーレスできます、自信をもって「サーバーレスやってる」と言いましょう。

Active DirectoryとAD ConnectorとWorkSpacesの関係

$
0
0

技術4課のVDIおじさん、かつ認証認可おじさんの鎌田です。

Active DirectoryとAD ConnectorとWorkSpacesの関係、分かったようで分かりづらいですよね。
この分かりづらい三角関係をちょっと紐解いてみたいと思います。

図示してみる

この分かりづらい関係を、ちょっと図示してみました。

  • Active Directoryはユーザーのオブジェクトを持っている場所
    • AD Connectorから来た認証情報が自分自身で保持しているか確認して、適切な応答をする
  • AD ConnectorはWorkSpaces接続時に認証情報をActive Directoryへスルーパスしてくれる
    • 認証の橋渡し役
  • WorkSpacesログイン後は、ドメインに関する情報は直接Active Directoryのサーバーに問い合わせている

AD Connectorの役割

Directory ServiceにおけるAD Connectorの役割として、

  • Active DirectoryのサーバーとWorkSpacesを同一ネットワークから分離する
  • WorkSpacesログイン時の認証情報をActive Direcotryに流す

という2つがあります。

このうち、後者の役割を果たすケースが多いため、AD Connector自身が認証機能さえ持っているのでは、と誤解されるケースが少なくありません。

しかし、AD ConnectorとWorkSpacesは同一IPセグメントへの展開が必須となっています。
このため、Active Directoryへのアクセスが必須となるAD Connectorが存在するセグメントは、WorkSpacesも同一IPセグメントですから、わざわざAD Connectorを介して接続する必要がありません。
WorkSpaces接続後、実際にドメイン関係の情報を確認していくと、WorkSpaces上ではDNSとしてActive Directoryのサーバーになるように設定が実施されています。
またWorkSpacesではVPCのOptionSetが指定されていたとしてもAD Connectorで指定されているDNSのIPアドレスがWorkSpacesにも割り当てられる形になっています。

まとめ

1.AD Connectorは認証情報を保持していない、Active Directoryにお任せ
2.WorkSpacesはAD ConnectorのDNSのIPアドレスがWorkSpacesのDNSの向き先として指定される
3,VPC OptionSetが設定されているVPCでも、WorkSpacesはその影響を受けず、2.の通りでDNSの向き先がされる

WorkSpacesはDirectory Servivceは付随して覚える必要のある箇所が多いサービスではありますが、どのように動いているか設定値などから整理していくと、見えてきます。
サーバー間のAWS上の関係だけではなく、OSの中の設定にも目を向けてみましょう。

CloudWatchのメトリクスをコマンドで取得する

$
0
0

技術4課の鎌田(裕)です。
CloudWatchのメトリクス、マネジメントコンソールで確認される方は多いと思いますが、メトリクスをコマンドラインで取得したいケースもあると思います。
色々な都合でAWS CLIとPowerShellの両方を比較しながら取得したかったのですが、意外と同じデータを取れる情報が並べて書かれている記事がなかったので、こちらのブログでは、AWS CLIとAWS Tools for PowerShellの両方の方法を記載します。

必要なパラメータ

CloudWatchの概念(https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html)でも
解説されている、各種パラメタを指定します。指定するパラメタは以下の通りです。

AWS CLI PowerShell 説明
namespace Namespace メトリクスを取得するAWSのサービスを指定します。EC2であればAWS/EC2を指定します。
metric-name MetricName 取得したいメトリクスの指定をします。CPU使用率であればCPUUtilizationを指定します。
statistics Statistic メトリクスの平均値/最大値/最小値など、いずれの情報を取得したいのか指定をします。最大値であればMaximumです。
period Period メトリクスを取得する間隔を秒で指定します。5分間隔であれば300を指定します。
start-time UtcStartTime メトリクスを表示したい日時の先頭となる日時を指定します。
end-time UtcEndTime メトリクスを表示したい日時の最後となる日時を指定します。
dimensions Dimension メトリクスを一意に識別する名前/値のペアを指定します。

AWS CLIで取得してみる

実際にコマンドで取得してみましょう。
以下のコマンドでは、EC2のCPU使用率の最大値を、指定した日時の期間、5分間隔で出力する例です。

aws cloudwatch get-metric-statistics --namespace AWS/WorkSpaces --metric-name UserConnected --statistics Maximum --period 300 --start-time 2019-02-26T23:00:00Z --end-time 2019-02-27T00:00:00Z --dimensions "Name=WorkspaceId,Value=ws-xxxxxxxx"

結果はjsonで返されます。

PowerShellで取得してみる

基本はAWS CLIと同じですが、PowerShellで取得する場合、Dimensionは一度オブジェクトを生成する必要があります。
EC2と同じように取得すると、下記のようになります。

$dimension = New-Object Amazon.CloudWatch.Model.Dimension
$dimension.set_Name("WorkspaceId")
$dimension.set_Value("ws-xxxxxxxx")
$date1 = ([Datetime]"2019/2/27 8:00:00").ToUniversalTime()
$date2 = ([Datetime]"2019/2/27 9:00:00").ToUniversalTime()
Get-CWMetricStatistics -Region ap-northeast-1 -Namespace AWS/WorkSpaces -MetricName UserConnected -UtcEndTime $date2 -UtcStartTime $date1 -Statistic Maximum -Period 600 -Dimension $dimension

結果はDatapointsというオブジェクトで返されます。Datapointsの中は配列になっています。
Get-CWMetricStatisticsの結果を$dataという変数に入れたあと、Datapointsの0番目のデータを見てみると、次のような値が取得できます。

日付の指定について

上記のコマンド実行例では、AWS CLIでは、UTCの時間を計算して指定しています。
一方、PowerShellでは日本時間で記載の上、PowerShellで変換をかけた上でコマンドの引数に使っています。
PowerShellの方が、日付の指定は直間的で分かり易いかも知れません。

終わりに

CloudWatchのメトリクスをコマンドで取得することで、運用などでもご活用いただけると思います。
なかなかAWS CLIとPowerShellで同じ実行例が並んでいなかったためこのブログ記事を書きました。
ご参考になれば幸いです。

AWS CLIのエラー「Could not connect to the endpoint URL」

$
0
0

きっとこのブログを見たアナタはAWS CLIで何かを実行したときに,

Could not connect to the endpoint URL: ~

とエラーが出て困っているのでしょう。

そのエラー、aws configureで設定したリージョンが間違えているのではないでしょうか?

例えば不要な-が入っているとか…

$ cat ./.aws/config
[default]
region = ap-north-east-1 #正しくはap-northeast-1

もしくは実行しようとしてるAWSサービスがaws configureで設定したリージョンで提供されていないのではないでしょうか?

この場合は以下のオプションでAWS CLIコマンド実行時にリージョンを指定します。

--region us-east-1


【SQL Server on EC2】インスタンス間でAlwaysOnを構成する [3.AlwaysOn設定編] –そして伝説へ –

$
0
0

こんにちは。技術4課の伊藤Kです。
タイトルの末尾は「3」から連想したフレーズなので深い意味はありません。

今回は「2台のEC2インスタンス間でSQL Server AlwaysOnを構成する」の第3回、「AlwaysOn設定編」です。
いよいよ最終回、AlwaysOnの設定です。
前回から間があいてしまい、全国のSQL Server on EC2ファンには申し訳なく思います。

<全3回リンク>
1. OS準備編
2. WSFC設定編
3. AlwaysOn設定編 (この記事)

作業前の状態、前提

「2. WSFC設定編」の手順を完了した状態を前提とします。
作業は「AWS Delegated Administrators」グループに所属させたユーザーアカウントで実施します。

バージョンエディション、IPアドレス等の情報を再掲します。

OS Windows Server 2012 R2 Standard Edition
SQL Server SQL Server 2014 Enterprise Edition SP2 (12.0.5000.0)
内容 コンピューター名 /
リソース名 /
リスナー名
IPアドレス
AlwaysOn インスタンス #1
(文中「1号機」と記します)
sql01 172.20.10.4
AlwaysOn インスタンス #2
(文中「2号機」と記します)
sql02 172.20.11.4
クラスターコアリソース t-cluster 172.20.10.5 / 172.20.11.5
AlwaysOn リスナー t-aonlis01 172.20.10.6 / 172.20.11.6

サービスの設定変更

1号機でWindowsのスタートメニューより「SQL Server 2014 Configuration Manager」を開きます。

「SQL Server サービス」を開き、「SQL Server インスタンス名」のアイコンを右クリックし、「プロパティ」を選択します。

「ログオン」タブでサービスを起動するユーザーアカウント(以下「サービスユーザーアカウント」と記します)をドメインアカウントに変更します。(このアカウントは1号機、2号機で共通のものを使用します。)ここでは、現在ログオンしている「AWS Delegated Administrators」グループのユーザーアカウントを使用します。

「AlwaysOn High Availability」タブで「Enable AlwaysOn Availability Groups」にチェックを入れます。[OK]ボタンをクリックしてプロパティを閉じます。

確認のダイアログが表示されるので[OK]ボタンをクリックします。

確認のダイアログに従い、「SQL Server インスタンス名」のアイコンを右クリックして「再起動」(Restart)を選択することでサービスを再起動させます。

2号機でもWindowsのスタートメニューより「SQL Server 2014 Configuration Manager」を開き、同一の手順を実施します。

フォルダ準備

各サーバー(インスタンス)にデータベースファイルを格納するフォルダを作成します。1号機、2号機とも同じパスである必要があります。
ここでは「C:\SQL_DATA」とします。

作成したフォルダに対してサービスユーザーアカウントが「変更」の権限を持つ必要があります。ここでは「AWS Delegated Administrators」グループのユーザーを使っており、デフォルトで要件以上の権限があるので特に設定は行いません。

2号機でも「C:\SQL_DATA」を作成します。

さらに、1号機、2号機間で初回同期を実施するための一時的な共有フォルダを作成します。これは1号機、2号機からアクセスできる場所に1つあればOKです。
ここでは、1号機に「wkshare」というフォルダを作成し、以下の権限で共有設定をします。

共有名 wkshare
共有許可設定 Everyone – フルコントロール
NTFS権限設定 (デフォルトのまま)


 

 

 

ログイン追加

1号機で、一度OSをサインアウトした後に、ローカル管理者(Administrator)でログインしなおします。

スタートメニューからSQL Server Management Studioを起動します。

Windows認証で1号機へ接続します。

1号機の「セキュリティ」→「ログイン」を右クリックして、「新しいログイン」メニューを選択します。

[検索]ボタンをクリックします。

[場所]ボタンをクリックすると資格情報を求められるので、ドメインユーザーのアカウントとパスワードを入力します。ここではサービスユーザーアカウントを使用します。

 

ドメイン名を選択して[OK]ボタンをクリックします。

サービスユーザーアカウント名を入力して[名前の確認]をクリックすると下線が付帯されます。[OK]をクリックします。

サービスユーザーアカウントが「ログイン名」に追加されます。

「サーバーロール」タブをクリックして「sysadmin」にチェックを入れて[OK]をクリックします。

「ログイン」一覧にサービスユーザーアカウントが追加されます。

現在ローカルのAdministratorでログオンしているので、一度OSをサインアウトした後に、サービスユーザーアカウントでログオンします。

2号機も同じ手順でログインを追加します。

追加後は、同じく一度OSをサインアウトした後に、サービスユーザーアカウントでログオンします。

可用性グループの作成、データベース登録

1号機でOSのスタートメニューからSQL Server Management Studioを起動します。

Windows認証で1号機へ接続します。

オブジェクトエクスプローラーの「接続」→「データベースエンジン」メニューから2号機へも接続します。

対象となるデータベースを一度「完全復旧モデル」の設定でバックアップする必要があります。
1号機のツリーから対象のデータベースを右クリックし、「プロパティ」を選択します。ここではテスト用に作成した「test_db」を対象とします。

「オプション」ページをクリックして、復旧モデルを「完全」に変更します。[OK]をクリックします。

再度対象のデータベースを右クリックし、[タスク] – [バックアップ] を選択します。

バックアップ先のパスは任意で構いません。ここではデフォルトで進めます。[OK]をクリックします。

バックアップが完了しました。

「AlwaysOn 高可用性」を展開して「可用性グループ」を右クリックします。[新しい可用性グループ ウィザード] を選択します。

[次へ]をクリックして進めます。

任意のグループ名を入力して[次へ]をクリックします。ここでは予定のリスナー名と同一にします。

先ほどバックアップを取った対象のデータベース名であることを確認し、チェックを入れて[次へ]をクリックします。

「レプリカ」タブで[レプリカの追加] をクリックして、2号機のホスト名を指定してWindows認証で接続することで、2号機が一覧に追加されます。

「自動フェールオーバー」「可用性モード」等の項目は要件に沿って設定します。ここでは下図の通りとします。他のタブもデフォルトのまま[次へ]をクリックします。

[完全なデータベースとログバックアップ] を選択し、先ほど初回同期用に作成した共有フォルダの共有パスを入力します。エクスプローラーでパスを入力してフォルダを開けることを確認し、そのパスをコピー貼り付けすると、ミスを防げます。[次へ]をクリックします。

要件の検証が行われます。「警告」が発生していますが、リンクをクリックして内容を確認し、「可用性グループリスナーをまだ作成していない」内容であれば後の手順で作成するので問題ないため、そのまま[次へ]をクリックします。

 

サマリーが表示されるので、一通り確認して[完了]ボタンをクリックします。

ウィザードが実行され、可用性グループが作成されます。

「可用性グループ」のツリーを展開すると、「可用性レプリカ」や「可用性データベース」が追加されています。

可用性グループリスナーの構成

いよいよ、可用性グループリスナーの追加です。「可用性グループリスナー」を右クリックして「リスナーの追加」を選択します。

「リスナーのDNS名」に予定のリスナー名を入力し、ポートは標準の1433を使用します。「ネットワークモード」の項目は「静的 IP」を選択します。IPアドレスを追加するために[追加]ボタンをクリックします。

1号機の属するサブネットを選択し、対応するIPアドレス(リスナーに割り振る予定のIPアドレス)を入力して[OK]をクリックします。

一覧にIPアドレスが追加されるので、再度[追加]をクリックして同じ手順で2号機の属するサブネット、IPアドレスを追加します。

[OK]をクリックするとリスナーが追加されます。

 

接続確認

1号機、2号機以外(DBの接続元サーバー等)から接続確認ができればベストですが、今回はその環境を用意していないため、各サーバーを1台ずつセカンダリの状態とし、それぞれセカンダリから接続確認を実施します。
まずは1号機がプライマリの状態で接続確認を行います。ここではsqlcmdを用いて接続確認を行います。

現在のセカンダリである、2号機からコマンドを使って確認します。データベースに接続され、テーブル名一覧が表示されました。

レコードの追加もできます。

次に手動フェールオーバー(※)を行い、2号機がプライマリ、1号機がセカンダリの状態で同じ手順で接続確認を行います。

※ 手動フェールオーバーの手順について、スクリーンショットを紛失した上、検証環境を削除してしまったので案内ができません。申し訳ありません・・・
確か、下図の可用性グループ名のアイコンを右クリックして「フェールオーバー」を選択して、ウィザードに沿って操作すればできたと思います。

以上で、接続確認が完了しました。

おわりに

長かった構築手順が終わり、AlwaysOn伝説が始まります。お疲れさまでした。

CloudFront でのアカウント跨ぎでアクセスログとオリジンアクセスアイデンティティを設定する

$
0
0

技術4課の多田です、こんにちは。

Amazon CloudFront(以下、CloudFront)から Amazon S3(以下、S3)にアカウント跨ぎでアクセスさせる必要があり、次の2つの設定検証を行いました。

  • CloudFront のアクセスログをアカウント跨ぎで S3 に格納
  • CloudFront のオリジンアクセスアイデンティティの設定をアカウント跨ぎで設定

今回は上記の検証結果をまとめていきます。

CloudFront のアクセスログをアカウント跨ぎで S3 に格納

CloudFront のアクセスログは S3 に格納することができます。

同一アカウントであれば S3 バケットの情報がリストされて、アクセスログの出力先を指定できます。

別アカウントの S3 バケットにアクセスログを格納したい場合は、個別にバケット情報を入力し、S3 バケットのアクセスコントロール設定を追加する必要があります。

1. S3 側のアクセスコントロール設定

まずは、S3 のアクセスコントロール設定を行います。

Access for other AWS accounts」にて「CloudFrontのアカウントのルートユーザーの ID」の情報を追加し、「FULL_CONTROL」を足します。

上記のルートユーザーの ID は、 CloudFront のアカウントで S3 バケットを作成し、アクセスコントロールから「Your AWS account (owner)
Canonical ID
」で確認可能です。

2つ目の ID は、後述する「2. CloudFront 側のアクセスログ設定」を行うと自動的に反映されます。

参考

アクセスログの設定および使用

2. CloudFront 側のアクセスログ設定

CloudFrontの「Distribution Settings」においてまず、「Logging」を有効化します。

次に、「Bucket for Logs」および「Log Prefix」を設定します。

  • Bucket for Logs」に別アカウントの 「S3 バケット名 +.s3.amazonaws.com」を設定
  • Log Prefix」に別アカウントの S3 バケットのアクセスログを格納するパスを設定

S3 バケットのアクセスコントロール設定が問題なければ、正常に設定完了します。

エラーが表示された場合、S3 バケットのアクセスコントロール設定を再度見直してみると良いと思います。

CloudFront のオリジンアクセスアイデンティティの設定をアカウント跨ぎで設定

CloudFront のオリジンアクセスアイデンティティは、 S3 バケットからのコンテンツ配信する際に設定します。

この設定もアカウントまたぎを行うには、アクセスログ設定同様に個別のバケット情報を入力する必要があります。

1. CloudFront 側のオリジンアクセスアイデンティティ設定

CloudFront 側の設定で、まずはオリジンアクセスアイデンティティを発行します。

発行した後に、設定編集画面から「Amazon S3 Canonical User Id」の情報をコピーしておきます( S3 バケットポリシー設定で使います)
次に、オリジンの設定を行なっていきます。

オリジンの設定では、以下の設定を行います。

  • Origin Domain Name」に別アカウントの 「S3 バケット名 +.s3.amazonaws.com」を設定
  • Restrict Backet Access」の設定を「Yes」を設定
  • Origin Access Identity」の設定を「Use an Existing Identity」を選択し、上記で設定したオリジンアクセスアイデンティティ名を設定
  • Grant Read Permission on Bucket」の設定を「No, I Will Update Permissions」を設定

2. S3側のバケットポリシー設定

S3のバケットポリシーを以下のように設定します。

CanonicalUser」の箇所に、「 1. CloudFront 側の設定」でコピーしておいた「Amazon S3 Canonical User Id」を反映します。

{
    "Version": "2012-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": " Grant a CloudFront Origin Identity access to support private content",
            "Effect": "Allow",
            "Principal": {
                "CanonicalUser":"CloudFront Origin Identity Canonical User ID"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::[S3バケット名]/*"
        }
    ]
}

参考

Amazon CloudFront オリジンアイデンティティへのアクセス許可の付与

3. Route53 に CloudFront のレコードを追加

最後に Route53 に CloudFront のレコード( xxxx.cloudfront.net )を設定します。

A レコードの Alias もしくは CNAME レコードで登録し、各エッジロケーションの情報が伝搬されればコンテンツにアクセス可能です。

まとめ

CloudFrontのアカウントまたぎでのS3バケット周りの設定方法を紹介しました。

最近のAWSの利用形態が、1つのアカウントでの運用から用途に応じてマルチアカウントかつ、マルチリージョンでの利用が増えてきた印象です。

AWSの権限制御の仕組みを理解することが意図した設定を実現するために必要だと改めて感じました。

今後もアカウントまたぎでの設定を行なった場合はブログにアウトプットしていきます。

ALB で Sorry ページを実装する方法と運用上の考慮点

$
0
0

2月も終わりますね、技術4課の多田です。

Web サイトを運用するケースでメンテナンスやサーバーの障害が発生した時に Sorry ページを返したいという要件って一般的にあると思います。

今回、構成上 ALB と EC2 がいる状況でEC2 で障害が発生した場合に Sorry ページを返すことを検証する機会がありましたので記事にまとめていきます。

ALB の固定ページとして Sorry ページを表示させる

ALB のアップデートでロードバランサーからHTTP エラーレスポンスコードとカスタムエラーメッセージを返すことができるようになりました。

Elastic Load Balancing で Application Load Balancer のリダイレクトおよび固定レスポンスのサポートを発表

具体的には、リスナーのルールで制御を行います。ルールにHTTP エラーレスポンスコードとカスタムエラーページを設定します。

今回は、HTTPエラーレスポンスコードとして「503」を返し、カスタムエラーページとして「Sorry Page Test」と返す設定を行いました。

設定後に、ブラウザからアクセスしてみます。想定通りのページが表示されました。

運用上の考慮点

ALB のルールでは、優先度に応じて挙動が変わります。

そのため、運用する際は Sorry ページを返すルールと、通常のコンテンツを返すルールの優先順位をコントロールする必要があります。

例えば、EC2 に障害が発生し、ターゲットグループのヘルスチェックが通らない状況になった場合にSorry ページを返したい、といったケースを考えます。

ルールとしては以下の画像のようにセットします。

障害が発生した時は、Sorry ページを表示するルールを、通常のコンテンツを返すルールより優先順位を上にします。

実現方法

GUI で行う場合の手順としては、次のように行います。

まず、上部のボタンの中で「Recorder Rules」を押します。

次に、優先度を変更したいルールの横にチェックボックスがあるためチェックを入れて、優先度を下げるボタンを押します。

最後に、「Save」ボタンを押して終了です。操作としては簡単ですね。

また、AWS CLIでは、set-rule-priorities というコマンドで優先度を変更可能です。

set-rule-priorities

EC2 に障害が発生後、Sorry ページを表示するルールを優先するように変更する際のコマンド例としては以下のコマンド打ちます。

aws elbv2 set-rule-priorities --rule-priorities RuleArn=arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxx:listener-rule/app/alb-dev/f9d65ec6f12ec5fc/33d54c2104b7c8d6/1b6bbb9c8560b2d9,Priority=1

ちなみに、上記の引数であるRuleArnは GUI からですと以下のように調べることが可能です。

今回紹介したのは、HTTP のルールだけでしたが、HTTPS のルールもあればそのルールも変更する必要があります。

まとめ

Sorry ページをALB 単体で表示できるアップデートは便利だと思います。

運用にあたっては優先度を変更するオペレーションがあると思うので、手動で変更するフローかAPI 経由で自動化するフローかを検討すると思いますが本番化する前のテストして想定の挙動かは確認するのが良いでしょう。

参考

固定レスポンスアクション

AWSドキュメントと + α で確認したいコンテンツ(公式のもののみ)

$
0
0

AWSの各サービスを利用していく中で、疑問がわいたとき皆さんはどうされてるでしょうか。ドキュメントを読んでみる・検証してみる、読んでもわからない・解決しないなら社内の詳しい人に聞く、というような流れじゃないでしょうか。場合によっては、AWSサポートへ問い合わせるかと思います。

たいていのことはドキュメントに書いてあるのですぐに解決しますよね。

実はドキュメントの他にも確認したい、AWSが公開しているコンテンツがあります。

よくある質問

各サービスの紹介ページ?からよくある質問を確認できます。

例えば最近話題のAmazon Connect

ドキュメントほどの細かい仕様は載っていませんのでエンジニアの方は確認することは少ないとは思います。

しかし。ドキュメントには載っていない料金の計算について載っています。

私は料金の計算方法がわからないときは、そのサービスの『よくある質問』を確認するようにしています。

月額料金を計算したいときに役に立つでしょう。

AWSサポートナレッジセンター

各サービスの『よくある質問』はどちらかというとこれからAWSを始める人向けのように見受けられます。

だとするとAWSサポートナレッジセンターはすでに利用している人向けのよくある質問でしょう。

こちらも一問一答形式ですが、技術的な質問ばかりです(たぶん)。そして英語のものもあったりします。

自分が疑問に思っていること・困っていること・実現したいことはもうすでに書いてあるかも…

まとめ

いかがでしたでしょうか。誰かに聞く前にこういったコンテンツを確認するのも良いかもしれません。

今回は公式のものを紹介しましたが、もちろんサーバーワークスのブログも確認してみてください!

【CloudTrail】リソースの「名前変更」(リソース名の変更)の履歴はイベント名「CreateTags」で

$
0
0

こんにちは。技術4課の伊藤Kです。

さて今回は小ネタです。
先日、案件でVPC環境を構築後、いつの間にかVPC名が構築当初から変更されていることに気づきました。

先輩「おい、おまえ勝手に変更してんじゃねーよ!」
伊藤K「ご、誤解ですよ~」

誤解を解くために、変更履歴を追って犯人が自分でないことを証明してやる!

「CloudTrail」でリソースの変更履歴を追う

こんな時はAWSリソースの設定変更履歴を追う「CloudTrail」を使います。
CloudTrailについての説明は、サーバーワークスでも他社さんでも多くの方が記事にしているので割愛させていただきます。
弊社エンジニアの記事はこちら
CloudTrailの基本

ログが多すぎて全部は追ってられないので「リソース名 = (VPC-ID)」でフィルターをかけて、と。

あれ、「名前変更」らしきイベントがないぞ・・・

先輩「やっぱりおまえだな、次からは気をつけろよ」
伊藤K「・・・」(な、なんで出てこないんだ・・・)

悔しいのでかたっぱしから追っていくと、「CreateTags」を発見。

誰か新しいタグつけたのかな。中を見ると、

これだ!
VPC名の変更は「CreateTags」イベントなのか・・・

考えてみれば、ここの表示の「Name」って、「Name」タグの値を表示させただけなので、
片方を変えるともう一方も連動して変わりますね。

イベント履歴のアカウントIDから、VPC名を変更したのは他のユーザーだったことが判明。
(そしてそのユーザーはプロパティの「Name」タグの値を変えただけの意識だったらしい)
かくして私の濡れ衣は解消、ブログのネタが一つ増えたのであった。めでたし、めでたし。

おわりに

文中の先輩とのやり取りはフィクションを含んでいます。実際にどのようなやり取りとなったかはご想像にお任せいたします。

Viewing all 1210 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>