ふり返る暇なんて無いね

日々のメモ書きをつらつらと。メインブログに書くほどでもないことを流してます

terraformでDataDogリソースを管理したかったのに403 Forbiddenと言われたとき

現象

terraformでdatadogプロバイダーを使ってdatadogリソースを管理しようとしていたのですが、apiキーもappキーも正しいものを使ってるはずなのに、403が出てこまりました。

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: 403 Forbidden
│ 
│   with module.datadog.provider["registry.terraform.io/datadog/datadog"],
│   on modules/datadog/provider.tf line 19, in provider "datadog":
│   19: provider "datadog" {
│ 
╵

原因

当初こんな感じに設定していました。api_urlの指定をしてませんでした。

provider "datadog" {
  api_key = var.datadog_api_key
  app_key = var.datadog_app_key
}

providerのソースコードを読んでもデフォルト値が分からないのですが、おそらく https://app.datadoghq.com の値がセットされてしまってるのかなと推定しています。 今回東京リージョン(AP1)を使っています。東京リージョンのURLは https://ap1.datadoghq.com なのでこの値api_urlを明示的にセットしてあげることで、planが通るようになりました。

variable "datadog_api_url" {
  type    = string
  default = "https://ap1.datadoghq.com"
}


provider "datadog" {
  api_key = var.datadog_api_key
  app_key = var.datadog_app_key
  api_url = var.datadog_api_url
}

参考

CloudSQL(PostgreSQL)のmax_connectionsを上げたい

割り当てと上限  |  Cloud SQL ドキュメント  |  Google Cloud にありますが、max_connectionsフラグを設定することで設定変更できます。

MySQL max_connections フラグを使用すると、接続数の上限を構成できます。MySQL で最大 100,000 件の接続が可能です。データベースに接続して次のコマンドを実行すると、インスタンスの接続数上限を確認できます。 SHOW VARIABLES LIKE "max_connections";

PostgreSQL max_connections フラグを使用すると、接続数の上限を構成できます。Cloud SQL for PostgreSQL インスタンスを作成すると、マシンタイプ構成設定により、選択したコア数に基づき、自動的に利用可能なメモリサイズの範囲が調整されます。これにより、インスタンスに設定される当初のデフォルトの接続数上限も設定されます。

データベースに接続して次のコマンドを実行すると、インスタンスの接続数上限を確認できます。SELECT * FROM pg_settings WHERE name = 'max_connections';

terraform で書くとするとこんな感じでしょうか。

resource "google_sql_database_instance" "main" {
  name             = "db_instance"
  database_version = "POSTGRES_14"
  region           = "asia-northeast1"

  settings {
    tier = "db-f1-micro"
    database_flags {
      name  = "max_connections"
      value = 100
    }
  }
}

なお、デフォルトのmax_connectionsはメモリーの容量によって自動的に設定されます。db-f1-microならメモリ0.6GBなのでmax_connectionsは25となります。

DB接続回りでほかに注意する点としてはCloud Runインスタンス当たりの接続数は100までに制限されています。

Cloud Run に関する上限 Cloud Run サービスでは、Cloud SQL データベースに対する接続数が 100 に制限されています。この上限はサービス インスタンスごとに適用されます。つまり、Cloud Run サービスの各インスタンスはデータベースに対して 100 接続を保持できるため、スケールした場合にデプロイあたりの接続の合計数が増加する可能性があります。

EventBridgeで受け取ったパラメータを後続のターゲットに渡したい

忘れがちな脳への覚え書きです

正確にはここを読んでください。

Amazon EventBridge input transformation - Amazon EventBridge

サンプルとして、S3バケットのCreate Objectを拾って、バケット名とオブジェクトをECSタスクに環境変数として引き渡す例を記載します。

locals {
  name                    = "eventbridge-input-test"
  ecs_task_definition_arn = "タスク定義ARN"
  ecs_cluster_arn         = "ECS Cluster ARN"
  security_group_id       = "ECSタスクのセキュリティグループ"
  subnets                 = ["ECSタスクのサブネット"]
}

module "source_bucket" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "3.14.0"

  bucket = "${local.name}-source"

  versioning = {
    enabled = true
  }
}

# XXX: s3モジュール単体では通知が対応していないので、ここで別途設定する
resource "aws_s3_bucket_notification" "source_bucket" {

  bucket      = module.source_bucket.s3_bucket_id
  eventbridge = true
}

module "collect_event_csv" {
  source  = "terraform-aws-modules/eventbridge/aws"
  version = "1.17.3"

  create_bus        = false
  role_name         = "${local.name}-event"
  attach_ecs_policy = true
  ecs_target_arns   = [local.ecs_task_definition_arn]

