Amazon Auroraの概要

本記事の目的

業務でAuroraについて調査したので、そのメモ。

Amazon Aurora 概要

Amazon Aurora(以下、Aurora)はMySQLおよびPosgteSQLと互換性のある、クラウド向けに構築されたRDBです。 商用DBと同等のセキュリティ、可用性、信頼性を10分の1のコストで実現します。

特徴

Auroraのアーキテクチャ

Aurora は、DBインスタンスと、インスタンスのデータを管理するクラスターボリュームで構成されます。

  • DBインスタンス

    • プライマリDBインスタンス

      • データの読み書きを担当、クラスターボリュームに対する全てのデータ変更を実行する
    • Aurora レプリカ

      • データの読み取りのみを担当
      • 各AZにAuroraレプリカを配置し、高可用性を維持
      • プライマリDBインスタンスが使用できなくなった場合、Auroraレプリカへ自動フェイルオーバー
  • クラスターボリューム

    • 複数のAZにまたがる仮想DBストレージボリューム
    • 各AZにはDBクラスターデータのコピーが保存される

アーキテクチャのイメージを以下に示します。

スクリーンショット 2019-08-13 23.18.14.png

Amazon Aurora DB クラスターより

上記構成から、

  • データを各AZに保存することによる高可用性の確保
  • ストレージとDB管理システムを分離することで高速化

を実現しています。

料金

Auroraの使用料金は、プライマリDBインスタンスとAuroraレプリカを合算したものです。 時間単位で計算されます。

同じインスタンスタイプのRDS for PostgreSQLと比較してみます。

アジアパシフィック(東京)リージョン、オンデマンド、db.t3.mediumの場合:

RDS for PosgreSQL Aurora
シングルAZ配置 0.112USD 0.125USD
マルチAZ配置 0.224USD 0.125USD

マルチAZでRDSを運用する場合は、Auroraを使用したほうがコストが低くなります。

参考URL

https://dev.classmethod.jp/cloud/aws/awssummit-2016-amazon-aurora-deep-dive/

https://othlotech.hatenablog.com/entry/2018/10/17/180000

TerraformでMFAを利用しながらAWSリソースへアクセスする方法

今回は

aws-vaultを使ってみます

前提

  • 下記設定が終了していること

    • ~/.aws/config
    • ~/.aws/credentials
  • source_profileの指定をしないこと

使い方(MacOSの場合)

Brew caskでインストール

$ brew cask install aws-vault

プロファイルを作成、アクセスキーとシークレットキーを入力

$ aws-vault add PROFILE_NAME

aws-vault ls で登録したプロフィールが確認できる

$ aws-vault ls 

aws-vault から一時的なアクセスキーを渡してプロセスを実行

$ aws-vault exec home -- aws s3 ls

Ansible Vaultで環境変数を使わずパスワードを暗号化する方法

Ansible Vaultの使い方として、コードをGithubに共有する場合があると思います。 一例として、第三者から機密情報を守るために、ファイルや文字列を暗号化する場合がありますね。

Ansibleを使う際に、暗号化する方法も色々ありますが、 今回はAnsible Vaultという機能を使って、環境変数ではなくファイルや文字列自体を暗号化する方法についてまとめました。

Ansible-vaultで暗号化できるもの

  1. ファイル
  2. 変数

暗号化したい値をymlファイルでまとめて管理する方法

1. パスワード等機密情報を記載したファイルを用意する

今回は一例として、appuserというLinuxユーザーのパスワードを暗号化していきましょう。 下記のように、my_vault.ymlというファイルにappuser_passwordとしてパスワードpasswordを定義しています。

$ vi my_vault.yml
appuser_password: password

2. my_vault.ymlファイルを暗号化する

下記コマンドで、ファイルの中身を暗号化できます。

$ ansible-vault encrypt [暗号化対象ファイル]

今回はmy_vault.ymlの中身を暗号化します。 コマンド実行時に、復号の際に必要なパスワードを指定する必要があります。 このパスワードを覚えておきましょう。

