vague memory

うろ覚えを無くしていこうともがき苦しむ人の備忘録

AWS CDK を AWS SSO で利用

cdk deploy, cdk diff 実行時に以下のエラーに遭遇しました。 実行対象のAWSアカウントへは AWS SSO を利用してアクセスしている環境でした。

Unable to resolve AWS account to use. It must be either configured when you define your CDK or through the environment

debug log 出力(--verbose) してみると下記エラー。

Unable to determine the default AWS account: ProcessCredentialsProviderFailure: Profile xxxxx did not include credential process

誤設定を疑って調べていたのですが、aws cli 実行は問題なく行え、cdk doctor でも正しい値を返していました。

原因

現時点で cdk では Named Profile をサポートしていないようです。

~/.aws/credentials への設定がある形式でないと認識できないようです。

対処

上記Issueの中でいくつか回避策が提示されています。

aws-export-credentialsaws-sso-credential-process を利用する方式を使わせてもらおうと思ったのですが、 aws-sso-util に組み込まれているとのことなので、こちらを利用します。

インストール

記載の手順通りにインストールします。

brew install pipx
pipx ensurepath
pipx install aws-sso-util
  • 確認
~ % pipx list
venvs are in /Users/xxxxx/.local/pipx/venvs
apps are exposed on your $PATH at /Users/xxxxx/.local/bin
   package aws-sso-util 4.25.0, Python 3.9.5
    - aws-sso-util
~ % aws-sso-util --version
4.25.0

関数設定

~/.zshrc などで読み込ませます。 AWS_CONFIGURE_SSO_DEFAULT_* の値は適宜変更します。

export AWS_CONFIGURE_SSO_DEFAULT_SSO_START_URL=https://xxxxx.awsapps.com/start
export AWS_CONFIGURE_SSO_DEFAULT_SSO_REGION=us-east-1

実行

  • ~/.aws/config
    • AWS SSO 向け設定がしてある状態
    • credential_process を追加
[profile xxxxx]
sso_start_url= https://xxxxx.awsapps.com/start
sso_region=ap-northeast-1
sso_account_id=123456789012
sso_role_name=XXXXX
credential_process = aws-sso-util credential-process --profile xxxxx
  • sso login
aws-sso-util login

# もしくは
#aws sso login --profile XXXXX

以上で正常に cdk コマンド正常が行えました。

いずれ cdk 側で正式にサポートされると思いますが、当面はこちらの方法を利用したいと思います。

aws-export-credentials

If you try this and your tools still don't work with the credentials, you can get the credentials themselves using aws-export-credentials, which can also inject them as environment variables for your program.

今回は aws-sso-util のみで必要十分だったのですが、せっかくなので載せておきます。

# インストール
pipx install aws-export-credentials
aws-export-credentials --version

# 環境変数設定
eval $(aws-export-credentials --env-export)
#eval $(aws-export-credentials --profile XXXXX --env-export) 

# 確認
env | grep AWS

Datadog へ Fluent Bit 内部メトリクスの送信

前置き

Fluent Bit で HTTP_Server を有効化することでメトリクスを参照できる機能があります。 (v1.7.0 時点では、Windows は非対応のようです)

これを Datadog に流します。

インテグレーションが用意されているのではと思ったのですが、 ログの送信先としての案内はありますが、メトリクスはありません。 (尚、Fluentd はあります)

公式ドキュメントの方に記述は見つけられなかったのですが、OpenMetrics で連携ができるとのことでした。 Datadog は Prometheus, OpenMetrics をサポートしており、いずれもインテグレーションが用意されています。

設定

openmetrics.d/conf.yaml に Fluent Bit の Prometheus format のエンドポイント (api/v1/metrics/prometheus)を指定することで、 カスタムメトリクスとして転送されます。

サンプル記載例

instances:
  - prometheus_url: <PROMETHEUS_URL>
    namespace: service
    metrics:
      - processor:cpu
      - memory:mem
      - io

全メトリクスを対象にする例

instances:
  - prometheus_url: http://127.0.0.1:2020/api/v1/metrics/prometheus
    namespace: td-agent-bit
    metrics: 
      - '*'

Datadog 上での表示

Fluent Bit のプラグイン名がname タグに振り分けられます。

f:id:htnosm:20210530111626p:plain

AWS ロールの切り替え(スイッチロール)のブックマーク

