kakakakakku blog

Weekly Tech Blog: Keep on Learning!

CloudWatch Alarm を SNS 経由で PagerDuty に通知する

Amazon CloudWatch Alarm で検出したアラームを PagerDuty に通知する仕組みを Terraform で構築する機会があって,検証用に実装した Terraform コードをまとめておく.設定自体は難しくなくて Amazon CloudWatch AlarmAmazon SNS TopicPagerDuty のように連携する❗️

設定に関しては以下のドキュメントに詳しく載っている📝 現在だと大きく Event Orchestration を使う方法と Amazon CloudWatch Integration を使う方法がある.今回はシンプルに Amazon CloudWatch Integration を使う前提とする.

support.pagerduty.com

1. PagerDuty: Amazon CloudWatch Integration

まずは PagerDuty で Amazon CloudWatch Integration を追加する.特に設定をする必要はなく,表示される https://events.pagerduty.com/integration/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/enqueue という Integration URL を控えておけば OK👌

デフォルトだと PagerDuty の Amazon CloudWatch Integration は Alarm Name でインシデントの重複排除をしてくれるけど,判断基準を変更する場合は設定値 Correlate events byAlarm Name から変更しておく.

2. Amazon SNS Topic

次に Amazon SNS Topic(標準)を構築する.Terraform だと aws_sns_topic を使う.

resource "aws_sns_topic" "incidents" {
  name = "incidents"
}

Amazon SNS Topic と PagerDuty を連携するには HTTPS でサブスクリプションを追加すれば OK👌 Terraform だと aws_sns_topic_subscription を使う.今回は endpoint に Amazon CloudWatch Integration の Integration URL を直接指定してるけど Terraform 変数にするなどご自由に❗️

resource "aws_sns_topic_subscription" "pagerduty" {
  topic_arn = aws_sns_topic.incidents.arn
  protocol  = "https"
  endpoint  = "https://events.pagerduty.com/integration/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/enqueue"
}

\( 'ω')/ 簡単だ〜

tfsec: Terraform のセキュリティスキャンを活用しよう

Terraform コードを書きながらセキュリティ観点の警告を把握できるため tfsec を導入すると便利❗️

tfsec では AWS, Microsoft Azure, Google Cloud などさまざまなプロバイダをサポートしている👏 最近 AWS プロバイダを前提に tfsec を導入する機会があって,個人的に検証した作業ログをまとめる📝

aquasecurity.github.io

また tfsec は前に紹介した TFLint と一緒に導入しておくとさらに便利〜 \( 'ω')/

kakakakakku.hatenablog.com

tfsec をセットアップする

tfsec のセットアップは macOS だと Homebrew を使えば簡単〜

今回は tfsec v1.28.1 を前提にする.

$ brew install tfsec

$ tfsec --version
v1.28.1

tfsec を実行する

基本的には tfsec コマンドを実行すれば OK👌

該当するとだーっと表示される.1件も該当しないと統計情報と共に No problems detected! と表示される.

$ tfsec

No problems detected!

tfsec にどんなルールがあるのか

tfsec には多くの警告があってドキュメントにまとまっている.AWS 関連の警告は以下で確認できる.サービス的に網羅はされていないけど,よく使うサービスのセキュリティ観点で気を付けるべき設定は警告されるようになっている気がする💡

aquasecurity.github.io

最近改善を担当することになった Terraform プロジェクトに tfsec を実行してみたところ Warning が 400件 も出てきた🔥とは言え,半分以上の警告は Severity(重大度)が LOW になっているため,今後の改善案としてコツコツ修正していくのが良さそう.

以下に代表的な警告を紹介する📝

Severity(重大度): CRITICAL

🔗 aws-ec2-no-public-ingress-sgr

セキュリティグループ(インバウンド)で 0.0.0.0/0 は避けるべし!という警告🛑

Application Load Balancer (ALB) で API を公開する場合など,意図的に 0.0.0.0/0 を設定する場合もあるためそれは無視しつつ,意図せず公開されている場合に警告が出るので助かる👌

aquasecurity.github.io

🔗 aws-ec2-no-public-egress-sgr

セキュリティグループ(アウトバウンド)で 0.0.0.0/0 は避けるべし!という警告🛑

アウトバウンドはデフォルトで 0.0.0.0/0 になっていることもあってよく出る警告だと思う.個人的には CRITICAL でなくても良さそうに思うけど,何も考えず 0.0.0.0/0 のままになっていることを再考するきっかけになると思う.VPC エンドポイントなども活用しつつ,できる限り制限した CIDR レンジを設定するべし.