  rules = {
    "${local.name}-target-ecs" = {
      description = "create object event"
      event_pattern = jsonencode({
        "source" : ["aws.s3"],
        "detail-type" : ["Object Created"]
        "detail" : {
          "bucket" : {
            "name" : ["${module.source_bucket.s3_bucket_id}"]
          }
        }
      })
    }
  }

  targets = {
    "${local.name}-target-ecs" = [
      {
        name            = "${local.name}-target-ecs"
        arn             = local.ecs_cluster_arn
        attach_role_arn = true
        ecs_target = {
          launch_type         = "FARGATE"
          task_count          = 1
          task_definition_arn = local.ecs_task_definition_arn

          network_configuration = {
            assign_public_ip    = true
            subnets             = local.subnets
            aws_security_groups = [local.security_group_id]
          }
        }
        input_transformer = {
          input_paths = {
            # $のあとにeventに存在する目的のパスを指定する。この場合S3のオブジェクト作成Eventからバケット名が取得出来る
            source_bucket = "$.detail.bucket.name" 
            target_object = "$.detail.object.key"
          }
          input_template = <<TEMPLATE
{
  "containerOverrides": [
    {
      "name": "${local.container_name}, # 書き換えるコンテナ名を指定
      "environment": [
        # input_transformer.input_pathsで指定したsource_bucketの値が実行時に変換される
        { "name": "SOURCE_BUCKET", "value": <source_bucket> }, 
        { "name": "TARGET_OBJECT", "value": <target_object> }
      ]
    }
  ]
}
TEMPLATE
        }
      }
    ]
  }
}

特定のファイルが変更されたときだけGItLab CIのジョブを動かしたい

忘れがちな脳のためのメモ

これでtest/ディレクトリおよびtest.txtが変更されたときだけジョブが走るようにする。

stages:
  - build