$ ansible-vault encrypt my_vault.yml
New Vault password:
Confirm New Vault password:
Encryption successful

3. 使用したいplaybook内で値を呼び出す

plyabook内で、下記の様にappuserを追加するタスクを書きます。

~
- name: add appuser
  become: true
  user:
    name: appuser
    comment: Application User
    uid: 505
    groups: appuser
    password: "{{ appuser_password | password_hash('sha512') }}"
# ansibleのuserモジュール内のpasswordで変数を使用する場合は、ハッシュ化する必要がある
~

4. playbook実行時に、オプションを指定する

下記オプションを指定して、playbook実行時にパスワードを入力させるようにします。

--ask-vault-pass --extra-vars="@my_vault.yml"

$ ansible-playbook -i inventory -l localhost test.yml --ask-vault-pass --extra-vars="@my_vault.yml"

これで問題なくタスクが実行できるはずです。

ansible-vaultの各コマンド

  • ansible-vault create

    • 暗号化されたファイルを作成
  • ansible-vault encrypt

    • 既存のファイルを暗号化
  • ansible-vault decrypt

    • 暗号化されたファイルを復号化
  • ansible-vault edit

    • 暗号化されたファイルを編集
  • ansible-vault rekey

    • パスワードを変更
  • ansible-vault view

    • 暗号化されたファイルを復号して PAGER で表示

Killコマンドについて

プロセスを強制終了させる際に、 kill <PID> を使用したことはあると思います。 また、以前systemdについてまとめましたが、Unitファイル内でも kill コマンドの扱いを定義していました。

今回はこの kill コマンドについて、詳しく調べてみました。

killコマンドについて

説明

kill コマンドは、指定したシグナルを指定したプロセスまたはプロセスグループへ送る。 シグナルが指定されない場合、TERMシグナルを送る。 TERMシグナルは、このシグナルをキャッチしないプロセスを終了させる。 このシグナルをキャッチしてしまうプロセスを終了させるためには、 KILL (9) シグナルを使う必要がある。 最近のシェルのほとんどには、組み込みのkill機能があり、 ここで説明しているコマンドと同じような使い方をする。 -a' オプションと-p' オプション、 そしてコマンド名で PID を指定する方法はローカルな拡張である。

出典

つまり、kill コマンドはプロセスの強制終了のためではなく、プロセスへ何らかのシグナルを送るために用意されています。 そして、シグナルに TERM が使用された場合に、プロセスを強制終了させるます。

それでは、シグナルとはどういったもので、どのような種類があるのでしょうか。

シグナル

シグナルとは

「シグナル」はプロセスとプロセスの間で通信を行う際に使用される“信号”のことで、シグナルを受け取ったプロセスは“何らかの動作”を行います。その動作は、例えば「再起動」であったり、「終了」であったりします。

出典

コンソールでkill <PID>Ctrl+cCtrl+zと入力するとプロセスが終了しますが、これらもプロセスへ終了シグナルを送っていることになります。

シグナルの種類

シグナルの種類を一部、下記の通り紹介します。

先述の例で、Ctrl+c を上げましたが、これは下記のSIGINT を該当のプロセスへ送信していることになります。

シグナルの種類 シグナル番号 デフォルト動作 備考
SIGINT 2 終了 キーボードからの割り込み (Interrupt)
SIGTSTP 20 停止 端末より入力された一時停止 (stop)
SIGKILL 9 終了 Kill シグナル
SIGTERM 15 終了 終了 (termination) シグナル
SIGHUP 1 終了 制御端末(controlling terminal)のハングアップ検出、または制御しているプロセスの死
SIGQUIT 3 終了 キーボードによる中止 (Quit)、プロセスの終了とコアダンプ出力

出典

シグナル動作の種類