AWSのマネジメントコンソールでロール切り替えをする際に、 履歴の数では賄えなくなってきたためロール管理方法のメモ

管理ツールなど


あまのじゃく

  • 拡張機能使わず、ブックマークで良い
  • まとめて生成したい
  • 設定は1箇所で賄いたい

~./aws/config (color = xxxxx でカラー指定) からインポート用のファイルを生成

Generate bookmarks HTML based on ~/.aws/config

$ curl -O https://gist.githubusercontent.com/htnosm/86483972e3a32b93fd6666db8a58b60d/raw/034885c71731c8b78e2416f1ce7a6f2452a4dc92/generate-aws-switch-role-bookmark.py

$ python -V
Python 3.8.9
$ python generate-aws-switch-role-bookmark.py > bookmark.html

AWS ChatbotのEventBridgeサポート

AmazonEventBridge を介して Chatbot を利用できるようになりました。

ドキュメントにも以下の記載があります。

Currently, AWS Chatbot can process all service events handled by Amazon EventBridge.

  • 以前は未サポート形式だとエラー
Event received is not supported (see https://docs.aws.amazon.com/chatbot/latest/adminguide/related-services.html )
  • AutoScaling イベントの通知例

f:id:htnosm:20210421102140p:plain

残念ながらカスタムイベントはサポートされていませんが、 ほぼほぼ網羅された感じです。

Terraform for_each で map 使用時の index 取得

Terraform v0.12.6 から利用できるようになった for_each で count.index の様な連番付与が行えないか調べました。

for_each の利点無くなるので結果的に使わなかったのですが、何かに使えるかもしれないのでメモ。 定義した変数を基にするのであれば、そこに含めてしまえば良いので出番は無いでしょう。

version

  • >= v0.12.6
$ terraform version
Terraform v0.14.6
+ provider registry.terraform.io/hashicorp/aws v3.28.0

以下、便宜的に resource aws_sns_topic を指定していますが特に意味は無いです。

map

locals {
  # map定義
  servers = {
    "serverA" = { role = "web" }
    "serverB" = { role = "ap" }
    "serverC" = { role = "db" }
  }
  # mapからindex作成
  servers_index = [for k, v in local.servers : k]
}

# resource定義
resource "aws_sns_topic" "sns_topic" {
  for_each = local.servers
  name     = "${each.key}-${each.value.role}-${index(local.servers_index, each.key)}"
}

plan

  # aws_sns_topic.sns_topic["serverA"] will be created
  + resource "aws_sns_topic" "sns_topic" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverA-web-0"
      + policy = (known after apply)
    }

  # aws_sns_topic.sns_topic["serverB"] will be created
  + resource "aws_sns_topic" "sns_topic" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverB-ap-1"
      + policy = (known after apply)
    }

  # aws_sns_topic.sns_topic["serverC"] will be created
  + resource "aws_sns_topic" "sns_topic" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverC-db-2"
      + policy = (known after apply)
    }

list

  • for_each に list は直接渡せないため変換が必要
The given "for_each" argument value is unsuitable: the "for_each" argument
must be a map, or set of strings, and you have provided a value of type tuple.
locals {
  # list定義
  server_list = [
    "serverA", "serverB", "serverC"
  ]
  # listからmapに変換
  server_list_to_map = { for i, j in local.server_list : j => { index = i } }
}

# tosetを使用した場合、key,valueが同値となる
# > each.key and each.value are the same for a set
resource "aws_sns_topic" "sns_topic_list" {
  for_each = toset(local.server_list)
  name     = "${each.key}-${each.value}"
}
# 変換したmapを使用
resource "aws_sns_topic" "sns_topic_list_to_map" {
  for_each = local.server_list_to_map
  name     = "${each.key}-${each.value.index}"
}