ex-build:
  stage: build
  script:
    - echo "てすと"
    - ls test/
    - cat test.txt
  rules:
    - changes:
      - test.txt
      - test/*

参考: .gitlab-ci.yml keyword reference | GitLab の rules:changes の項

notion整理した

散らかりたい放題だったnotionをだいぶ整理した。

タグとして機能するのは、技術タグと分類タグ。

ドキュメントの分類としてはタスクとストックとフローに加えて、記事のリンクをコピペしていくスクラップの4本立てでやってく。

しばらく運用してみてうまくいきそうだったらこのまま行きたいところ。

KCNA-JP(Kubernetes and Cloud Native Associate)に合格してました。

10/6にKubernetes and Cloud Native Associateを受けてきました。そして合格してきました。

training.linuxfoundation.org

credlyのリンクも置いておきます。 www.credly.com

Kubernetes何もわからない民から、なんとなく分かる民になりました。本当の目標は次に受けるCKAなので、弾みになりました。

ちなみに、LPI-JAPAN経由で円建てで受験用クーポン買えるのですが、ちょうど11/1に価格改定があり、値上げされてました。自分はタイミング悪く11/1に購入したのでかなしいですね。

為替次第で円建てで買うかドル建て買うかどちらが安いかは変わるので少し考えて見ると良いと思います。

k8s.stores.jp

勉強方法

Linux Foundationが公式で出してるトレーニンKubernetesとクラウドネイティブ基礎(LFS250-JP)をやってました。内容としてはすごくまとまってて良かったです。

training.linuxfoundation.org

この内容を完璧にして、参考リンクまで知識を深めていけば、合格はそこまでむつかしくないのかなという印象です。

当日

日本語対応とはいえ、問題文と試験官のチャットだけ日本語で、それ以外は全て英語でした。そこまでむつかしくはないのでなんとかはなりました。

試験を受けるためにPSIのセキュアブラウザをインストールしないといけないのですが、自分のM1 MacBook AirだとVentureにアップグレードしたせいなのか、インストールを何回してもエラーになるという出来事がありました。仕方ないので、都合良く前日に初期化してたInterl MacBook Pro(Monterey)に入れて事なきを得ました。

また、普段使いのデスクが致命的に散らかってて、試験環境に向かなかったので、使ってない部屋の床に座って試験を受けてました。ただ、床座は腰に来るので次回からはやめようと思いました。

受け終わった後の所感としては、細かい知識の詰めが甘くて、受かってるかどうか五分五分だなあという感じでした。基礎をちゃんと固めれば受かる試験ですが、なめてかかると普通に落ちるなあという感じですね。

結果

試験後24時間で結果がメールで通知されます。スコアはトレーニングポータルのページを見に行かないと見れないです。

なお、自分のスコアは85で微妙な感じです。アソシエイトレベルの試験なのでもう少し余裕を持った点数で受かりたかった気持ちはあります。次のCKAに向けて精進します。

あとで調べる: Venturaにアップグレード後にxcrunが見つからないと言われる件、ところでxrunってなに

makeとかhomebrewで入れたツール類を実行しようとすると以下のエラーが出るようになった。

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

対処方としてはxcodeのcommand line toolsをインストールすれば良いのですが、

xcode-select --install 

ところでxcrunってなんですかね?manを引くとこんな感じ。

複数のxcodeのツールチェーンをサポートするためにMakefileなどを変更せずにも、コマンドラインからデベロッパーツールを呼び出したり見つけたりする機能を提供する。らしい。xcode回りを雰囲気で使ってるのでこの辺よく分からないので、あとで深みにはまりたいところ。

ビルド済みのコマンドとか実行するのに必要そうな感じは受けないのだが、どこでどう使われてるかも調べたいところ。

XCRUN(1)                                                                     BSD General Commands Manual                                                                    XCRUN(1)

NAME
       xcrun - Run or locate development tools and properties.

SYNOPSIS
       xcrun [--sdk <SDK name>] --find <tool name>

       xcrun [--sdk <SDK name>] <tool name> ... tool arguments ...

       <tool name> ... tool arguments ...

DESCRIPTION
       xcrun provides a means to locate or invoke developer tools from the command-line, without requiring users to modify Makefiles or otherwise take inconvenient measures to
       support multiple Xcode tool chains.

       The tool xcode-select(1) is used to set a system default for the active developer directory, and may be overridden by the DEVELOPER_DIR environment variable (see
       ENVIRONMENT).

       The SDK which will be searched defaults to the most recent available SDK, and can be specified by the SDKROOT environment variable or the --sdk option (which takes
       precedences over SDKROOT). When used to invoke another tool (as opposed to simply finding it), xcrun will provide the absolute path to the selected SDK in the SDKROOT
       environment variable. See ENVIRONMENT for more information.

未解決: Cloud Runのオートスケールする条件が分からなかった

Cloud Runのオートスケールする条件がいまいちよく分からなかったので、調べてました。

結論として、ちゃんとした条件が分からなかったので、時間が取れるときにちゃんと実験したいです。

確実なのは公式ドキュメントなので、関係のありそうな歌唱から読んでいきます。

コンテナ インスタンスの自動スケーリングについて  |  Cloud Run のドキュメント  |  Google Cloud

Cloud Run では、リビジョンのスケーリングが自動的に行われます。すべての受信リクエストまたはイベントを処理できるように、必要なコンテナ インスタンスの数が調整されます。リビジョンがトラフィックを受信しない場合、デフォルトでは、コンテナ インスタンスの数がゼロにスケールインされます。このデフォルトは必要に応じて変更できます。インスタンスをアイドル状態のままにすることも、最小インスタンスの設定を使用してウォームアップを指定することもできます。

受信リクエストまたはイベントのレートに加えて、スケジュールされるインスタンスの数は以下の影響を受けます。

ここでは、CPU使用率が60%を維持するようにつまり60%を超えるとスケールするように読み取れます。

インスタンスあたりの最大同時リクエスト数(サービス)  |  Cloud Run のドキュメント  |  Google Cloud

Cloud Run サービスでは、リビジョンのスケーリングが自動的に行われます。すべての受信リクエストを処理できるように、必要なコンテナ インスタンスの数が調整されます。

ここでは、現在稼働してるインスタンスの合計最大同時実行数ではリクエストを処理しきれなくなりそうになるとスケールするように読み取れます。

リソースモデル  |  Cloud Run のドキュメント  |  Google Cloud

リビジョンは、受信したすべてのリクエストを処理できるように、コンテナ インスタンスの数を自動的にスケーリングします。1 つのコンテナ インスタンスが同時に多くのリクエストを受信する場合があります。同時実行の設定を使用すると、1 つのコンテナ インスタンスに同時に送信されるリクエストの最大数を設定できます。

ここも同じこと言ってますね。

まとめると、

  • CPU60%を維持(超えない)ようにスケーリングする
  • すべてのリクエストを処理できるように(同時実行数を超えると)スケーリングする
    • ただし、最大インスタンス数の制限を超えてスケールすることはできない。

ということでいいんですかね?

余談ですが、Cloud Runのオートスケーリングについて調べてたときに見つけたこの動画すごく参考になりました。オートスケーリングに関しては、何も得るものがなかったんですが、ログとリクエストの紐付けとか運用上役に立つ知識が得られました。

www.youtube.com

故障と障害の違いがわからずに困惑してた

ふと調査ごとをしてて故障と障害ってなんか違いあるんだっけ?と疑問に思い調べてました。

JIS X 0014:1999 情報処理用語-信頼性、保守性及び可用性

いったん、JIS X 0014:1999の定義を見てみることにします。

故障は要求された機能の能力がなくなること。できごとを表す感じですかね?

故障
要求された機能を遂行する,機能単位の能力がなくなること。
備考 この定義はJIS Z 8115 : 1981と同一であるが,JIS Z 8115 : 1981には更に幾つかの備考がある。

なるほど。障害は要求された機能が実行できない異常状態らしいです。

障害
要求された機能を遂行する機能単位の能力の,縮退又は喪失を引き起こす,異常な状態。
備考 JIS Z 8115 : 1981では,予防保守又は他の計画的な作業の間に発生する場合,及び外部資源の不足のために発生する場合を除いて,要求された機能を遂行できない状態を“フォールト”と定義している

ちょっとこれだけだとよくわからないので、言及されてるJIS Z 8115を見てみましょう。

JIS Z 8115 : 2000 デイペンダビリティ(信頼性)用語

JIS Z 8115 : 1981が見つからないので今回はJIS Z 8115 : 2000を見ていきます。

これも機能を失うこと。イベントですね。故障はイベント、フォールト(障害)は状態という区別らしいです。そしてそれらを厳密に区別しないこともある。

故障
アイテムが要求機能達成能力を失うこと。

備考1.  一般に,アイテムは故障の後フォールトをもつ。
2.故障は,イベントであり,状態であるフォールトと区別される。
3.ソフトウェアを含むシステムは故障事象をもち,その要因はシステムを構成するハードウェア,ソフトウェア,及び人的要素等の個々の状態又はそれらの組み合わさった複合状態に起因した不具合及び故障によっても発生する。
4.システム故障は系全体の機能の喪失又は規定された機能水準を下回る,系の一時的機能低下,すなわち,系のサービス中断として用いる。
5.ソフトウェア故障という用語は,一般にシステム故障が発生したときの状態において使用される。
6.イベントと状態を厳密に区別しないで故障ということかある。参考  正しい理解と使用のために解説を参照する

障害にあたるフォールトを見てみると。1つ目は機能が実行できない状態。2つ目がちょっとわかりにくいですが、こちらも状態としてとっていいのかな。

フォールト
a)ある要求された機能を遂行不可能なアイテムの状態,また,その状態にあるアイテムの部分。
b)アイテムの要求機能遂行能力を失わせたり,要求機能遂行能力に支障を起こさせる原因(設計の状態)。ただし,予防保全又はその他の計画された活動にる場合,若しくは外部からの供給不良による場合は除く。

備考1.  フォールトはアイテム自体の故障の結果であるが,先行ずる故障がなくても存在することがある。
2.故障発生の過程を原因−結果の連鎖とした場合,故障の原因をフォールトとみなすこともある。フォールトは,着目しているアイテムの下位のアイテムの故障である場合もあるが,アイテム自身に内包されている場合もある。
3.ソフトウェアアイテムの場合,コンピュータシステムではプログラム全体てのプログラミング,論理構成,プログラムプロセス,チータ定義などの間違いを意味する。
4.ソフトウェアフォールトはハードウェアの故障要因と区別するときに使用する場合がある。参考  正しい理解と使用のために解説を参照する

ところで、アイテムとは、

アイテム
ディペンダビリティの対象となる,部品,構成品,デバイス,装置,機能ユニット,機器,サブシステム,システムなどの総称又はいずれか。
備考1.  アイテムは,ハードウェア,ソフトウェア,又は両方から構成される。さらに,特別な場合は,人間も含む。
2.複数のアイテム,例えば,アイテムの母集団及びサンプルは,それ自身アイテムとして考えることができる。
3.ソフトウェアアイテムとして用いる場合は,例えば,ソースコード,オブジェクトコード,ジョブ制御言語.関連文書類又はこれらの集合体を指す(SW1 参照)。
参考  IEC 60050 (191)  の対応英語 entity は除いてある(解説を参照)。

ISTQB 用語集

昔、JATQBの試験を受けたときにこの辺の単語見た気がしたので改めて用語集を見てみます。

ISTQB Glossary failure

日本語だと状態を表してるように読み取れますが、原文だとEventになってます。JISでいうところの故障と同じような概念を指してるように見えます。

故障(failure)
コンポーネントやシステムが定義された範囲内で要求する機能を実行しないこと。
An event in which a component or system does not perform a required function within specified limits.

ISTQB Glossary fault

フォールトそのものは載ってないのですが、Synonymとしてdefectがありました。ただ、JISでいうところのフォールトとは違う意味のように取れます。うーむ?

欠陥(defect)
作業成果物に存在する、要件または仕様を満たさない不備または欠点。
Synonyms: バグ(bug), フォールト(fault), 問題(problem)
An imperfection or deficiency in a work product where it does not meet its requirements or specifications.

結果

余計困惑しました。

アイテムが故障した結果、フォールト(障害)の状態になるというのが基本的な理解で、ただ、故障とフォールトは厳密に区別せずに使われることもある。そういう理解で良いのでしょうか?