シグナルが送信されると、プロセスの通常処理に割り込んでシグナルが動作します。 シグナルの種類によりデフォルト動作は定義されており、以下の動作をそれぞれ実行します。

  1. プロセスを終了する
  2. コアを出力し、プロセスを終了する
  3. シグナルを無視する
  4. 処理を一時停止する
  5. 処理を再開する

出典

シグナル挙動の上書き

デフォルト動作は上記のように定義されていますが、シグナルを受け取った際に別の処理を実行させることもできます。 この別の処理は、プログラム側で実装します。

nginxの公式サイトにも、それぞれのシグナルを受け取った際にメインプロセスがどのような振る舞いをするかが記されています。

kill コマンドの使い方

書式

$ kill [-s signal | -p] [-a] [ --] pid ...
$ kill -l [signal]  

killのあとに、シグナル名もしくはシグナル番号を指定してPIDに対してコマンドを実行します。

まとめ

  • kill コマンドは、プロセスに対してシグナルを送信する。
  • シグナルには種類があり、それぞれ動作が異なる。
  • 各シグナルにはデフォルト動作があるか、その動作をプログラム側で書き換えることも可能。

補足

Unitファイル内で KillMode オプションを指定できます。 各値の動作は以下のようになっています。

systemdは起動したサービスに関連する全てのプロセスをCgroupの個別のグループに入れて管理している

ExecStopコマンドで停止した時、グループ内にプロセスが残っている場合、KillModeの設定に応じて残プロセス処理を行う

  • KillMode=none 残プロセスは放置
  • KillMode=process メインプロセスが残っている場合、SIGTERM/SIGKILLで停止する。その他の残プロセスは放置
  • KillMode=control-group グループ内の全ての残プロセスを SIGTERM/SIGKILL で停止する
  • KillMode=mixed メインプロセスを SIGTERM/SIGKILL で停止し、続けてグループ内の全ての残プロセスを SIGKILL で停止する。

出典

AWS ソリューションアーキテクト・アソシエイト合格体験記

約1ヶ月の勉強期間で、AWS ソリューションアーキテクト・アソシエイトに合格しました。 振り返りの意味も込めて、やったことをまとめてみます。 これから同じ資格を受験する方への、参考になれば嬉しいです。

※こちらは2020年2月1日受験時点での内容となります。ご了承ください。

私は誰

  • 自社開発企業でインフラエンジニアとして勤務
  • AWSを業務で触り始めて約半年
  • 業務で経験のあるAWSサービスは、基本的なものだけ(EC2、RDS、ELB、S3など)

学習の大まかな流れ

  1. 書籍で一通り試験範囲の内容を掴む
  2. 模試を受ける
  3. 苦手な分野を把握する
  4. 苦手な分野のBlackbeltを繰り返し読む

上記の流れをひたすら繰り返しました。

やったこと

  • Blackbeltの読み込み
  • 模擬試験
  • テキストを使った勉強

Blackbeltの読み込み

各サービスの説明資料であるBlackbeltを読みました。 AWS公式ページに、Blackbeltをはじめ各サービスの説明資料がまとめられています。

読むだけでなく、理解を深めるためにブログ記事に内容をまとめたりもしました。

一度で理解しようとせず、何度も何度もBlackbeltを読み返すことが大事だと思います。

模擬試験

Udemyの、これだけでOK! AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座(初心者向け22時間完全コース) | Udemyを購入しました。 ※アフィリンクではありません。 この講座には模擬試験が3回分ついているので、模擬試験を目的に購入しました。

模擬試験を何度も繰り返し、苦手なサービスに絞って勉強しました。 (講座の内容はほぼ見ていません…)

講座部分は、ハンズオン形式で学習できるので余裕があれば取り組んだほうがよいです。 今回は学習時間短縮のため、模擬試験だけ受けました。

テキストを使った勉強

下記の本を使用しました。

図を使った解説が豊富で、各サービスの仕組みを理解するのに役立ちました。 また、試験対策への重要度が記載されているため、重点的に勉強すべきところがわかりやすかったです。 巻末に模擬試験もついていますので、おすすめです!