aquasecurity.github.io

Severity(重大度): HIGH

🔗 aws-iam-no-policy-wildcards

IAM ポリシーを記述するときにワイルドカード * は避けるべし!という警告🛑

最小権限の原則に従っていないと警告が出てしまう.ワイルドカードのまま本番環境に導入してしまうと後から直すコストが高くなってしまうけど,IAM Access Analyzer などを活用しながらワイルドカードを減らせると良さそう👌

aquasecurity.github.io

🔗 aws-ecr-enforce-immutable-repository

Amazon ECR リポジトリのイメージタグを上書きできないようにイミュータブル設定を有効化せよ!という警告🛑

latest タグすら使わずにイメージタグの運用をしっかり回せている前提にはなるけど有効化しておくと良さそう👌

aquasecurity.github.io

🔗 aws-ecr-enable-image-scans

Amazon ECR リポジトリのイメージスキャンを有効化せよ!という警告🛑

aquasecurity.github.io

基本的に有効化しておくと良さそう👌しかし現在は Basic scanning 以外に Amazon Inspector と統合された Enhanced scanning もあるので,そっちを使う場合は警告は無視しておけば良いかと.

docs.aws.amazon.com

🔗 aws-elb-drop-invalid-headers

Application Load Balancer (ALB) で 無効なヘッダーフィールドを削除 を有効化せよ!という警告🛑

動作確認は慎重に行いつつ有効化すると良さそう👌

aquasecurity.github.io

無効なヘッダーフィールドを削除 に関しては前にブログにまとめてある📝

kakakakakku.hatenablog.com

Severity(重大度): LOW

🔗 aws-ec2-add-description-to-security-group-rule

セキュリティグループの各エントリーに説明を設定せよ!という警告🛑

Severity(重大度)は LOW だし必須ではないと思うけど,運用を引き継いだ AWS 環境を調査していて「これは何だ〜?」というエントリーに出会うこともあるし,ちゃんと説明を設定しておくのはセキュリティ目的に限らず重要だと思う.

aquasecurity.github.io

不要な警告を減らす

tfsec の設定ファイル .tfsec/config.yml を活用すると tfsec で警告する Severity(重大度)の閾値や無視する警告を設定できる❗️以下の例だと閾値を HIGH 以上にして,いくつかの警告を無視することで大幅に減らせる👏

minimum_severity: HIGH

exclude:
  - aws-ec2-no-public-egress-sgr
  - aws-ec2-no-public-ingress-sgr
  - aws-ecr-enable-image-scans
  - aws-ecr-enforce-immutable-repository
  - aws-elb-alb-not-public
  - aws-iam-no-policy-wildcards

tfsec コマンドを実行すると自動的に .tfsec/config.yml を参照するけど,ファイル名を変えて複数種類の設定ファイルを活用するような場合は --config-file オプションで指定することもできる.

$ tfsec --config-file .tfsec/my-config.yml

また tfsec コマンドを実行したときに表示される統計情報の ignored で該当していた件数も確認できるため(以下の件数は例),運用中の Terraform プロジェクトに途中から tfsec を導入する場合は,一度無視してから段階的に ignored を減らしていく戦略もアリだと思う💡

$ tfsec

  timings
  ──────────────────────────────────────────
(中略)

  counts
  ──────────────────────────────────────────
(中略)

  results
  ──────────────────────────────────────────
  passed               150
  ignored              200
  critical             0
  high                 0
  medium               0
  low                  0


No problems detected!

個別に警告を無視する

Terraform コードに #tfsec:ignore:... と書けば個別に警告を無視できる.以下は例として aws-elb-alb-not-public の警告を無視するために #tfsec:ignore:aws-elb-alb-not-public と書いてある.書く場所も重要で今回だと internalの直前に書いている💨

