kikukawa's diary

都内で活動するシステムエンジニアが書いてます。 興味を持った技術やハマったポイント、自分用メモをつけてます。 最近はweb中心

datadogでfargateのコンテナ監視をする

datadogでコンテナ内の詳細なメトリクスが取得できるようになります。

上記2つを参考に進めていけばあっさりと設定できます。

コンテナ定義

[
  {
      "cpu": 0,
      "memoryReservation": 1024,
      "name": "foo-app",
      "image": "xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/foo-app-repository:latest",
      "essential": true,
      "dockerLabels": {
          "com.datadoghq.tags.env": "prd",
          "com.datadoghq.tags.service": "foo-app"
      },
      "logConfiguration": {
          "logDriver": "awslogs",
          "options": {
              "awslogs-group": "foo-app-log-group",
              "awslogs-region": "ap-northeast-1",
              "awslogs-stream-prefix": "ecs"
          }
      },
      "secrets": [
          {
          "name": "DB_HOST",
          "valueFrom": "/DB_HOST"
          },
          {
          "name": "DB_USER",
          "valueFrom": "/DB_USER"
          },
          {
          "name": "DB_PASS",
          "valueFrom": "/DB_PASS"
          },
          {
          "name": "DB_NAME",
          "valueFrom": "/DB_NAME"
          }
      ]
  },
  {
      "cpu": 10,
      "memoryReservation": 256,
      "name": "datadog-agent",
      "image": "datadog/agent:latest",
      "essential": true,
      "logConfiguration": {
          "logDriver": "awslogs",
          "options": {
              "awslogs-group": "datadog-agent-log-group",
              "awslogs-region": "ap-northeast-1",
              "awslogs-stream-prefix": "ecs"
          }
      },
      "secrets": [
          {
          "name": "DD_API_KEY",
          "valueFrom": "/DD_API_KEY"
          }
      ],
      "environment": [
          {
          "name": "ECS_FARGATE",
          "value": "true"
          }
      ]
  }
]

アプリケーション側の dockerLabels

datadogのタグ付けを行っています。
DD_DOCKER_LABELS_AS_TAGSDD_DOCKER_ENV_AS_TAGS を使うこともできるようですが、
datadogとしては下記の方法を推奨しているようです。
https://docs.datadoghq.com/ja/getting_started/tagging/unified_service_tagging/?tab=ecs

今回はアプリケーション側にenvがないので、 部分的なコンフィギュレーション で設定しています。

追加のインテグレーションのメトリクス収集

こちらで

インテグレーションメトリクスの収集の詳細については、ECS Fargate のインテグレーションセットアップを参照してください。

とあるのですが、最初なんのことか分からず困りました。
要はアプリケーション側がdatadogが対応しているインテグレーション(ミドルウェアなど)であれば、
追加でさらに詳細なメトリクスを収集できますよ。
ということのようです。

参考

aws cliからfargateのタスクを実行する

すでにタスク定義が存在するfargateタスクをaws cliから実行する方法です。
いろいろ探しましたが、fargateではなくインスタンスであったり、サービス前提のタスクだったりで
私の欲しい物がなかったので覚書を残します。

前提

  • fargateで動かす
  • タスク定義はすでに存在する
  • サービスでは動かさない
  • タスク定義はバッチのような動きをする

iam周り

aws cliを叩くときに指定するiamには以下のアクションを許可しています。

  • ecs:ListTaskDefinitions
  • ecs:ListTasks
  • ecs:DescribeTasks
  • ecs:RunTask
  • iam:PassRole

ecs:ListTaskDefinitions , ecs:ListTasks , ecs:DescribeTasks はタスク実行前、実行中に
list-task-definitions , list-tasks , wait tasks-stopped などを使うためです。
iam:PassRole はタスク定義で指定しているタスク実行ロールにわたすためです。

コマンド

$ aws ecs list-task-definitions #タスク定義のarnを確認する
$ aws ecs run-task \
    --cluster foo-cluster \
    --task-definition arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/foo-task-definision:9 \ #確認したarnをリビジョン含めて指定する
    --launch-type FARGATE \
    --network-configuration 'awsvpcConfiguration={subnets=[subnet-xxxx],securityGroups=[sg-xxxxxxxx],assignPublicIp=DISABLED}' #ネットワーク周りの設定を指定する
$ aws ecs list-tasks --cluster foo-cluster #タスク一覧で確認する
$ aws ecs wait tasks-stopped \ #タスクが終わるのを待つ
    --cluster foo-cluster \
    --tasks arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx #run-taskで返ってきたarnを指定する

参考

embulkでgoogle analyticsからデータを抽出する

embulkのinputプラグインである embulk-input-google_analytics を使ってgoogle analyticsからデータを抽出したので覚書です。

GCP ConsoleとGAのつなぎこみ