plan

  # aws_sns_topic.sns_topic_list["serverA"] will be created
  + resource "aws_sns_topic" "sns_topic_list" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverA-serverA"
      + policy = (known after apply)
    }

  # aws_sns_topic.sns_topic_list["serverB"] will be created
  + resource "aws_sns_topic" "sns_topic_list" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverB-serverB"
      + policy = (known after apply)
    }

  # aws_sns_topic.sns_topic_list["serverC"] will be created
  + resource "aws_sns_topic" "sns_topic_list" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverC-serverC"
      + policy = (known after apply)
    }

  # aws_sns_topic.sns_topic_list_to_map["serverA"] will be created
  + resource "aws_sns_topic" "sns_topic_list_to_map" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverA-0"
      + policy = (known after apply)
    }

  # aws_sns_topic.sns_topic_list_to_map["serverB"] will be created
  + resource "aws_sns_topic" "sns_topic_list_to_map" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverB-1"
      + policy = (known after apply)
    }

  # aws_sns_topic.sns_topic_list_to_map["serverC"] will be created
  + resource "aws_sns_topic" "sns_topic_list_to_map" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "serverC-2"
      + policy = (known after apply)
    }

Opsgenie Monit Integration

Monit から Opsgenie へアラートを通知します。

f:id:htnosm:20210118075308p:plain

公式ではメールでの連携方法が紹介されていますが、 各監視対象ホストでメール送信を有効化するのが手間だったのでAPIを利用します。

前置き

軽く探索してみた所、下記情報があります。

これらを参考にスクリプトを作成しました。

Monit -> Opsgenie 通知用スクリプト

設定

Opsgenie APIキー取得

REST API のインテグレーションから取得します。

  • [Team] -> 対象のチーム -> [Integrations] -> APIインテグレーション

f:id:htnosm:20210118075313p:plain

スクリプト格納

監視対象ホストにて、任意の場所にスクリプトをダウンロードします。

wget https://raw.githubusercontent.com/htnosm/opsgenie-monit.sh/main/opsgenie-trigger
wget https://raw.githubusercontent.com/htnosm/opsgenie-monit.sh/main/opsgenie-resolve

ダウンロードした2つのスクリプトに実行権限を与え、スクリプト内の OPSGENIE_API_KEY を書き換えます。

# 実行権限付与
chmod +x opsgenie-*
# OPSGENIE_API_KEY="1234567890abcdef1234567890abcdef"
↓
OPSGENIE_API_KEY="Opsgenie APIキー"

Monit設定

Failure、Success それぞれにアラート作成、クローズのスクリプトを指定します。

check process crond with pidfile /var/run/crond.pid
    if does not exist for 3 cycles
        then exec "/etc/monit/opsgenie-trigger"
    else if passed for 3 cycles
        then exec "/etc/monit/opsgenie-resolve"

正常に設定できていれば、Monit に連動して Opsgenie のアラート作成とクローズが行えます。

  • Alert created via API

f:id:htnosm:20210118075319p:plain

  • Alert closed via API

f:id:htnosm:20210118075324p:plain

MacOS コマンドラインで「選択したビデオファイルをエンコード」

選択したビデオファイルをエンコード(Encode Selected Video Files)

f:id:htnosm:20201231032200p:plain

上の様にFinderから実行できますが、 コマンドライン実行したかったので調査。 Mac OS X 10.7 Lion から追加された基本機能とのこと。

avconvert

  • オーディオのみ メニューと同等のコマンド例
$ avconvert --preset PresetAppleM4A --source test.mov --output test.m4a

avconvert completed with error:0.

$ file test.*
test.m4a:     ISO Media, Apple iTunes ALAC/AAC-LC (.M4A) Audio
test.mov:     ISO Media, Apple QuickTime movie, Apple QuickTime (.MOV/QT)

オプション

usage: avconvert [--param <value> ...]

    Required parameters:
        --preset (or -p)          <presetName>  Use --help to list all available preset names.
        --source (or -s)          <source media file>
        --output (or -o)          <output movie file>

    Optional parameters:
        --disableFastStart        Disable fast-start movie creation.  Reduces disk accesses if fast-start is not required.
        --disableMetadataFilter   Disable the metadata filter.  Use with caution.  This will allow privacy sensitive source metadata to be preserved in the output file.  Refer to the man page for more details.
        --duration <duration>     Trim the output movie to duration seconds (decimal allowed).  Default is end of file.
        --help (or -h)            Print command usage and list available preset names.
        --multiPass               Perform a higher quality multi-pass encode in the conversion, if supported by the codec.
        --progress (or -prog)     Display progress information.
        --replace                 Overwrite the output file, if it already exists.
        --start <startTime>       Skip the first startTime seconds (decimal allowed) of the source movie.  Default is beginning of file.
        --verbose (or -v)         Print additional information about the conversion.

参考