現在はkindle unlimitedの対象になっているようなので、試し読みしてみるのもいいでしょう。 個人的には紙形式が好みなので、購入して持ち歩いていました。

重点的に理解すべき部分

自分が苦手だった部分でもありますが、下記が模擬試験でも本番でもよく問われました。

  • EBSボリュームタイプの違いと、各ユースケース
  • S3(Glacier含む)の各ストレージクラスのユースケース、取り出し時間の違い
  • 各データベース・データストアサービス(RDS、Aurora、Dynamo、Redshift、ElastiCache)のユースケース
  • Auto Scalingのスケーリングポリシー

また、使用経験がないサービスはもちろんですが、 使用経験があるサービスのなかで、なじみのないオプションについても集中的に学習しました。

試験当日のTips

集合時間には余裕を持つ

当たり前ですが、時間には余裕を持ちましょう。

自分はピアソンVUEで受験しました。 当日会場について、いきなりテストを受けられるわけではありませんでした。 受験の前に受験要項の確認と注意事項の説明を受け、署名する必要があります。また、荷物をロッカーに預けたりといった作業も必要でした。

なので、試験時間には余裕を持って到着する必要があります。 自分はぎりぎりに到着したので、少し焦りました...

持ち物を確認する

身分を証明するものが2つ必要です。 写真付きの公的身分証明書と、クレジットカードやキャッシュカードといった自分の名前が印字されたものです。

自分は、念の為パスポートとクレジットカードを持っていきました。

合格判定を見逃さない

試験終了後、画面に合格かどうかが表示されます。 見逃さないようにしましょう。

振り返り機能を活用する

PC画面上で選択式の問題に答えていくのですが、 「後で見返す」問題にフラグをつけることができます。

自信のない問題や、時間がかかりそうな問題にフラグをつけておけば、 あとで一気に見返すことができます。

この機能を使って、試験時間を節約しましょう。

おわりに

準備期間が長くなくても、AWS Solution Architect Associateに合格できました。 合格することが目的ではありましたが、使用経験のないサービスについても学習することができ、とても良い経験になりました。

この記事がなにかの助けになれば幸いです。

迷惑メールと認定されないためにできること

迷惑メールフィルタが迷惑メールを判定するための根拠を学ぶことで、ユーザーに向けた情報がブロックされず適切に届くようになる方法を紹介します。

迷惑メールフィルタの仕組み:Gmailの場合

Gmailにおける迷惑メールを判断する根拠は、Googleからある程度公開されているようです。

メールアドレスのなりすまし フィッシング詐欺 未確認の送信者からのメール 管理者が設定したポリシー 特定の送信者からのメールのブロック 内容が空のメール 手動で迷惑メールに振り分けたメール

出典:迷惑メールのマーク付けとマークの解除 - パソコン - Gmail ヘルプ https://support.google.com/mail/answer/1366858

上記から、いくつか理由をピックアップして解説します。

メールアドレスのなりすまし

メールアドレスが既存の送信者のアドレスに酷似している場合です。 メールアドレスのアルファベット「O」が数字の「0」になっている場合などが該当します。

未確認の送信者からのメール

この項目は非常に重要です。 スパムメールの特徴の1つに、送信元のヘッダー情報を書き換えて送る、があります。

メールをサーバー間で送受信する際は、SMTPというプロトコルを使います。 SMTPのセキュリティ上の弱点として、任意のドメインの差出人になりすますことが可能です。

では、どのようにしてなりすますことが可能になるのか、仕組みをみていきます。

電子メールの構造

電子メールは、下記3つの主要な部分から構成されています。

1) Envelope(封筒) 2) Message Header(メッセージヘッダ) 3) Message Body(メッセージ本体)

出典:電子メールなりすましの仕組みと、なりすましがなぜ簡単なのかの理由 | Proofpoint JP https://www.proofpoint.com/jp/corporate-blog/post/how-does-email-spoofing-work-and-why-it-so-easy