resource "aws_lb" "alb" {
  name                       = "alb"
  load_balancer_type         = "application"
  #tfsec:ignore:aws-elb-alb-not-public
  internal                   = false
(中略)

aquasecurity.github.io

また #tfsec:ignore:aws-elb-alb-not-public:exp:2023-12-31 のように書くと有効期限を設定できるのは最高❗️いつまでに直すぞ〜という意思表示に使えるし,有効期限を過ぎたら CI/CD で突然エラーになるのもイイ仕組みだと思う👏

tfsec を GitHub Actions で動かす

tfsec を GitHub Actions で動かす場合は「tfsec-action」を使えば簡単に導入できる❗️

github.com

name: tfsec

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

jobs:
  tfsec:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run tfsec
        uses: aquasecurity/tfsec-action@v1.0.3

さらにプルリクエストに直接コメントをするように設定したかったら「tfsec-pr-commenter-action」を使えば実現できる👌

github.com

VS Code 拡張機能「tfsec」

もし tfsec を使うなら VS Code 拡張機能「tfsec」をインストールしておくと開発中にはかどる💡該当した警告をレベル別 (Critical, High, Medium, Low) に一覧できたり,コードジャンプできたり,右クリックメニューを使って ignore コメントを自動挿入できたりする❗️

\( 'ω')/ 実際に使ってるけど VS Code 拡張機能は便利〜

marketplace.visualstudio.com

ALB の設定項目 routing.http.drop_invalid_header_fields.enabled を有効化する

Application Load Balancer (ALB) の設定項目 routing.http.drop_invalid_header_fields.enabled を有効化すると不正な HTTP ヘッダーをターゲットに転送せず ALB で自動的に削除できるようになる💡 HTTP ヘッダー名は正規表現 [-A-Za-z0-9]+ で表現する必要があって,例えば _ を HTTP ヘッダー名に使うと不正と見なされて削除対象になる.試してみる❗️

ちなみに設定項目 routing.http.drop_invalid_header_fields.enabled のコンソールでの日本語表記は 無効なヘッダーフィールドを削除 で,英語表記だと Drop invalid header fields となる📝 デフォルトでは「OFF」になっている.

docs.aws.amazon.com

検証環境

routing.http.drop_invalid_header_fields.enabled の動作確認をするため,ALB と Amazon ECS (AWS Fargate) で検証環境を構築した.Amazon ECS Task で動かすコンテナとしては mendhak/http-https-echo を使う.このコンテナは HTTP リクエスト内容をそのまま JSON で返してくれる仕組みになっていて,デバッグ用途に相性抜群👏 今回は HTTP ヘッダーの動作確認をするため mendhak/http-https-echo を使おうと思った❗️

\( 'ω')/ mendhak/http-https-echo 便利〜

github.com

routing.http.drop_invalid_header_fields.enabled: OFF

まずはデフォルト設定として routing.http.drop_invalid_header_fields.enabled OFF の動作確認をする.curl で ALB に GET リクエストを投げるときに HTTP ヘッダーとして my-headermy_header を指定して,jq を使って Amazon ECS Task(ターゲット)に転送された HTTP ヘッダーを確認する.

期待通り my-headermy_header どちらも転送されている💡

$ curl -s \
  -H my-header:my-header \
  -H my_header:my_header \
  http://xxx.ap-northeast-1.elb.amazonaws.com/ | jq '.headers | with_entries(select(.key | startswith("my")))'
{
  "my-header": "my-header",
  "my_header": "my_header"
}

routing.http.drop_invalid_header_fields.enabled: ON

次は routing.http.drop_invalid_header_fields.enabled ON の動作確認をする.ALB の設定変更をして,同じく GET リクエストを投げて Amazon ECS Task(ターゲット)に転送された HTTP ヘッダーを確認する.

期待通り my_header は削除されて my-header のみ転送されている💡

$ curl -s \
  -H my-header:my-header \
  -H my_header:my_header \
  http://xxx.ap-northeast-1.elb.amazonaws.com/ | jq '.headers | with_entries(select(.key | startswith("my")))'
{
  "my-header": "my-header"
}

Terraform x tfsec

ちなみに ALB をデフォルト設定のまま実装した Terraform コードを tfsec でチェックすると Load balancers should drop invalid headers として検出される👀 その場合は aws_alb リソースに drop_invalid_header_fields = true を追加すれば OK👌もちろん動作確認は慎重に〜

aquasecurity.github.io

Result #1 HIGH Application load balancer is not set to drop invalid headers.

(中略)

          ID aws-elb-drop-invalid-headers
      Impact Invalid headers being passed through to the target of the load balance may exploit vulnerabilities
  Resolution Set drop_invalid_header_fields to true

  More Information
  - https://aquasecurity.github.io/tfsec/v1.28.1/checks/aws/elb/drop-invalid-headers/
  - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb#drop_invalid_header_fields

なぜプロダクトマーケティングが重要なのか /「LOVED」を読んだ

書籍「LOVED」を読んだ📕どうしたらプロダクトを通して市場とユーザーのニーズに応えられるのか.どうしたらプロダクトを認知してもらえるのか.本書は「プロダクトマーケティング」というテーマで,理論・アプローチ・事例まで学べる刺激的な一冊だった.

と同時に本書を読んだだけで満足するのではなく,実際にプロダクト(もしくは何かしらプロダクトのようなもの)でアプローチを実践をすることで学びを深められる一冊でもあると感じた👏

本書は翻訳者であり友人でもある id:ykmc に送っていただいた.ありがとう❗️そして2冊目の出版本当におめでとう🎉

僕自身は今ソフトウェアエンジニアとして実際にプロダクト開発をしているけど,マーケティングは自分には関係ないと考えるのではなく,何かできることはないだろうか・どうすればもっとシナジーを生み出せるのだろうか,などプロダクトやマーケティングにさらなる歩み寄りが必要だなと姿勢を考えさせられた.

2023年3月まで約5年ほど技術講師としてプロダクト開発に携わるエンジニアの人材育成に注力していたけど,今は自分自身がプロダクト開発の現場にまた戻って本当に楽しみながら働けている.実はプロダクト開発にまた戻って活躍したいなと背中を押してくれた理由の一つとして,同じく id:ykmc が翻訳をした「プロダクト・レッド・オーガニゼーション」を読んだことが関係してて,本当にいつも刺激を与えてくれてありがとう❗️

kakakakakku.hatenablog.com

目次

  • PART Ⅰ : プロダクトマーケティングの基本
  • PART Ⅱ : プロダクトマーケターの役割
  • PART Ⅲ : プロダクトマーケティングの戦略
  • PART Ⅳ : ストーリーとメッセージング
  • PART Ⅴ : プロダクトマーケティングリーダー

プロダクトマーケティングの基本

PART Ⅰ では,プロダクトマーケティングの基本として,4種類の役割(活動)が解説されていた.ただ闇雲に「プロダクトマーケティング」と捉えるのではなく,具体的に言語化された目的を意識することで視野が広がりそう.また CHAPTER 1「巨人に打ち勝つとき」に載っているよくある誤解に "プロダクトマーケティングの仕事は販促物や営業資料を作ること" と書かれていたのも興味深かった.今までの限られた経験の中でもそのように振る舞っているように見えていた人はいたし,逆にもっと戦略性を持って振る舞っているように見えていた人もいて,過去の振り返りながら読めたのも良かった.

  • 基本 1「アンバサダー」
  • 基本 2「ストラテジスト」
  • 基本 3「ストーリーテラー」
  • 基本 4「エバンジェリスト」

そして,事例として Pocket, Microsoft Word, Dropbox, Quizlet など,実際に使ったことのあるプロダクトの話も出てくるため,実践的なプロダクトマーケティングをイメージできたのも良かった👌

アンチパターン

CHAPTER 8「プロダクトマネジメントとのパートナーシップ」と CHAPTER 9「マーケティングとのパートナーシップ」と CHAPTER 10「営業とのパートナーシップ」には "アンチパターン" と "良い状態" という具体例が紹介されていて,これは該当するものも多く首を立てに振りながら読んでいた👀

例えば,技術ファーストになりすぎていて「プロダクトはリリースされるけど営業が販売できない」や,戦略的な視点が落ちてしまっていて「マーケティングチームが営業チームへサービスを提供しているようになってしまう」など.

アジャイルマーケティング

CHAPTER 12「アジャイル時代のプロダクトマーケティング」も考えさせられる内容だった.エンジニア側とマーケティング側で機能開発や改善に対する温度感が異なる話は実体験としてもあって,だからこそ本章に載っていた「リリーススケール(リリースの分類と Go-to-Market 目標の共通理解を深める情報)」を活用する話はすぐにでも試せそうだった❗️

他にはアジャイルソフトウェア開発宣言(マニフェスト)を参考にした「アジャイルマーケティングマニフェスト」の話も載っていておもしろかった.本書の基本原則とサイトの原則は少し違う?

agilemarketingmanifesto.org

あわせて読みたい

プロダクト開発を学ぶシリーズとして「INSPIRED」「EMPOWERED」がある.「LOVED」は3作目という位置付けとのこと📚

翻訳者 id:ykmc の発表資料もリンクしておく🔗

speakerdeck.com

誤植

読みながら気付いたものをまとめておく📝

  • P.230 : 一線を画していることシンプルに示した。一線を画していることをシンプルに示した。

pub.jmam.co.jp

まとめ

書籍「LOVED」は Go-to-Market 戦略として「プロダクトと市場とユーザーをつなぐ」アプローチと事例を学べる一冊だった❗️冒頭に読むだけではなく実践することで学びを深められると書いたけど,そのためにはプロダクト開発に関わるメンバー同士で本書の輪読会をするなど,シナジーを生み出せるように活用するのも良さそう.読むと良さそうな同僚にも積極的におすすめしていくぞー💡

僕自身はソフトウェアエンジニアとして,プロダクトマーケティングにも興味を示しできることから取り組んでいきたいと思えた👏

TFLint: Terraform の Linter を活用しよう

Terraform を使うときに記法やお作法を共通化してベストプラクティスに近付けるために TFLint を導入すると便利❗️

最近 TFLint を導入する機会があったので作業ログをまとめる📝

github.com

TFLint をセットアップする

TFLint のセットアップは macOS だと Homebrew を使えば簡単〜

今回は TFLint v0.47.0 を前提にする.

$ brew install tflint

$ tflint --version
TFLint version 0.47.0
+ ruleset.terraform (0.4.0-bundled)

TFLint を実行する

基本的には tflint コマンドを実行すれば OK👌

該当する Warning があるとだーっと表示される.

$ tflint
10 issue(s) found:

もしモジュールを使ってて modules/ ディレクトリ直下も TFLint の対象にする場合は --recursive オプションを使う.

$ tflint --recursive

TFLint にどんなルールがあるのか

ちょうど最近改善を担当することになった Terraform プロジェクトに TFLint を実行してみたところ Warning が 400件 も出てきた🔥

$ tflint --recursive
400 issue(s) found:

(中略)

出てきた Warning をまとめるとほとんどは以下の5種類だった.

  • Warning: [Fixable] Interpolation-only expressions are deprecated in Terraform v0.12.14 (terraform_deprecated_interpolation)
  • Warning: [Fixable] variable "xxx" is declared but not used (terraform_unused_declarations)
  • Warning: `xxx` variable has no type (terraform_typed_variables)
  • Warning: terraform "required_version" attribute is required (terraform_required_version)
  • Warning: Missing version constraint for provider "aws" in `required_providers` (terraform_required_providers)

現時点だと TFLint の Terraform ルールセットには「16種類」のルールが実装されている.その中でもデフォルトでは Recommended として「10種類」のルールが有効化されている.

github.com

TFLint の設定ファイル .tflint.hcl で以下のように preset = "all" と書くとすべてのルールを有効化できる.

plugin "terraform" {
  enabled = true
  preset  = "all"
}

今度は --config オプションで .tflint.hcl を指定して実行すると,Warning と Notice が 620件 に増えた🔥

$ tflint --recursive --config $(pwd)/.tflint.hcl
620 issue(s) found:

(中略)

個別にルールを無効化する

個別にルールを無効化する場合は .tflint.hcl にルールごとに enabled = false と書けば ok👌

rule "terraform_required_version" {
  enabled = false
}

rule "terraform_required_providers" {
  enabled = false
}

自動的に修正する

出てきた Warning を自動的に修正する場合は --fix オプションを使う.ただし,自動的に修正できないルールもあるので,最終的には一つずつ確認しながら修正していくのが良いと思う.

$ tflint --recursive --fix

TFLint を GitHub Actions で動かす

TFLint を GitHub Actions で動かす場合は「Setup TFLint Action」を使えば簡単に導入できる❗️

github.com

TFLint は --format compact オプションも対応しているため,GitHub Actions の Problem Matchers を使ってプルリクエストに直接コメントできる❗️

\( 'ω')/ これは便利〜

name: TFLint

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

jobs:
  tflint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup TFLint
        uses: terraform-linters/setup-tflint@v3
        with:
          tflint_version: v0.47.0
      - name: Show version
        run: tflint --version
      - name: Run TFLint
        run: tflint --recursive --config $(pwd)/.tflint.hcl --format compact

TFLint Ruleset for terraform-provider-aws も導入する

TFLint の Plugin として TFLint Ruleset for terraform-provider-aws を導入すると AWS Provider に特化したルールを追加できる❗️以下のように .tflint.hcl に plugin を追加して tflint --init コマンドを実行すれば OK👌

plugin "aws" {
  enabled = true
  version = "0.24.3"
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

こっちは特に Warning は出なかった💨

github.com