embulk-input-google_analytics では、GAの認証をGCPのサービスアカウントで認証します。
そのためにはGCPとGAをつなぎこまなければなりません。

手順としては、

  1. GCP側でサービスアカウントを作成する
  2. 作成したサービスアカウントのメールアドレスで、GA側にユーザーを作る

というだけです。

実際の作業は このサイト が分かりやすいです。

dimensions,metricsに指定するもの

ymlに設定するdimensions,metricsは Dimensions & Metrics Explorer にあるものが指定できます。 GAのreporting apiのパラメーターと同じものです。

embulk-output-bigqueryと一緒に使うとエラーになる場合

BigQueryに出力するのが流れとしては自然かと思いますが、 embulk-output-bigquery をしようするとエラーがでます。
こちら に同様の質問がありました。
その場合は、 embulk-input-google_analytics の v0.1.24以降を指定すると解決することがあります。

直接の原因はterratailにあるようにGemごとのバージョン依存関係なのですが https://github.com/treasure-data/embulk-input-google_analytics/pull/46 がで解決されてv0.1.24で取り込まれてます。

ssh-keygenよく使うもの

自分用メモ

鍵ペアを作る

$ ssh-keygen -t ed25519 -C "" -m PEM
$ ssh-keygen -t rsa -b 4096 -C "" -m PEM

強度の強い ed25519 が使えればそれを使い
使えない場合は、 rsa4096 を使います
-C は公開鍵に記載されるコメントなので不要なら空文字を指定しておきます
-m はフォーマットの指定。なしだとopenssh形式になります。PEM形式にしておきたいので指定します。
パスフレーズをなしにしたい場合は、聞かれたときに何も入力せずエンターでなしにできます。

パスレーズを変更する

$ ssh-keygen -p -f path/to/secret-key

秘密鍵から公開鍵を作る

$ ssh-keygen -y -f path/to/secret-key

パスフレーズがある場合は入力を求められます。
入力を求められるかどうかでパスフレーズが設定されているかどうかの確認にも使えます。

参考

sftpコマンドまとめ

毎回検索しているので自分用メモ

接続

$ sftp -oPort="2222" foo@localhost #ポート指定
$ sftp -oPort="2222" -oIdentityFile=~/ssh/sftp_rsa foo@localhost #ポートと鍵指定

ディレクトリの移動、確認

リモート側は普通にコマンドを打つだけ

$ pwd
$ ls
$ cd path/to

ローカルは接頭辞に l をつける

$ lpwd
$ lls
$ lcd path/to

get

リモート側からホスト側にファイルを引っ張る

$ get foo.txt
$ mget *.txt #メタ文字を使うときはmget

put

リモート側にホスト側からファイルを送る

$ put foo.txt
$ mput *.txt #メタ文字を使うときはmput

パスの補完

Macのデフォルトのsftpコマンドではパスの補完が出来ないが、opensshのsftpならばできる

brew install openssh

参考

https://cns-guide.sfc.keio.ac.jp/2004/2/6/3.html

terraformによるAWSパラメーターストアの管理

パラメーターストアをterraformで管理したいけど、 値はコード上に残したくない場合は、 ignore_changes を使います。
for_eachを併用した例を載せます。

locals {
  params = [
    "db/host",
    "db/user",
    "db/password",
    "db/name",
  ]
}
resource "aws_ssm_parameter" "list" {
  for_each = toset(local.params) //listをtosetでfor_eachで使えるようにします。keyもvalueも同じ値が入ります。
  name  = "/${each.key}"
  value = "ignore" //値自体は別途編集するのでなんでもよい
  type  = "String"
  lifecycle {
    ignore_changes = [value]
  }
}

for_eachで作成したリソースのstateを指定する

for_eachで作成したリソースは、どのようにstateを指定するか戸惑ったのでメモです。

リソースの種類.リソース名["for_eachのkey"] で指定するみたいです。

もともとそれぞれ別リソースを作成していた場合にfor_eachで書き直した場合を考えてみます。

before

resource "aws_ssm_parameter" "foo" {
  name  = /foo
  value = "example-foo"
  type  = "String"
}
resource "aws_ssm_parameter" "bar" {
  name  = /bar
  value = "example-bar"
  type  = "String"
}

after

locals {
  params = [
    "foo",
    "bar",
  ]
}
resource "aws_ssm_parameter" "list" {
  for_each = toset(local.params) //listをtosetでfor_eachで使えるようにします。keyもvalueも同じ値が入ります。
  name  = "/${each.key}"
  value = "example-${each.key}"
  type  = "String"
}

state mv

こんな感じで指定します。

$ terraform state mv aws_ssm_parameter.foo 'aws_ssm_parameter.list["foo"]'
$ terraform state mv aws_ssm_parameter.bar 'aws_ssm_parameter.list["bar"]'

参考

https://www.terraform.io/docs/commands/import.html