EnvelopeとMessage Headerに、送信元アドレスが明記されてます。 それぞれの送信元アドレスを、EnvelopeFromと、HeaderFromと呼びます。

HeaderFromは、送信者が自由に書き換える事ができます。 メーラーに表示されるのはHeaderFromなので、正規のドメインから届いたメールのように偽装することが可能です。

Envelopeは受信Boxに届いた段階で破棄されるので、受信ユーザーがメーラー上でEnvelopの情報を確認することは難しいようです(調査中)。

上記の構造から、送信元アドレスが適切なものか保証する仕組みが必要になります。

SPF

Sender Policy Frameworkの略です。 DNSのTXTレコードの一種であるSPFレコードを使って、送信元を認証します。

EnvelopeFromに記載されている情報を、受信メールサーバーが送信元ドメインDNSに問い合わせ、送信元を検証します。

動作イメージ図: sender-authentication-technology-outline.png

(出典:送信ドメインを認証するためのSPFレコードに詳しくなろう | SendGridブログ

自分で設定することもできますが、メール送信用SaaSを使えば、自動で設定してくれることも多いです。

まとめ

  • メールの送信元を偽装するのはかんたん
  • 送信元アドレスを検証する仕組みの1つにSPFがある
  • DNSSPFが登録されていれば、正規の送信元だと判断される事が多い

EventBridgeの内容をStep Functionsで整形してSNSトピックに流す

EventBridgeの内容はそのままだと見づらいことも多く、見栄えを良くしたい場合がある。 そういった場合に、Step Functionsのパスに飛ばして内容を整形することができるよ、というお話。

別途IAMロール、CloudWatch Alarmがすでに作成してある前提。 EventBridgeの内容をStep Functionsに送り、Step Functionsのステートマシン内で整形しSNSトピックへ送信している。

最終的に、下記の様なメールを飛ばせる

# CloudWatch AlarmでCPU使用率が0%になったことを受け取るEventBridge
resource "aws_cloudwatch_event_rule" "ecs_cpu_utilization_zero_rule" {
  name          = "ecs-task-connectivity-rule"
  description   = "Capture ECS Tasks Connectivity Alarm Rule"
  event_pattern = <<EOF
{
  "source": ["aws.cloudwatch"],
  "detail-type": ["CloudWatch Alarm State Change"],
  "resources": [
    "${aws_cloudwatch_metric_alarm.ecs_cpu_utilization_zero.arn}"
  ],
  "detail": {"state": {"value": ["ALARM"]}}
}
EOF
}

# EventBridgeとStep Functionsを連携するターゲット
resource "aws_cloudwatch_event_target" "ecs_task_connectivity_event" {
  rule     = aws_cloudwatch_event_rule.ecs_cpu_utilization_zero_rule.name
  arn      = aws_sfn_state_machine.ecs_task_connectivity_state_machine.arn
  role_arn = aws_iam_role.sfn_execution_role.arn
}

# EventBridgeの通知内容を整形してSNSを送るStep Functions
resource "aws_sfn_state_machine" "ecs_task_connectivity_state_machine" {
  name     = "ecs-connectivity"
  role_arn = aws_iam_role.publish_sns_role.arn

  definition = <<EOF
{
  "StartAt": "InputToOutput",
  "States": {
    "InputToOutput": {
      "Type": "Pass",
      "Parameters": {
        "serviceName.$" :"$.detail.configuration.metrics[0].metricStat.metric.dimensions.ServiceName",
        "failedMessage": "ECSの死活監視が失敗しました。"
      },
      "ResultPath": "$.input",
      "Next": "PublishSns"
    },
    "PublishSns": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "TopicArn": "${var.infra_alert_sns_topic}",
        "Message.$": "States.Format('{} \n \n 死活監視が失敗したリソース: {}',$.input.failedMessage , $.input.serviceName)",
        "Subject": "ECSの死活監視が失敗しました"
      },
      "End": true
    }
  }
}
EOF
}

参考

自分が使っためちゃくちゃわかりやすい参考書。