tech - ふり返る暇なんて無いね 日々のメモ書きをつらつらと。メインブログに書くほどでもないことを流してます 2024-03-28T13:03:37+09:00 masasuz Hatena::Blog hatenablog://blog/12704914408863016875 ALBのヘルスチェック間隔でどれくらいだっけ? hatenablog://entry/6801883189094178779 2024-03-28T13:03:37+09:00 2024-03-28T13:03:37+09:00 解 HealthCheckIntervalSecondsの設定次第で、デフォルト30秒。5秒から300秒の範囲で指定ができる。 参考:ターゲットグループのヘルスチェック - Elastic Load Balancing 背景 LambdaをALBのバックエンドにしたときにヘルスチェックを設定すると無料の範囲内からはみ出ないか、というところが気になりました。なお、Lambdaの無料枠は1ヶ月あたり100万回となります。 参考:料金 - AWS Lambda |AWS AWS Lambda の無料利用枠には、1 か月あたり 100 万件の無料リクエスト デフォルトの30秒間隔であれば、1分間に2回… <h1 id="解">解</h1> <p>HealthCheckIntervalSecondsの設定次第で、デフォルト30秒。5秒から300秒の範囲で指定ができる。</p> <ul> <li>参考:<a href="https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/network/target-group-health-checks.html">ターゲットグループのヘルスチェック - Elastic Load Balancing</a></li> </ul> <h1 id="背景">背景</h1> <p>LambdaをALBのバックエンドにしたときにヘルスチェックを設定すると無料の範囲内からはみ出ないか、というところが気になりました。なお、Lambdaの無料枠は1ヶ月あたり100万回となります。</p> <ul> <li>参考:<a href="https://aws.amazon.com/jp/lambda/pricing/">料金 - AWS Lambda |AWS</a> <blockquote><p>AWS Lambda の無料利用枠には、1 か月あたり 100 万件の無料リクエスト</p></blockquote></li> </ul> <p>デフォルトの30秒間隔であれば、1分間に2回呼び出されることとなる。1ヶ月を30日とすると以下のような計算式になります。</p> <p><code>2(/minute)*60(minutes)*24(hours)*30(days)=86400回</code></p> <p>結論としては8万6千回強なので、100万回には程遠い。他のLambdaの使われ方次第ではあるが、気にしなくても良いという結論となりました。</p> masasuz CDKTFでリソースのアトリビュートに対して文字列処理がうまくできなかった件 hatenablog://entry/6801883189093621699 2024-03-26T02:14:37+09:00 2024-03-26T02:14:37+09:00 リソースのアトリビュートを文字列処理しようとしたらうまく動かなかったという現象に出会ったのですが、 結論としては、リソースのアトリビュートはStringではなくTokensという型なので、Stringのメソッドは使えないという話しです。 Tokens - CDK for Terraform | Terraform | HashiCorp Developer <p>リソースのアトリビュートを文字列処理しようとしたらうまく動かなかったという現象に出会ったのですが、 結論としては、リソースのアトリビュートはStringではなくTokensという型なので、Stringのメソッドは使えないという話しです。</p> <p><a href="https://developer.hashicorp.com/terraform/cdktf/concepts/tokens">Tokens - CDK for Terraform | Terraform | HashiCorp Developer</a></p> <h1 id="現象">現象</h1> <p>こんな感じでIAM Policyを定義しようとしていました。 タスク定義ARNの末尾には <code>:${リビジョン番号}</code> が付与されてるので、これを削除するためにreplace()を使ってるつもりですが、これはうまく動きません。 意図通りreplaceされることはなく、タスク定義ARNがそのままの値でResourceに渡されてしまいます。</p> <pre class="code lang-typescript" data-lang="typescript" data-unlink> <span class="synType">const</span> taskDefinition <span class="synStatement">=</span> <span class="synStatement">new</span> EcsTaskDefinition<span class="synStatement">(</span><span class="synIdentifier">this</span><span class="synStatement">,</span> <span class="synConstant">&quot;ecs_task_definition&quot;</span><span class="synStatement">,</span> <span class="synIdentifier">{</span> <span class="synComment">// 省略</span> <span class="synIdentifier">}</span><span class="synStatement">);</span> <span class="synStatement">new</span> IamPolicy<span class="synStatement">(</span><span class="synIdentifier">this</span><span class="synStatement">,</span> <span class="synConstant">&quot;ecs_deploy_policy&quot;</span><span class="synStatement">,</span> <span class="synIdentifier">{</span> name: getResourceName<span class="synStatement">(</span><span class="synConstant">&quot;ecs-deploy-policy&quot;</span><span class="synStatement">),</span> policy: <span class="synSpecial">JSON</span>.stringify<span class="synStatement">(</span><span class="synIdentifier">{</span> Version: <span class="synConstant">&quot;2012-10-17&quot;</span><span class="synStatement">,</span> Statement: <span class="synIdentifier">[</span> <span class="synIdentifier">{</span> Sid: <span class="synConstant">&quot;RegisterTaskDefinitionWithTag&quot;</span><span class="synStatement">,</span> Effect: <span class="synConstant">&quot;Allow&quot;</span><span class="synStatement">,</span> Action: <span class="synIdentifier">[</span><span class="synConstant">&quot;ecs:TagResource&quot;</span><span class="synIdentifier">]</span><span class="synStatement">,</span> Condition: <span class="synIdentifier">{</span> StringEquals: <span class="synIdentifier">{</span> <span class="synConstant">&quot;ecs:CreateAction&quot;</span>: <span class="synConstant">&quot;RegisterTaskDefinition&quot;</span><span class="synStatement">,</span> <span class="synIdentifier">}</span><span class="synStatement">,</span> <span class="synIdentifier">}</span><span class="synStatement">,</span> Resource: taskDefinition.arn.replace<span class="synStatement">(</span><span class="synConstant">&quot;/:[1-9][0-9]*$/&quot;</span><span class="synStatement">,</span> <span class="synConstant">&quot;&quot;</span><span class="synStatement">),</span> <span class="synIdentifier">}</span><span class="synStatement">,</span> <span class="synIdentifier">]</span><span class="synStatement">,</span> <span class="synIdentifier">}</span><span class="synStatement">)</span> </pre> <h1 id="原因">原因</h1> <p><a href="https://developer.hashicorp.com/terraform/cdktf/concepts/tokens">Tokens - CDK for Terraform | Terraform | HashiCorp Developer</a></p> <p>タスク定義ARNの型はStringではなく、Tokens型です。Tokensはモジュールのoutputやリソースのアトリビュートに使われる型で、terraformがapplyされるまで不定の値を示します。</p> <p>Tokensを文字列として扱うためにはFnを利用してterraformの組み込み関数を呼び出すか、asString()メソッドを呼び出して、Stringに変換してから文字列処理をしてあげる必要があります。</p> <h1 id="解">解</h1> <p>解としては以下の通りになります。</p> <pre class="code lang-typescript" data-lang="typescript" data-unlink> <span class="synStatement">import</span> <span class="synIdentifier">{</span> Fn <span class="synIdentifier">}</span> <span class="synStatement">from</span> <span class="synConstant">&quot;cdktf&quot;</span><span class="synStatement">;</span> <span class="synStatement">new</span> IamPolicy<span class="synStatement">(</span><span class="synIdentifier">this</span><span class="synStatement">,</span> <span class="synConstant">&quot;ecs_deploy_policy&quot;</span><span class="synStatement">,</span> <span class="synIdentifier">{</span> name: getResourceName<span class="synStatement">(</span><span class="synConstant">&quot;ecs-deploy-policy&quot;</span><span class="synStatement">),</span> policy: <span class="synSpecial">JSON</span>.stringify<span class="synStatement">(</span><span class="synIdentifier">{</span> Version: <span class="synConstant">&quot;2012-10-17&quot;</span><span class="synStatement">,</span> Statement: <span class="synIdentifier">[</span> <span class="synIdentifier">{</span> Sid: <span class="synConstant">&quot;RegisterTaskDefinitionWithTag&quot;</span><span class="synStatement">,</span> Effect: <span class="synConstant">&quot;Allow&quot;</span><span class="synStatement">,</span> Action: <span class="synIdentifier">[</span><span class="synConstant">&quot;ecs:TagResource&quot;</span><span class="synIdentifier">]</span><span class="synStatement">,</span> Condition: <span class="synIdentifier">{</span> StringEquals: <span class="synIdentifier">{</span> <span class="synConstant">&quot;ecs:CreateAction&quot;</span>: <span class="synConstant">&quot;RegisterTaskDefinition&quot;</span><span class="synStatement">,</span> <span class="synIdentifier">}</span><span class="synStatement">,</span> <span class="synIdentifier">}</span><span class="synStatement">,</span> Resource: Fn.replace<span class="synStatement">(</span>taskDefinition.arn<span class="synStatement">,</span> <span class="synConstant">&quot;/:[1-9][0-9]*$/&quot;</span><span class="synStatement">,</span> <span class="synConstant">&quot;&quot;</span><span class="synStatement">),</span> <span class="synIdentifier">}</span><span class="synStatement">,</span> <span class="synIdentifier">]</span><span class="synStatement">,</span> <span class="synIdentifier">}</span><span class="synStatement">),</span> <span class="synIdentifier">}</span><span class="synStatement">);</span> </pre> masasuz Spannerを触りたい。(Spanner構築と接続確認まで) hatenablog://entry/6801883189079069418 2024-01-29T23:00:00+09:00 2024-01-30T00:57:17+09:00 Cloud SQLでPostgreSQLを使っていたのですが、諸事情でSpannerを検証する必要があるので、ざっくり構築して接続確認するまでのメモです。 Spanner構築 Terraformでざっくり作ります。マルチリージョン構成で、スペックは最低で作ります。 database_dialectをPOSTGRESQLにすることでPostgreSQLと互換が取れます。 ########################################### # Service API ########################################### resource "go… <p>Cloud SQLでPostgreSQLを使っていたのですが、諸事情でSpannerを検証する必要があるので、ざっくり構築して接続確認するまでのメモです。</p> <h1 id="Spanner構築">Spanner構築</h1> <p>Terraformでざっくり作ります。マルチリージョン構成で、スペックは最低で作ります。 database_dialectをPOSTGRESQLにすることでPostgreSQLと互換が取れます。</p> <pre class="code lang-hcl" data-lang="hcl" data-unlink><span class="synComment">###########################################</span> <span class="synComment"># Service API</span> <span class="synComment">###########################################</span> <span class="synType">resource</span> <span class="synConstant">&quot;google_project_service&quot;</span> <span class="synConstant">&quot;main&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">for_each</span> = <span class="synSpecial">{</span> <span class="synStatement">for</span> service <span class="synStatement">in</span> <span class="synSpecial">[</span> <span class="synConstant">&quot;spanner.googleapis.com&quot;</span>, <span class="synSpecial">]</span> : service =&gt; service <span class="synSpecial">}</span> <span class="synIdentifier">service</span> = each.key <span class="synIdentifier">disable_dependent_services</span> = <span class="synConstant">true</span> <span class="synIdentifier">disable_on_destroy</span> = <span class="synConstant">false</span> } <span class="synComment">###########################################</span> <span class="synComment"># Spanner</span> <span class="synComment">###########################################</span> <span class="synType">resource</span> <span class="synConstant">&quot;google_spanner_instance&quot;</span> <span class="synConstant">&quot;main&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">config</span> = <span class="synConstant">&quot;asia1&quot;</span> <span class="synIdentifier">name</span> = <span class="synConstant">&quot;poc-spanner&quot;</span> <span class="synIdentifier">display_name</span> = <span class="synConstant">&quot;poc-spanner&quot;</span> <span class="synIdentifier">processing_units</span> = <span class="synConstant">100</span> <span class="synIdentifier">depends_on</span> = <span class="synSpecial">[</span> google_project_service.main <span class="synSpecial">]</span> } <span class="synType">resource</span> <span class="synConstant">&quot;google_spanner_database&quot;</span> <span class="synConstant">&quot;database&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">instance</span> = google_spanner_instance.main.name <span class="synIdentifier">name</span> = <span class="synConstant">&quot;poc&quot;</span> <span class="synIdentifier">database_dialect</span> = <span class="synConstant">&quot;POSTGRESQL&quot;</span> <span class="synSpecial">}</span> </pre> <ul> <li>参考: <a href="https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/spanner_instance">google_spanner_instance | Resources | hashicorp/google | Terraform | Terraform Registry</a></li> <li>参考: <a href="https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/spanner_database">google_spanner_database | Resources | hashicorp/google | Terraform | Terraform Registry</a></li> </ul> <h1 id="Spannerに接続">Spannerに接続</h1> <p>SpannerにはPostgreSQLのインターフェースがあるが、これに接続するために、PGAdapterを使用する必要があります。 PGAdapterはローカルで起動して、Spannerに接続するためのプロキシとして働きます。</p> <p>今回はMac上にPGAdapterをインストールして、接続確認します。</p> <ul> <li>参考: <a href="https://cloud.google.com/spanner/docs/pgadapter?hl=ja">PGAdapter の概要  |  Cloud Spanner  |  Google Cloud</a></li> <li>参考: <a href="https://cloud.google.com/spanner/docs/pgadapter-get?hl=ja">PGAdapter を取得する  |  Cloud Spanner  |  Google Cloud</a></li> </ul> <p>とりあえず、javaのランタイムとpsqlクライアントをインストールします。</p> <pre class="code" data-lang="" data-unlink>brew install java echo &#39;export PATH=&#34;/opt/homebrew/opt/openjdk/bin:$PATH&#34;&#39; &gt;&gt; ~/.zshrc sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk brew install libpq echo &#39;export PATH=&#34;/opt/homebrew/opt/libpq/bin:$PATH&#34;&#39; &gt;&gt; ~/.zshrc exec ${SHELL} -l</pre> <p>PGAdapterをダウンロードして、起動します</p> <pre class="code" data-lang="" data-unlink>wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz &amp;&amp; tar -xzvf pgadapter.tar.gz java -jar pgadapter.jar -p ${PROJECT_ID} -i ${INSTANCE_NAME} -d ${DATABASE}</pre> <p>ターミナルを別窓で開いてpsqlで接続して雑にテーブルを作ってみます。</p> <pre class="code" data-lang="" data-unlink>% psql -h localhost psql (16.1, server 14.1) Type &#34;help&#34; for help. poc=&gt; CREATE TABLE Staff ( poc-&gt; id INTEGER NOT NULL, poc(&gt; name TEXT NOT NULL, poc(&gt; age INTEGER , poc(&gt; PRIMARY KEY (id));</pre> <p>気持ちテーブル作成に時間がかかる気がします。</p> <p>コンソールからテーブルを確認すると作成されていることが確認できます。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masasuz/20240130/20240130004247.png" width="1200" height="854" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>いったん接続出来るところまで確認できました。 ここから既存のデータを入れたり、Cloud Run上のアプリケーションから接続したりを確認していきます。</p> masasuz TerraformでEventBridgeのターゲットにCloudWatch Logsにするリソースを構築するとうまく動かない件 hatenablog://entry/6801883189078377771 2024-01-28T00:00:00+09:00 2024-01-28T00:00:01+09:00 現象 Terraformで以下のようにECSイベントが発生した際にそれをCloudWatch Logsに出力するEventBridge ruleとtargetを作成したところ、うまくCloudWatch Logsにイベントが出力されませんでした。 resource "aws_cloudwatch_log_group" "main" { name = "/aws/events/masasuzu/test/ecs/event" retention_in_days = 3 } module "eventbridge" { source = "terraform-aws-modules/eventbr… <h1 id="現象">現象</h1> <p>Terraformで以下のようにECSイベントが発生した際にそれをCloudWatch Logsに出力するEventBridge ruleとtargetを作成したところ、うまくCloudWatch Logsにイベントが出力されませんでした。</p> <pre class="code lang-hcl" data-lang="hcl" data-unlink><span class="synType">resource</span> <span class="synConstant">&quot;aws_cloudwatch_log_group&quot;</span> <span class="synConstant">&quot;main&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">name</span> = <span class="synConstant">&quot;/aws/events/masasuzu/test/ecs/event&quot;</span> <span class="synIdentifier">retention_in_days</span> = <span class="synConstant">3</span> <span class="synSpecial">}</span> <span class="synType">module</span> <span class="synConstant">&quot;eventbridge&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">source</span> = <span class="synConstant">&quot;terraform-aws-modules/eventbridge/aws&quot;</span> <span class="synIdentifier">create_bus</span> = <span class="synConstant">false</span> <span class="synIdentifier">create_role</span> = <span class="synConstant">false</span> <span class="synIdentifier">rules</span> = <span class="synSpecial">{</span> <span class="synConstant">&quot;masasuzu-test-ecs-event-log&quot;</span> = <span class="synSpecial">{</span> <span class="synIdentifier">event_pattern</span> = <span class="synIdentifier">jsonencode</span>(<span class="synSpecial">{</span> <span class="synConstant">&quot;source&quot;</span> : <span class="synSpecial">[</span><span class="synConstant">&quot;aws.ecs&quot;</span><span class="synSpecial">]</span>, <span class="synSpecial">}</span>) <span class="synIdentifier">enabled</span> = <span class="synConstant">true</span> <span class="synSpecial">}</span> <span class="synSpecial">}</span> <span class="synIdentifier">targets</span> = <span class="synSpecial">{</span> <span class="synConstant">&quot;masasuzu-test-ecs-event-log&quot;</span> = <span class="synSpecial">[</span> <span class="synSpecial">{</span> <span class="synIdentifier">name</span> = <span class="synConstant">&quot;masasuzu-test-ecs-event-log&quot;</span> <span class="synIdentifier">arn</span> = aws_cloudwatch_log_group.main.arn <span class="synSpecial">}</span> <span class="synSpecial">]</span> <span class="synSpecial">}</span> } </pre> <p>試しにコンソールから同様のリソースを作成したところうまくCloudWatch Logsに出力され、Terraformで作ったEventBridgeも正しく動くようになりました。</p> <p>ここからわかることはコンソールでEventBridgeの設定をした際に裏側で暗黙的になにかリソースが作られたということです。</p> <h1 id="原因">原因</h1> <p>EventBridgeからCloudWatch Logsへの出力を許可するためにCloudWatch Logsのリソースポリシーを設定する必要があります。</p> <p>まっさらなAWSアカウントでは以下のようにCloudWatch Logsのリソースポリシーが設定されています。何も設定されていません。</p> <pre class="code" data-lang="" data-unlink>% aws logs describe-resource-policies --no-cli-pager { &#34;resourcePolicies&#34;: [] }</pre> <p>コンソールからEventBridgeの設定をすると以下のような設定が追加されます。これにより、EventBridgeからCloudWatch LogsへのPutLogEventsやCreateLogStreamが許可され、無事イベントがログに出力されるようになります。</p> <pre class="code" data-lang="" data-unlink>% aws logs describe-resource-policies --no-cli-pager { &#34;resourcePolicies&#34;: [ { &#34;policyName&#34;: &#34;TrustEventsToStoreLogEvents&#34;, &#34;policyDocument&#34;: &#34;{\&#34;Version\&#34;:\&#34;2012-10-17\&#34;,\&#34;Statement\&#34;:[{\&#34;Sid\&#34;:\&#34;TrustEventsToStoreLogEvent\&#34;,\&#34;Effect\&#34;:\&#34;Allow\&#34;,\&#34;Principal\&#34;:{\&#34;Service\&#34;:[\&#34;delivery.logs.amazonaws.com\&#34;,\&#34;events.amazonaws.com\&#34;]},\&#34;Action\&#34;:[\&#34;logs:CreateLogStream\&#34;,\&#34;logs:PutLogEvents\&#34;],\&#34;Resource\&#34;:\&#34;arn:aws:logs:ap-northeast-1:xxxxxxxxxx:log-group:/aws/events/*:*\&#34;}]}&#34;, &#34;lastUpdatedTime&#34;: 1705025982872 } ] }</pre> <h1 id="対策">対策</h1> <p>リソースポリシーを設定するために、以下のような記述を追加してあげると良いでしょう。</p> <pre class="code lang-hcl" data-lang="hcl" data-unlink><span class="synType">data</span> <span class="synConstant">&quot;aws_iam_policy_document&quot;</span> <span class="synConstant">&quot;main&quot;</span> <span class="synSpecial">{</span> <span class="synType">statement</span> <span class="synSpecial">{</span> <span class="synIdentifier">actions</span> = <span class="synSpecial">[</span> <span class="synConstant">&quot;logs:CreateLogStream&quot;</span>, <span class="synConstant">&quot;logs:PutLogEvents&quot;</span>, <span class="synSpecial">]</span> <span class="synIdentifier">resources</span> = <span class="synSpecial">[</span><span class="synConstant">&quot;arn:aws:logs:ap-northeast-1:$</span><span class="synSpecial">{</span>var.account_id<span class="synSpecial">}</span><span class="synConstant">:log-group:$</span><span class="synSpecial">{</span>var.log_group_path<span class="synSpecial">}</span><span class="synConstant">:*&quot;</span><span class="synSpecial">]</span> <span class="synType">principals</span> <span class="synSpecial">{</span> <span class="synIdentifier">identifiers</span> = <span class="synSpecial">[</span><span class="synConstant">&quot;events.amazonaws.com&quot;</span><span class="synSpecial">]</span> <span class="synIdentifier">type</span> = <span class="synConstant">&quot;Service&quot;</span> <span class="synSpecial">}</span> } } <span class="synType">resource</span> <span class="synConstant">&quot;aws_cloudwatch_log_resource_policy&quot;</span> <span class="synConstant">&quot;main&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">policy_document</span> = data.aws_iam_policy_document.main.json <span class="synIdentifier">policy_name</span> = <span class="synConstant">&quot;EventsToLog&quot;</span> <span class="synSpecial">}</span> </pre> <p>参考: <a href="https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html">CloudWatch Logs リソースへの許可の管理の概要 - Amazon CloudWatch Logs</a></p> <p>参考: <a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_resource_policy">aws_cloudwatch_log_resource_policy | Resources | hashicorp/aws | Terraform | Terraform Registry</a></p> masasuz GCSのバケットをすべてコピーしたい(同期したい) hatenablog://entry/6801883189078290951 2024-01-27T01:14:07+09:00 2024-01-27T01:14:07+09:00 Google Cloud Storageのバケットのリージョンは作成後に変更できません。 そのため、シングルリージョンで作ったバケットをデュアルリージョンまたはマルチリージョンに変えるためには新規で作成し、オブジェクトを全部新しいバケットにコピーした上で切り替えないといけません。 そのためのオブジェクト同期の方法について考えます。 参考: バケットの保存場所 | Cloud Storage | Google Cloud ドキュメントで紹介されている例は転送ジョブとgcloud storage cp gsutil cp ですが、これだとコピーはできますが、バケットの中身を同じにはできません。ここ… <p>Google Cloud Storageのバケットのリージョンは作成後に変更できません。 そのため、シングルリージョンで作ったバケットをデュアルリージョンまたはマルチリージョンに変えるためには新規で作成し、オブジェクトを全部新しいバケットにコピーした上で切り替えないといけません。 そのためのオブジェクト同期の方法について考えます。</p> <ul> <li>参考: <a href="https://cloud.google.com/storage/docs/locations?hl=ja">バケットの保存場所  |  Cloud Storage  |  Google Cloud</a></li> </ul> <p>ドキュメントで紹介されている例は転送ジョブと<code>gcloud storage cp</code> <code>gsutil cp</code> ですが、これだとコピーはできますが、バケットの中身を同じにはできません。ここで別解として <code>gsutil rsync</code> を使います。</p> <ul> <li>参考: <a href="https://cloud.google.com/storage/docs/moving-buckets?hl=ja">バケットの移動と名前変更  |  Cloud Storage  |  Google Cloud</a></li> </ul> <p>コマンド例としては以下の通りになります。</p> <pre class="code" data-lang="" data-unlink>gsutil -m rsync -r -d gs://${転送元バケット名} gs://${転送先バケット名}</pre> <blockquote><p>The -m option typically will provide a large performance boost if either the source or destination (or both) is a cloud URL. If both source and destination are file URLs the -m option will typically thrash the disk and slow synchronization down.</p></blockquote> <p>-mオプションはパフォーマンスの向上のため</p> <blockquote><p>The rsync -d option is very useful and commonly used, because it provides a means of making the contents of a destination bucket or directory match those of a source bucket or directory. This is done by copying all data from the source to the destination and deleting all other data in the destination that is not in the source. Please exercise caution when you use this option: It's possible to delete large amounts of data accidentally if, for example, you erroneously reverse source and destination.</p></blockquote> <p>-rオプションはディレクトリ再帰</p> <blockquote><p>The -R and -r options are synonymous. Causes directories, buckets, and bucket subdirectories to be synchronized recursively. If you neglect to use this option gsutil will make only the top-level directory in the source and destination URLs match, skipping any sub-directories.</p></blockquote> <p>-dは削除オプションとなり転送元に存在しないオブジェクトが転送先にある場合削除されてしまいます。これをつけることで転送元と転送先が同期できますが、バケットを間違えると大変なことになるので注意が必要です。</p> <ul> <li>参考: <a href="https://cloud.google.com/storage/docs/gsutil/commands/rsync">rsync - Synchronize content of two buckets/directories  |  Cloud Storage  |  Google Cloud</a></li> </ul> masasuz google-github-actions/deploy-cloudrunでlabelを付け替えるのをやめさせたい hatenablog://entry/6801883189070539885 2023-12-29T00:18:04+09:00 2023-12-29T01:59:31+09:00 v0からv2にバージョンアップした際にdeploy-cloudrunでlabelを更新する挙動に変わったので、これをやめさせたいといのが趣旨です。 Cloud Run Serviceのlabelはterraform側で制御したいので、GitHub Actions側で変更されると困るのです。 結論から言うと、 skip_default_labelsを trueにしてあげると良いです。 # (省略) - name: Deploy to Cloud Run uses: 'google-github-actions/deploy-cloudrun@v2' with: service: ${{ inpu… <p>v0からv2にバージョンアップした際にdeploy-cloudrunでlabelを更新する挙動に変わったので、これをやめさせたいといのが趣旨です。 Cloud Run Serviceのlabelはterraform側で制御したいので、GitHub Actions側で変更されると困るのです。</p> <p>結論から言うと、 skip_default_labelsを trueにしてあげると良いです。</p> <pre class="code" data-lang="" data-unlink># (省略) - name: Deploy to Cloud Run uses: &#39;google-github-actions/deploy-cloudrun@v2&#39; with: service: ${{ inputs.SERVICE_NAME }} image: ${{ inputs.REPOSITORY }}:${{ github.sha }} project_id: ${{ inputs.PROJECT_ID }} region: ${{ inputs.REGION }} skip_default_labels: true # &lt;&lt;&lt;&lt;&lt; これ</pre> <ul> <li><a href="https://github.com/google-github-actions/deploy-cloudrun/blob/main/README.md">deploy-cloudrun/README.md at main · google-github-actions/deploy-cloudrun</a></li> </ul> <p>ドキュメントの該当箇所は以下の通りです。</p> <blockquote><p>skip_default_labels: (Optional) Skip applying the special annotation labels that indicate the deployment came from GitHub Actions. The GitHub Action will automatically apply the following labels which Cloud Run uses to enhance the user experience:</p> <pre><code>managed-by: github-actions commit-sha: &lt;sha&gt; </code></pre> <p>Setting this to true will skip adding these special labels. The default value is false.</p></blockquote> masasuz EC2インスタンスのuserdataにシェバンがないと動かない hatenablog://entry/820878482969325203 2023-09-21T11:20:51+09:00 2023-09-21T11:20:51+09:00 EC2インスタンスのuserdataの実行履歴を見たい - ふり返る暇なんて無いね でログを確認したところ、以下のように言われてしまった。 2023-09-21 02:01:06,809 - __init__.py[WARNING]: Unhandled non-multipart (text/x-not-multipart) userdata: 'b''...' どうもシェバンがないのでうまくbashスクリプトとして認識してくれなかったようだ。下記1行を先頭に加えて再度起動したところうまく動いた。 #!/bin/bash 参考 起動時に Linux インスタンスでコマンドを実行する - Am… <p><a href="https://diary.masasuzu.net/entry/2023/09/21/111054">EC2インスタンスのuserdataの実行履歴を見たい - ふり返る暇なんて無いね</a> でログを確認したところ、以下のように言われてしまった。</p> <pre class="code" data-lang="" data-unlink>2023-09-21 02:01:06,809 - __init__.py[WARNING]: Unhandled non-multipart (text/x-not-multipart) userdata: &#39;b&#39;&#39;...&#39;</pre> <p>どうもシェバンがないのでうまくbashスクリプトとして認識してくれなかったようだ。下記1行を先頭に加えて再度起動したところうまく動いた。</p> <pre class="code" data-lang="" data-unlink>#!/bin/bash </pre> <p>参考 <a href="https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html#user-data-shell-scripts">起動時に Linux インスタンスでコマンドを実行する - Amazon Elastic Compute Cloud</a></p> <blockquote><p>ユーザーデータシェルスクリプトは、#! 文字と、スクリプトの読み取り先であるインタープリタのパス (通常は /bin/bash)) で開始する必要があります。シェルスクリプティングに関する有用な紹介文は、Linux ドキュメントプロジェクト (tldp.org) の「BASHプログラミングのハウツー」で入手できます。</p></blockquote> masasuz EC2インスタンスのuserdataの実行履歴を見たい hatenablog://entry/820878482969323308 2023-09-21T11:10:54+09:00 2023-09-21T11:10:54+09:00 メモ残しておかないと忘れるので、雑に置いておく。 Session Manager等でログインして、 /var/log/cloud-init-output.log を覗く。 sudo cat /var/log/cloud-init-output.log 参考: 起動時に Linux インスタンスでコマンドを実行する - Amazon Elastic Compute Cloud <p>メモ残しておかないと忘れるので、雑に置いておく。</p> <p>Session Manager等でログインして、 <code>/var/log/cloud-init-output.log</code> を覗く。</p> <pre class="code" data-lang="" data-unlink>sudo cat /var/log/cloud-init-output.log</pre> <p>参考: <a href="https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html#user-data-shell-scripts">起動時に Linux インスタンスでコマンドを実行する - Amazon Elastic Compute Cloud</a></p> masasuz terraformでDataDogリソースを管理したかったのに403 Forbiddenと言われたとき hatenablog://entry/820878482953124059 2023-07-27T11:37:05+09:00 2023-07-27T11:37:05+09:00 現象 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/prov… <h1 id="現象">現象</h1> <p>terraformでdatadogプロバイダーを使ってdatadogリソースを管理しようとしていたのですが、apiキーもappキーも正しいものを使ってるはずなのに、403が出てこまりました。</p> <pre class="code" data-lang="" data-unlink>Planning failed. Terraform encountered an error while generating this plan. ╷ │ Error: 403 Forbidden │ │ with module.datadog.provider[&#34;registry.terraform.io/datadog/datadog&#34;], │ on modules/datadog/provider.tf line 19, in provider &#34;datadog&#34;: │ 19: provider &#34;datadog&#34; { │ ╵</pre> <h1 id="原因">原因</h1> <p>当初こんな感じに設定していました。api_urlの指定をしてませんでした。</p> <pre class="code" data-lang="" data-unlink>provider &#34;datadog&#34; { api_key = var.datadog_api_key app_key = var.datadog_app_key } </pre> <p>providerのソースコードを読んでもデフォルト値が分からないのですが、おそらく <code>https://app.datadoghq.com</code> の値がセットされてしまってるのかなと推定しています。 今回東京リージョン(AP1)を使っています。東京リージョンのURLは <code>https://ap1.datadoghq.com</code> なのでこの値api_urlを明示的にセットしてあげることで、planが通るようになりました。</p> <pre class="code" data-lang="" data-unlink>variable &#34;datadog_api_url&#34; { type = string default = &#34;https://ap1.datadoghq.com&#34; } provider &#34;datadog&#34; { api_key = var.datadog_api_key app_key = var.datadog_app_key api_url = var.datadog_api_url } </pre> <h1 id="参考">参考</h1> <ul> <li><a href="https://registry.terraform.io/providers/DataDog/datadog/latest/docs">Docs overview | DataDog/datadog | Terraform | Terraform Registry</a></li> <li><a href="https://docs.datadoghq.com/ja/getting_started/site/">Datadog サイトの概要</a></li> <li><a href="https://github.com/DataDog/terraform-provider-datadog">DataDog/terraform-provider-datadog: Terraform Datadog provider</a></li> </ul> masasuz CloudSQL(PostgreSQL)のmax_connectionsを上げたい hatenablog://entry/820878482950404894 2023-07-17T00:01:10+09:00 2023-07-17T00:01:10+09:00 割り当てと上限 | Cloud SQL ドキュメント | Google Cloud にありますが、max_connectionsフラグを設定することで設定変更できます。 MySQL max_connections フラグを使用すると、接続数の上限を構成できます。MySQL で最大 100,000 件の接続が可能です。データベースに接続して次のコマンドを実行すると、インスタンスの接続数上限を確認できます。 SHOW VARIABLES LIKE "max_connections"; PostgreSQL max_connections フラグを使用すると、接続数の上限を構成できます。Cloud … <p><a href="https://cloud.google.com/sql/docs/quotas?hl=ja#maximum_concurrent_connections">割り当てと上限  |  Cloud SQL ドキュメント  |  Google Cloud</a> にありますが、max_connectionsフラグを設定することで設定変更できます。</p> <blockquote><p><a class="keyword" href="https://d.hatena.ne.jp/keyword/MySQL">MySQL</a> max_connections フラグを使用すると、接続数の上限を構成できます。<a class="keyword" href="https://d.hatena.ne.jp/keyword/MySQL">MySQL</a> で最大 100,000 件の接続が可能です。データベースに接続して次のコマンドを実行すると、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の接続数上限を確認できます。 SHOW VARIABLES LIKE "max_connections";</p> <p><a class="keyword" href="https://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a> max_connections フラグを使用すると、接続数の上限を構成できます。Cloud <a class="keyword" href="https://d.hatena.ne.jp/keyword/SQL">SQL</a> for <a class="keyword" href="https://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a> <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>を作成すると、マシンタイプ構成設定により、選択したコア数に基づき、自動的に利用可能なメモリサイズの範囲が調整されます。これにより、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>に設定される当初のデフォルトの接続数上限も設定されます。</p> <p>データベースに接続して次のコマンドを実行すると、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の接続数上限を確認できます。SELECT * FROM pg_settings WHERE name = 'max_connections';</p></blockquote> <p>terraform で書くとするとこんな感じでしょうか。</p> <pre class="code" data-lang="" data-unlink>resource &#34;google_sql_database_instance&#34; &#34;main&#34; { name = &#34;db_instance&#34; database_version = &#34;POSTGRES_14&#34; region = &#34;asia-northeast1&#34; settings { tier = &#34;db-f1-micro&#34; database_flags { name = &#34;max_connections&#34; value = 100 } } }</pre> <p>なお、デフォルトのmax_connectionsはメ<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%EA%A1%BC">モリー</a>の容量によって自動的に設定されます。db-f1-microならメモリ0.6GBなのでmax_connectionsは25となります。</p> <ul> <li>参考: <a href="https://cloud.google.com/sql/docs/postgres/flags?hl=ja#postgres-m">データベース フラグを構成する  |  Cloud SQL for PostgreSQL  |  Google Cloud</a></li> </ul> <p>DB接続回りでほかに注意する点としてはCloud Run<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>当たりの接続数は100までに制限されています。</p> <blockquote><p>Cloud Run に関する上限 Cloud Run サービスでは、Cloud <a class="keyword" href="https://d.hatena.ne.jp/keyword/SQL">SQL</a> データベースに対する接続数が 100 に制限されています。この上限はサービス <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>ごとに適用されます。つまり、Cloud Run サービスの各<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>はデータベースに対して 100 接続を保持できるため、スケールした場合にデプロイあたりの接続の合計数が増加する可能性があります。</p></blockquote> masasuz EventBridgeで受け取ったパラメータを後続のターゲットに渡したい hatenablog://entry/820878482950297368 2023-07-16T16:38:07+09:00 2023-07-16T16:38:07+09:00 忘れがちな脳への覚え書きです 正確にはここを読んでください。 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 = "… <p>忘れがちな脳への覚え書きです</p> <p>正確にはここを読んでください。</p> <p><a href="https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-transform-target-input.html">Amazon EventBridge input transformation - Amazon EventBridge</a></p> <p>サンプルとして、S3<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D0%A5%B1%A5%C3%A5%C8">バケット</a>のCreate Objectを拾って、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D0%A5%B1%A5%C3%A5%C8">バケット</a>名とオブジェクトをECSタスクに<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4">環境変数</a>として引き渡す例を記載します。</p> <pre class="code lang-hcl" data-lang="hcl" data-unlink><span class="synType">locals</span> <span class="synSpecial">{</span> <span class="synIdentifier">name</span> = <span class="synConstant">&quot;eventbridge-input-test&quot;</span> <span class="synIdentifier">ecs_task_definition_arn</span> = <span class="synConstant">&quot;タスク定義ARN&quot;</span> <span class="synIdentifier">ecs_cluster_arn</span> = <span class="synConstant">&quot;ECS Cluster ARN&quot;</span> <span class="synIdentifier">security_group_id</span> = <span class="synConstant">&quot;ECSタスクのセキュリティグループ&quot;</span> <span class="synIdentifier">subnets</span> = <span class="synSpecial">[</span><span class="synConstant">&quot;ECSタスクのサブネット&quot;</span><span class="synSpecial">]</span> <span class="synSpecial">}</span> <span class="synType">module</span> <span class="synConstant">&quot;source_bucket&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">source</span> = <span class="synConstant">&quot;terraform-aws-modules/s3-bucket/aws&quot;</span> <span class="synIdentifier">version</span> = <span class="synConstant">&quot;3.14.0&quot;</span> <span class="synIdentifier">bucket</span> = <span class="synConstant">&quot;$</span><span class="synSpecial">{</span>local.name<span class="synSpecial">}</span><span class="synConstant">-source&quot;</span> <span class="synIdentifier">versioning</span> = <span class="synSpecial">{</span> <span class="synIdentifier">enabled</span> = <span class="synConstant">true</span> <span class="synSpecial">}</span> } <span class="synComment"># </span><span class="synTodo">XXX</span><span class="synComment">: s3モジュール単体では通知が対応していないので、ここで別途設定する</span> <span class="synType">resource</span> <span class="synConstant">&quot;aws_s3_bucket_notification&quot;</span> <span class="synConstant">&quot;source_bucket&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">bucket</span> = module.source_bucket.s3_bucket_id <span class="synIdentifier">eventbridge</span> = <span class="synConstant">true</span> } <span class="synType">module</span> <span class="synConstant">&quot;collect_event_csv&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">source</span> = <span class="synConstant">&quot;terraform-aws-modules/eventbridge/aws&quot;</span> <span class="synIdentifier">version</span> = <span class="synConstant">&quot;1.17.3&quot;</span> <span class="synIdentifier">create_bus</span> = <span class="synConstant">false</span> <span class="synIdentifier">role_name</span> = <span class="synConstant">&quot;$</span><span class="synSpecial">{</span>local.name<span class="synSpecial">}</span><span class="synConstant">-event&quot;</span> <span class="synIdentifier">attach_ecs_policy</span> = <span class="synConstant">true</span> <span class="synIdentifier">ecs_target_arns</span> = <span class="synSpecial">[</span>local.ecs_task_definition_arn<span class="synSpecial">]</span> <span class="synIdentifier">rules</span> = <span class="synSpecial">{</span> <span class="synConstant">&quot;$</span><span class="synSpecial">{</span>local.name<span class="synSpecial">}</span><span class="synConstant">-target-ecs&quot;</span> = <span class="synSpecial">{</span> <span class="synIdentifier">description</span> = <span class="synConstant">&quot;create object event&quot;</span> <span class="synIdentifier">event_pattern</span> = <span class="synIdentifier">jsonencode</span>(<span class="synSpecial">{</span> <span class="synConstant">&quot;source&quot;</span> : <span class="synSpecial">[</span><span class="synConstant">&quot;aws.s3&quot;</span><span class="synSpecial">]</span>, <span class="synConstant">&quot;detail-type&quot;</span> : <span class="synSpecial">[</span><span class="synConstant">&quot;Object Created&quot;</span><span class="synSpecial">]</span> <span class="synConstant">&quot;detail&quot;</span> : <span class="synSpecial">{</span> <span class="synConstant">&quot;bucket&quot;</span> : <span class="synSpecial">{</span> <span class="synConstant">&quot;name&quot;</span> : <span class="synSpecial">[</span><span class="synConstant">&quot;$</span><span class="synSpecial">{</span>module.source_bucket.s3_bucket_id<span class="synSpecial">}</span><span class="synConstant">&quot;</span><span class="synSpecial">]</span> <span class="synSpecial">}</span> <span class="synSpecial">}</span> <span class="synSpecial">}</span>) <span class="synSpecial">}</span> <span class="synSpecial">}</span> <span class="synIdentifier">targets</span> = <span class="synSpecial">{</span> <span class="synConstant">&quot;$</span><span class="synSpecial">{</span>local.name<span class="synSpecial">}</span><span class="synConstant">-target-ecs&quot;</span> = <span class="synSpecial">[</span> <span class="synSpecial">{</span> <span class="synIdentifier">name</span> = <span class="synConstant">&quot;$</span><span class="synSpecial">{</span>local.name<span class="synSpecial">}</span><span class="synConstant">-target-ecs&quot;</span> <span class="synIdentifier">arn</span> = local.ecs_cluster_arn <span class="synIdentifier">attach_role_arn</span> = <span class="synConstant">true</span> <span class="synIdentifier">ecs_target</span> = <span class="synSpecial">{</span> <span class="synIdentifier">launch_type</span> = <span class="synConstant">&quot;FARGATE&quot;</span> <span class="synIdentifier">task_count</span> = <span class="synConstant">1</span> <span class="synIdentifier">task_definition_arn</span> = local.ecs_task_definition_arn <span class="synIdentifier">network_configuration</span> = <span class="synSpecial">{</span> <span class="synIdentifier">assign_public_ip</span> = <span class="synConstant">true</span> <span class="synIdentifier">subnets</span> = local.subnets <span class="synIdentifier">aws_security_groups</span> = <span class="synSpecial">[</span>local.security_group_id<span class="synSpecial">]</span> <span class="synSpecial">}</span> } <span class="synIdentifier">input_transformer</span> = <span class="synSpecial">{</span> <span class="synIdentifier">input_paths</span> = <span class="synSpecial">{</span> <span class="synComment"># $のあとにeventに存在する目的のパスを指定する。この場合S3のオブジェクト作成Eventからバケット名が取得出来る</span> <span class="synIdentifier">source_bucket</span> = <span class="synConstant">&quot;$.detail.bucket.name&quot;</span> <span class="synIdentifier">target_object</span> = <span class="synConstant">&quot;$.detail.object.key&quot;</span> <span class="synSpecial">}</span> <span class="synIdentifier">input_template</span> = <span class="synConstant">&lt;&lt;TEMPLATE</span> <span class="synConstant">{</span> <span class="synConstant"> &quot;containerOverrides&quot;: [</span> <span class="synConstant"> {</span> <span class="synConstant"> &quot;name&quot;: &quot;$</span><span class="synSpecial">{</span>local.container_name<span class="synSpecial">}</span><span class="synConstant">, # 書き換えるコンテナ名を指定</span> <span class="synConstant"> &quot;environment&quot;: [</span> <span class="synConstant"> # input_transformer.input_pathsで指定したsource_bucketの値が実行時に変換される</span> <span class="synConstant"> { &quot;name&quot;: &quot;SOURCE_BUCKET&quot;, &quot;value&quot;: &lt;source_bucket&gt; }, </span> <span class="synConstant"> { &quot;name&quot;: &quot;TARGET_OBJECT&quot;, &quot;value&quot;: &lt;target_object&gt; }</span> <span class="synConstant"> ]</span> <span class="synConstant"> }</span> <span class="synConstant"> ]</span> <span class="synConstant">}</span> <span class="synConstant">TEMPLATE</span> <span class="synSpecial">}</span> } <span class="synSpecial">]</span> } } </pre> masasuz 特定のファイルが変更されたときだけGItLab CIのジョブを動かしたい hatenablog://entry/4207112889948615545 2022-12-27T14:05:09+09:00 2022-12-27T14:05:09+09:00 忘れがちな脳のためのメモ これで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 の項 <p>忘れがちな脳のためのメモ</p> <p>これでtest/<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リおよびtest.txtが変更されたときだけジョブが走るようにする。</p> <pre class="code" data-lang="" data-unlink>stages: - build ex-build: stage: build script: - echo &#34;てすと&#34; - ls test/ - cat test.txt rules: - changes: - test.txt - test/*</pre> <p>参考: <a href="https://docs.gitlab.com/ee/ci/yaml/#ruleschanges">.gitlab-ci.yml keyword reference | GitLab</a> の rules:changes の項</p> masasuz KCNA-JP(Kubernetes and Cloud Native Associate)に合格してました。 hatenablog://entry/4207112889934684601 2022-11-08T09:52:22+09:00 2022-11-08T09:52:22+09:00 10/6にKubernetes and Cloud Native Associateを受けてきました。そして合格してきました。 training.linuxfoundation.org credlyのリンクも置いておきます。 www.credly.com Kubernetes何もわからない民から、なんとなく分かる民になりました。本当の目標は次に受けるCKAなので、弾みになりました。 ちなみに、LPI-JAPAN経由で円建てで受験用クーポン買えるのですが、ちょうど11/1に価格改定があり、値上げされてました。自分はタイミング悪く11/1に購入したのでかなしいですね。 為替次第で円建てで買うかドル… <p>10/6に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Kubernetes">Kubernetes</a> and Cloud Native Associateを受けてきました。そして合格してきました。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Ftraining.linuxfoundation.org%2Fja%2Fcertification%2Fkubernetes-and-cloud-native-associate-kcna-jp%2F" title="Kubernetes and Cloud Native Associate (KCNA) Exam | Linux Foundation" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://training.linuxfoundation.org/ja/certification/kubernetes-and-cloud-native-associate-kcna-jp/">training.linuxfoundation.org</a></cite></p> <p>credlyのリンクも置いておきます。 <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.credly.com%2Fbadges%2Fe7059a44-c8d3-4bca-b7a4-fb7d5c76aee4" title="KCNA: Kubernetes and Cloud Native Associate was issued by The Linux Foundation to 鈴木 勝史." class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.credly.com/badges/e7059a44-c8d3-4bca-b7a4-fb7d5c76aee4">www.credly.com</a></cite></p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Kubernetes">Kubernetes</a>何もわからない民から、なんとなく分かる民になりました。本当の目標は次に受ける<a href="https://training.linuxfoundation.org/ja/certification/certified-kubernetes-administrator-cka/">CKA</a>なので、弾みになりました。</p> <p>ちなみに、LPI-JAPAN経由で円建てで受験用クーポン買えるのですが、ちょうど11/1に価格改定があり、値上げされてました。自分はタイミング悪く11/1に購入したのでかなしいですね。</p> <p>為替次第で円建てで買うかドル建て買うかどちらが安いかは変わるので少し考えて見ると良いと思います。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fk8s.stores.jp%2Fitems%2F6299e2c839da5f470bc821c3" title="受験用クーポン:認定Kubernetesクラウドネイティブアソシエイト (KCNA-JP/日本語監督版)試験" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://k8s.stores.jp/items/6299e2c839da5f470bc821c3">k8s.stores.jp</a></cite></p> <h1 id="勉強方法">勉強方法</h1> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a> Foundationが公式で出してるト<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A1%BC%A5%CB%A5%F3">レーニン</a>グ<code>Kubernetesとクラウドネイティブ基礎(LFS250-JP)</code>をやってました。内容としてはすごくまとまってて良かったです。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Ftraining.linuxfoundation.org%2Fja%2Ftraining%2Fkubernetes-and-cloud-native-essentials-lfs250-jp%2F" title="KubernetesとCloudNativeEssentialsトレーニングコース| Linux Foundation" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://training.linuxfoundation.org/ja/training/kubernetes-and-cloud-native-essentials-lfs250-jp/">training.linuxfoundation.org</a></cite></p> <p>この内容を完璧にして、参考リンクまで知識を深めていけば、合格はそこまでむつかしくないのかなという印象です。</p> <h1 id="当日">当日</h1> <p>日本語対応とはいえ、問題文と試験官のチャットだけ日本語で、それ以外は全て英語でした。そこまでむつかしくはないのでなんとかはなりました。</p> <p>試験を受けるためにPSIのセキュアブラウザをインストールしないといけないのですが、自分のM1 <a class="keyword" href="http://d.hatena.ne.jp/keyword/MacBook%20Air">MacBook Air</a>だとVentureにアップグレードしたせいなのか、インストールを何回してもエラーになるという出来事がありました。仕方ないので、都合良く前日に初期化してたInterl <a class="keyword" href="http://d.hatena.ne.jp/keyword/MacBook%20Pro">MacBook Pro</a>(Monterey)に入れて事なきを得ました。</p> <p>また、普段使いのデスクが致命的に散らかってて、試験環境に向かなかったので、使ってない部屋の床に座って試験を受けてました。ただ、床座は腰に来るので次回からはやめようと思いました。</p> <p>受け終わった後の所感としては、細かい知識の詰めが甘くて、受かってるかどうか五分五分だなあという感じでした。基礎をちゃんと固めれば受かる試験ですが、なめてかかると普通に落ちるなあという感じですね。</p> <h1 id="結果">結果</h1> <p>試験後24時間で結果がメールで通知されます。スコアはト<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A1%BC%A5%CB%A5%F3">レーニン</a>グポータルのページを見に行かないと見れないです。</p> <p>なお、自分のスコアは85で微妙な感じです。アソシエイトレベルの試験なのでもう少し余裕を持った点数で受かりたかった気持ちはあります。次のCKAに向けて精進します。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masasuz/20221108/20221108092953.png" width="342" height="130" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> masasuz あとで調べる: Venturaにアップグレード後にxcrunが見つからないと言われる件、ところでxrunってなに hatenablog://entry/4207112889934669990 2022-11-08T08:31:08+09:00 2022-11-08T08:31:08+09:00 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を引くとこんな… <p>makeとかhomebrewで入れたツール類を実行しようとすると以下のエラーが出るようになった。</p> <pre class="code" data-lang="" data-unlink>xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun</pre> <p>対処方としては<a class="keyword" href="http://d.hatena.ne.jp/keyword/xcode">xcode</a>のcommand line toolsをインストールすれば良いのですが、</p> <pre class="code" data-lang="" data-unlink>xcode-select --install </pre> <p>ところでxcrunってなんですかね?manを引くとこんな感じ。</p> <p>複数の<a class="keyword" href="http://d.hatena.ne.jp/keyword/xcode">xcode</a>のツールチェーンをサポートするために<a class="keyword" href="http://d.hatena.ne.jp/keyword/Makefile">Makefile</a>などを変更せずにも、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%DE%A5%F3%A5%C9%A5%E9%A5%A4%A5%F3">コマンドライン</a>から<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D9%A5%ED%A5%C3%A5%D1">デベロッパ</a>ーツールを呼び出したり見つけたりする機能を提供する。らしい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/xcode">xcode</a>回りを雰囲気で使ってるのでこの辺よく分からないので、あとで深みにはまりたいところ。</p> <p>ビルド済みのコマンドとか実行するのに必要そうな感じは受けないのだが、どこでどう使われてるかも調べたいところ。</p> <pre class="code" data-lang="" data-unlink>XCRUN(1) BSD General Commands Manual XCRUN(1) NAME xcrun - Run or locate development tools and properties. SYNOPSIS xcrun [--sdk &lt;SDK name&gt;] --find &lt;tool name&gt; xcrun [--sdk &lt;SDK name&gt;] &lt;tool name&gt; ... tool arguments ... &lt;tool name&gt; ... 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.</pre> masasuz 未解決: Cloud Runのオートスケールする条件が分からなかった hatenablog://entry/4207112889933459559 2022-11-04T00:00:00+09:00 2022-11-04T00:00:02+09:00 Cloud Runのオートスケールする条件がいまいちよく分からなかったので、調べてました。 結論として、ちゃんとした条件が分からなかったので、時間が取れるときにちゃんと実験したいです。 確実なのは公式ドキュメントなので、関係のありそうな歌唱から読んでいきます。 コンテナ インスタンスの自動スケーリングについて | Cloud Run のドキュメント | Google Cloud Cloud Run では、リビジョンのスケーリングが自動的に行われます。すべての受信リクエストまたはイベントを処理できるように、必要なコンテナ インスタンスの数が調整されます。リビジョンがトラフィックを受信しない場合、… <p>Cloud Runのオートスケールする条件がいまいちよく分からなかったので、調べてました。</p> <p>結論として、ちゃんとした条件が分からなかったので、時間が取れるときにちゃんと実験したいです。</p> <p>確実なのは公式ドキュメントなので、関係のありそうな歌唱から読んでいきます。</p> <p><a href="https://cloud.google.com/run/docs/about-instance-autoscaling?hl=ja">コンテナ インスタンスの自動スケーリングについて  |  Cloud Run のドキュメント  |  Google Cloud</a></p> <blockquote><p>Cloud Run では、リビジョンのスケーリングが自動的に行われます。すべての受信リク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トまたはイベントを処理できるように、必要なコンテナ <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の数が調整されます。リビジョンが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%D5%A5%A3%A5%C3%A5%AF">トラフィック</a>を受信しない場合、デフォルトでは、コンテナ <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の数がゼロにスケールインされます。このデフォルトは必要に応じて変更できます。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>をアイドル状態のままにすることも、最小<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の設定を使用してウォームアップを指定することもできます。</p> <p>受信リク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トまたはイベントのレートに加えて、スケジュールされる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の数は以下の影響を受けます。</p> <ul> <li>リク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トまたはイベントを処理中の既存<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の CPU 使用率(スケジュールされた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>を CPU 使用率 60% に維持するためのターゲティング)</li> <li>最大同時実行数の設定</li> <li>コンテナ <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の最大数の設定</li> <li>コンテナ <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の最小数の設定</li> </ul> </blockquote> <p>ここでは、CPU使用率が60%を維持するようにつまり60%を超えるとスケールするように読み取れます。</p> <p><a href="https://cloud.google.com/run/docs/about-concurrency?hl=ja">インスタンスあたりの最大同時リクエスト数(サービス)  |  Cloud Run のドキュメント  |  Google Cloud</a></p> <blockquote><p>Cloud Run サービスでは、リビジョンのスケーリングが自動的に行われます。すべての受信リク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トを処理できるように、必要なコンテナ <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の数が調整されます。</p></blockquote> <p>ここでは、現在稼働してる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の合計最大同時実行数ではリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トを処理しきれなくなりそうになるとスケールするように読み取れます。</p> <p><a href="https://cloud.google.com/run/docs/resource-model?hl=ja">リソースモデル  |  Cloud Run のドキュメント  |  Google Cloud</a></p> <blockquote><p>リビジョンは、受信したすべてのリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トを処理できるように、コンテナ <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の数を自動的にスケーリングします。1 つのコンテナ <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>が同時に多くのリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トを受信する場合があります。同時実行の設定を使用すると、1 つのコンテナ <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>に同時に送信されるリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トの最大数を設定できます。</p></blockquote> <p>ここも同じこと言ってますね。</p> <p>まとめると、</p> <ul> <li>CPU60%を維持(超えない)ようにスケーリングする</li> <li>すべてのリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トを処理できるように(同時実行数を超えると)スケーリングする <ul> <li>ただし、最大<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>数の制限を超えてスケールすることはできない。</li> </ul> </li> </ul> <p>ということでいいんですかね?</p> <p>余談ですが、Cloud Runのオートスケーリングについて調べてたときに見つけたこの動画すごく参考になりました。オートスケーリングに関しては、何も得るものがなかったんですが、ログとリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トの紐付けとか運用上役に立つ知識が得られました。</p> <p><iframe width="560" height="315" src="https://www.youtube.com/embed/XiT55bMkJPs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="02-01 Cloud Ops で踏み出す Cloud Run 本番運用への第一歩"></iframe><cite class="hatena-citation"><a href="https://www.youtube.com/watch?v=XiT55bMkJPs">www.youtube.com</a></cite></p> masasuz 故障と障害の違いがわからずに困惑してた hatenablog://entry/4207112889931627539 2022-10-28T21:09:27+09:00 2022-10-28T21:09:27+09:00 ふと調査ごとをしてて故障と障害ってなんか違いあるんだっけ?と疑問に思い調べてました。 JIS X 0014:1999 情報処理用語-信頼性、保守性及び可用性 いったん、JIS X 0014:1999の定義を見てみることにします。 故障は要求された機能の能力がなくなること。できごとを表す感じですかね? 故障 要求された機能を遂行する,機能単位の能力がなくなること。 備考 この定義はJIS Z 8115 : 1981と同一であるが,JIS Z 8115 : 1981には更に幾つかの備考がある。 なるほど。障害は要求された機能が実行できない異常状態らしいです。 障害 要求された機能を遂行する機能単位… <p>ふと調査ごとをしてて故障と障害ってなんか違いあるんだっけ?と疑問に思い調べてました。</p> <h1 id="JIS-X-00141999-情報処理用語信頼性保守性及び可用性">JIS X 0014:1999 情報処理用語-信頼性、保守性及び可用性</h1> <p>いったん、JIS X 0014:1999の定義を見てみることにします。</p> <p>故障は要求された機能の能力がなくなること。できごとを表す感じですかね?</p> <pre class="code" data-lang="" data-unlink>故障 要求された機能を遂行する,機能単位の能力がなくなること。 備考 この定義はJIS Z 8115 : 1981と同一であるが,JIS Z 8115 : 1981には更に幾つかの備考がある。</pre> <p>なるほど。障害は要求された機能が実行できない異常状態らしいです。</p> <pre class="code" data-lang="" data-unlink>障害 要求された機能を遂行する機能単位の能力の,縮退又は喪失を引き起こす,異常な状態。 備考 JIS Z 8115 : 1981では,予防保守又は他の計画的な作業の間に発生する場合,及び外部資源の不足のために発生する場合を除いて,要求された機能を遂行できない状態を“フォールト”と定義している</pre> <p>ちょっとこれだけだとよくわからないので、言及されてるJIS Z 8115を見てみましょう。</p> <h1 id="JIS-Z-8115--2000-デイペンダビリティ信頼性用語">JIS Z 8115 : 2000 デイペンダビリティ(信頼性)用語</h1> <p>JIS Z 8115 : 1981が見つからないので今回はJIS Z 8115 : 2000を見ていきます。</p> <p>これも機能を失うこと。イベントですね。故障はイベント、フォールト(障害)は状態という区別らしいです。そしてそれらを厳密に区別しないこともある。</p> <pre class="code" data-lang="" data-unlink>故障 アイテムが要求機能達成能力を失うこと。 備考1. 一般に,アイテムは故障の後フォールトをもつ。 2.故障は,イベントであり,状態であるフォールトと区別される。 3.ソフトウェアを含むシステムは故障事象をもち,その要因はシステムを構成するハードウェア,ソフトウェア,及び人的要素等の個々の状態又はそれらの組み合わさった複合状態に起因した不具合及び故障によっても発生する。 4.システム故障は系全体の機能の喪失又は規定された機能水準を下回る,系の一時的機能低下,すなわち,系のサービス中断として用いる。 5.ソフトウェア故障という用語は,一般にシステム故障が発生したときの状態において使用される。 6.イベントと状態を厳密に区別しないで故障ということかある。参考 正しい理解と使用のために解説を参照する</pre> <p>障害にあたるフォールトを見てみると。1つ目は機能が実行できない状態。2つ目がちょっとわかりにくいですが、こちらも状態としてとっていいのかな。</p> <pre class="code" data-lang="" data-unlink>フォールト a)ある要求された機能を遂行不可能なアイテムの状態,また,その状態にあるアイテムの部分。 b)アイテムの要求機能遂行能力を失わせたり,要求機能遂行能力に支障を起こさせる原因(設計の状態)。ただし,予防保全又はその他の計画された活動にる場合,若しくは外部からの供給不良による場合は除く。 備考1. フォールトはアイテム自体の故障の結果であるが,先行ずる故障がなくても存在することがある。 2.故障発生の過程を原因−結果の連鎖とした場合,故障の原因をフォールトとみなすこともある。フォールトは,着目しているアイテムの下位のアイテムの故障である場合もあるが,アイテム自身に内包されている場合もある。 3.ソフトウェアアイテムの場合,コンピュータシステムではプログラム全体てのプログラミング,論理構成,プログラムプロセス,チータ定義などの間違いを意味する。 4.ソフトウェアフォールトはハードウェアの故障要因と区別するときに使用する場合がある。参考 正しい理解と使用のために解説を参照する</pre> <p>ところで、アイテムとは、</p> <pre class="code" data-lang="" data-unlink>アイテム ディペンダビリティの対象となる,部品,構成品,デバイス,装置,機能ユニット,機器,サブシステム,システムなどの総称又はいずれか。 備考1. アイテムは,ハードウェア,ソフトウェア,又は両方から構成される。さらに,特別な場合は,人間も含む。 2.複数のアイテム,例えば,アイテムの母集団及びサンプルは,それ自身アイテムとして考えることができる。 3.ソフトウェアアイテムとして用いる場合は,例えば,ソースコード,オブジェクトコード,ジョブ制御言語.関連文書類又はこれらの集合体を指す(SW1 参照)。 参考 IEC 60050 (191) の対応英語 entity は除いてある(解説を参照)。</pre> <h1 id="ISTQB-用語集">ISTQB 用語集</h1> <p>昔、JATQBの試験を受けたときにこの辺の単語見た気がしたので改めて用語集を見てみます。</p> <p><a href="https://glossary.istqb.org/jp/search/failure">ISTQB Glossary failure</a></p> <p>日本語だと状態を表してるように読み取れますが、原文だとEventになってます。JISでいうところの故障と同じような概念を指してるように見えます。</p> <pre class="code" data-lang="" data-unlink>故障(failure) コンポーネントやシステムが定義された範囲内で要求する機能を実行しないこと。</pre> <pre class="code" data-lang="" data-unlink>An event in which a component or system does not perform a required function within specified limits.</pre> <p><a href="https://glossary.istqb.org/jp/search/fault">ISTQB Glossary fault</a></p> <p>フォールトそのものは載ってないのですが、Synonymとしてdefectがありました。ただ、JISでいうところのフォールトとは違う意味のように取れます。うーむ?</p> <pre class="code" data-lang="" data-unlink>欠陥(defect) 作業成果物に存在する、要件または仕様を満たさない不備または欠点。 Synonyms: バグ(bug), フォールト(fault), 問題(problem)</pre> <pre class="code" data-lang="" data-unlink>An imperfection or deficiency in a work product where it does not meet its requirements or specifications.</pre> <h1 id="結果">結果</h1> <p>余計困惑しました。</p> <p>アイテムが故障した結果、フォールト(障害)の状態になるというのが基本的な理解で、ただ、故障とフォールトは厳密に区別せずに使われることもある。そういう理解で良いのでしょうか?</p> masasuz GitHub Actionsで `save-state` と`set-output` が廃止されるようです。 hatenablog://entry/4207112889930126490 2022-10-23T19:06:02+09:00 2022-10-23T19:06:02+09:00 ふとGitHub Actionsを実行ログを眺めてたら、下記のwarningsがでてることに気づきました。 The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ なんだろと思い… <p>ふと<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a> Actionsを実行ログを眺めてたら、下記のwarningsがでてることに気づきました。</p> <pre class="code" data-lang="" data-unlink>The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/</pre> <p>なんだろと思いつつ、示されてた参考リンクを見ると <code>set-output</code> が使えなくなる模様。</p> <ul> <li><a href="https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/">GitHub Actions: Deprecating save-state and set-output commands | GitHub Changelog</a></li> </ul> <p>10月11日にリリースしたrunner version 2.298.2からこのwarningsがでるようになってて、2023年6月1日からsave-stateまたはset-outputを使うと失敗するようになるので、それ以降使えないとのこと。</p> <p>それまでに対応する必要がありそう。</p> <p>リンクの例に書かれてますが、今回使えなくなる <code>set-output</code> と <code>save-state</code> の形式がこれで、</p> <pre class="code" data-lang="" data-unlink>- name: Save state run: echo &#34;::save-state name={name}::{value}&#34; - name: Set output run: echo &#34;::set-output name={name}::{value}&#34;</pre> <p>今後は、こっちのように指定のファイルに出力するように対応すれば良い。</p> <pre class="code" data-lang="" data-unlink>- name: Save state run: echo &#34;{name}={value}&#34; &gt;&gt; $GITHUB_STATE - name: Set output run: echo &#34;{name}={value}&#34; &gt;&gt; $GITHUB_OUTPUT</pre> <p>しかし、10月11日からwarningsでてたはずなのに気づいてなかった。。。</p> masasuz はてなブログのカテゴリごとのRSSフィード hatenablog://entry/4207112889929851482 2022-10-22T21:53:07+09:00 2022-10-22T21:53:07+09:00 こんな形式のURLになってます。 https://${domain}/rss/category/${category} https://${domain}/feed/category/${category} うちのでいうとこんな感じですね。 https://diary.masasuzu.net/rss/category/tech https://diary.masasuzu.net/feed/category/tech このブログわりかし技術系以外の内容が含まれてるので、技術系のカテゴリだけslackに流したいなと思って、特定カテゴリだけのRSSフィードがないか探してました。 これで良い感じに… <p>こんな形式のURLになってます。</p> <pre class="code" data-lang="" data-unlink>https://${domain}/rss/category/${category} https://${domain}/feed/category/${category}</pre> <p>うちのでいうとこんな感じですね。</p> <ul> <li><a href="https://diary.masasuzu.net/rss/category/tech">https://diary.masasuzu.net/rss/category/tech</a></li> <li><a href="https://diary.masasuzu.net/feed/category/tech">https://diary.masasuzu.net/feed/category/tech</a></li> </ul> <p>このブログわりかし技術系以外の内容が含まれてるので、技術系のカテゴリだけslackに流したいなと思って、特定カテゴリだけの<a class="keyword" href="http://d.hatena.ne.jp/keyword/RSS%A5%D5%A5%A3%A1%BC%A5%C9">RSSフィード</a>がないか探してました。</p> <p>これで良い感じにできそう。</p> masasuz 未解決: Google Cloud Storageの静的配信でnginxで言うところのtry_files的なことをしたかった。。。。 hatenablog://entry/4207112889929845655 2022-10-22T21:34:02+09:00 2022-10-22T21:34:02+09:00 結論から言うと、ページとしては想定のものが返ってきてるが、status code 404が返るようになってうまくいってないです。 nginxだと下記の様に設定すると、指定されたファイルを探して見つからなかったら/index.htmlを返す(それもなかったら404を返す)。ということをしてくれます。 try_files $uri /index.html =404; シングルページアプリとかだと返して欲しいhtmlはindex.htmlだけど、パスに応じて挙動を変えるみたいなことをしてると思います。これに対応するために上記の設定をしています。 もともとNginxをCloudRunで動かして、これを… <p>結論から言うと、ページとしては想定のものが返ってきてるが、status code 404が返るようになってうまくいってないです。</p> <p>nginxだと下記の様に設定すると、指定されたファイルを探して見つからなかったら/index.htmlを返す(それもなかったら404を返す)。ということをしてくれます。</p> <pre class="code" data-lang="" data-unlink>try_files $uri /index.html =404;</pre> <p>シングルページアプリとかだと返して欲しいhtmlはindex.htmlだけど、パスに応じて挙動を変えるみたいなことをしてると思います。これに対応するために上記の設定をしています。</p> <p>もともとNginxをCloudRunで動かして、これをやっていたのですが、どうせ静的配信しかしないならCloud Storageでいいのでは?となって移行しようとしています。</p> <p>これと同等のことCloud Storageでやるには、NotFoundPage = index.htmlを指定するとよさそうです。terraformで書くとこんな感じになります。</p> <pre class="code" data-lang="" data-unlink>resource &#34;google_storage_bucket&#34; &#34;website&#34; { name = &#34;${local.name}-site&#34; location = &#34;ASIA1&#34; storage_class = &#34;MULTI_REGIONAL&#34; website { main_page_suffix = &#34;index.html&#34; not_found_page = &#34;index.html&#34; }</pre> <p>ページの表示としてはうまくいったのですが、status codeが404で返ってきてしまいます。これをうまく200で返す手段がCloud Storageとロードバランサの組み合わせでは見つかりませんでした。</p> <p>CloudFunctionsでうまくごにょごにょすれば良いかもですが、だったらCloud RunでNginxをサーブする方がシンプルにできそうで良いのでは?と言う気持ちになってます。なにかシンプルなうまい方法ないですかね?</p> <p>参考:</p> <ul> <li><a href="https://cloud.google.com/storage/docs/static-website?hl=ja#error-page">静的ウェブサイトの例とヒントのエラーページのところ</a></li> <li><a href="https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#nested_website">google_storage_bucketのwebsiteのところ</a></li> </ul> masasuz Google Cloudの外部HTTP(S)ロードバランサと外部HTTP(S)ロードバランサ(従来型)の違いがわからなかった。 hatenablog://entry/4207112889929495438 2022-10-21T19:01:11+09:00 2022-10-21T19:01:11+09:00 外部HTTP(S)ロードバランサには無印と従来型の2つがあります。この辺まとめてるのが日本語では見つからなかったので、ざっくりとドキュメントからかいつまんでみました。 従来型を使いたい特別な理由がない限りは無印を使うとよいのかなとます 無印 従来型 特徴(作成時のツールチップより引用) 複数のリージョンにグローバルに分散されたユーザーまたはバックエンド サービスを持つ外部 HTTP(S) ワークロード向けに推奨されるロードバランサです。このロードバランサは、従来の HTTP(S) ロードバランサよりも多くの機能がある、高度なトラフィック管理機能を備えているため、トラフィックの処理方法をきめ細か… <p>外部HTTP(S)ロードバランサには無印と従来型の2つがあります。この辺まとめてるのが日本語では見つからなかったので、ざっくりとドキュメントからかいつまんでみました。</p> <p>従来型を使いたい特別な理由がない限りは無印を使うとよいのかなとます</p> <table> <thead> <tr> <th> </th> <th> 無印 </th> <th> 従来型 </th> </tr> </thead> <tbody> <tr> <td> 特徴(作成時の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB%A5%C1%A5%C3%A5%D7">ツールチップ</a>より引用) </td> <td> 複数のリージョンにグローバルに分散されたユーザーまたはバックエンド サービスを持つ外部 HTTP(S) ワークロード向けに推奨されるロードバランサです。このロードバランサは、従来の HTTP(S) ロードバランサよりも多くの機能がある、高度な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%D5%A5%A3%A5%C3%A5%AF">トラフィック</a>管理機能を備えているため、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%D5%A5%A3%A5%C3%A5%AF">トラフィック</a>の処理方法をきめ細かく制御できます </td> <td> 従来のグローバル <a class="keyword" href="http://d.hatena.ne.jp/keyword/HTTPS">HTTPS</a> ロードバランサは、グローバル <a class="keyword" href="http://d.hatena.ne.jp/keyword/HTTPS">HTTPS</a> ロードバランサの以前のバージョンであり、高度な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%D5%A5%A3%A5%C3%A5%AF">トラフィック</a>管理などの機能をサポートしていません </td> </tr> <tr> <td> ネットワークティア </td> <td> プレミアムティア </td> <td> スタンダードティア、プレミアムティア </td> </tr> <tr> <td> GKE互換 </td> <td> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%BF%A5%F3%A5%C9%A5%A2%A5%ED%A5%F3">スタンドアロン</a>NEG </td> <td> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ingress">Ingress</a>または<a class="keyword" href="http://d.hatena.ne.jp/keyword/Gateway">Gateway</a> </td> </tr> <tr> <td> Cloud Armor </td> <td> <a class="keyword" href="http://d.hatena.ne.jp/keyword/bot">bot</a>管理を除く </td> <td> <a class="keyword" href="http://d.hatena.ne.jp/keyword/bot">bot</a>管理を含む </td> </tr> <tr> <td> セッションアフィニティのオプション </td> <td> </td> <td> ヘッダーフィールドとHTTP Clookie未対応 </td> </tr> <tr> <td> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A1%BC%A5%C9%A5%D0%A5%E9%A5%F3%A5%B5%A1%BC">ロードバランサー</a>スキーム </td> <td> EXTERNAL_MANAGED </td> <td> EXTERNAL </td> </tr> <tr> <td> その他 </td> <td> Envoyプロキシを使用した<a href="https://cloud.google.com/load-balancing/docs/https/traffic-management-regional?hl=ja">高度なトラフィック管理</a> </td> <td> </td> </tr> </tbody> </table> <p>あとの細かいことはドキュメントを見てください。</p> <ul> <li><a href="https://cloud.google.com/load-balancing/docs/https?hl=ja">外部 HTTP(S) 負荷分散の概要 | Google Cloud</a></li> <li><a href="https://cloud.google.com/load-balancing/docs/https/migrate-to-global?hl=ja">グローバル外部 HTTP(S) ロードバランサへの移行を計画する | 負荷分散 | Google Cloud</a></li> <li><a href="https://cloud.google.com/load-balancing/docs/features">ロードバランサの機能比較 | 負荷分散 | Google Cloud</a></li> </ul> masasuz Google Cloud認定 Professional Cloud Architect合格してた hatenablog://entry/4207112889929090790 2022-10-20T09:02:06+09:00 2022-10-20T10:27:00+09:00 10/27の午前中にGoogle CloudのProfessional Cloud Architectを受けてきました。 PCA受かってたっぽい。見間違え出なければ合格と表示されてたので、たぶんそう。手応えがなさすぎて実感はないです。— masasuzu (@masasuz) 2022年10月17日 Professional Cloud Architect • 勝史 鈴木 • Google Cloud スッと試験終了後の画面に合格と表示されてたのでホントに受かってるのか不安でしたが、メールでの通知もあったし、Accredibleにも登録されてるので、これは間違いなく合格してるでしょう。 時間の… <p>10/27の午前中に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> Cloudの<a href="https://cloud.google.com/certification/cloud-architect?hl=ja">Professional Cloud Architect</a>を受けてきました。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">PCA受かってたっぽい。<br>見間違え出なければ合格と表示されてたので、たぶんそう。<br>手応えがなさすぎて実感はないです。</p>&mdash; masasuzu (@masasuz) <a href="https://twitter.com/masasuz/status/1581821416038887425?ref_src=twsrc%5Etfw">2022年10月17日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p><a href="https://www.credential.net/eb92567a-25ea-426c-8c68-37dc9b830fd4">Professional Cloud Architect &bull; &#x52DD;&#x53F2; &#x9234;&#x6728; &bull; Google Cloud</a></p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masasuz/20221020/20221020085439.png" width="479" height="372" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>スッと試験終了後の画面に合格と表示されてたのでホントに受かってるのか不安でしたが、メールでの通知もあったし、Accredibleにも登録されてるので、これは間違いなく合格してるでしょう。</p> <p>時間の関係上、実質5日間しか勉強してなく、詰め込みでやったのであんまり達成感ないです。<a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>と違ってスコアでないのもどれくらい理解度が進んでたのかが分からないのが難点ですね。</p> <p><a href="https://cloud.google.com/certification/cloud-developer?hl=ja">Professional Cloud Developer</a>を今年中に受ける予定なので、こっちはちゃんと身になるように勉強していきたいです。</p> masasuz t3系インスタンスのスペックについて hatenablog://entry/4207112889929088821 2022-10-20T08:51:14+09:00 2022-10-20T08:51:14+09:00 特にオチはないメモです。 インスタンスタイプ - Amazon EC2 | AWS 基本的にはメモリとCPUクレジットが1サイズ上げると倍になっていく。vCPU数はt3.largeまでは2でそれ以降倍になっていく。 ちょっとした作業スペースとして使うならメモリ0.5GiBのt3.nanoで十分。簡単なwebアプリとか動かすならメモリ2GiBのt3.smallで余裕。 そもそも2vCPUしかないのでCPUを使ったバリバリとして並列処理には向かない <p>特にオチはないメモです。</p> <p><a href="https://aws.amazon.com/jp/ec2/instance-types/">インスタンスタイプ - Amazon EC2 | AWS</a></p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masasuz/20221020/20221020084618.png" width="845" height="343" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>基本的にはメモリとCPUクレジットが1サイズ上げると倍になっていく。vCPU数はt3.largeまでは2でそれ以降倍になっていく。</p> <p>ちょっとした作業スペースとして使うならメモリ0.5GiBのt3.nanoで十分。簡単なwebアプリとか動かすならメモリ2GiBのt3.smallで余裕。</p> <p>そもそも2vCPUしかないのでCPUを使ったバリバリとして並列処理には向かない</p> masasuz build-in commandのmanが引けなくて困った hatenablog://entry/4207112889928318616 2022-10-17T15:35:16+09:00 2022-10-17T15:38:48+09:00 zshの話です。 historyコマンドのmanpageを引きたくて以下のようにコマンドを打ったところ、 man history builtinのmanpageが表示されて、そうじゃないんだよなあ。。。ってなってました。 See the built-in command description in the appropriate shell manual page. 言われても。。。。 BUILTIN(1) General Commands Manual BUILTIN(1) NAME builtin, !, %, ., :, @, [, {, }, alias, alloc, bg, bi… <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/zsh">zsh</a>の話です。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/history">history</a>コマンドのmanpageを引きたくて以下のようにコマンドを打ったところ、</p> <pre class="code" data-lang="" data-unlink>man history</pre> <p>builtinのmanpageが表示されて、そうじゃないんだよなあ。。。ってなってました。 <code>See the built-in command description in the appropriate shell manual page.</code> 言われても。。。。</p> <pre class="code" data-lang="" data-unlink>BUILTIN(1) General Commands Manual BUILTIN(1) NAME builtin, !, %, ., :, @, [, {, }, alias, alloc, bg, bind, bindkey, break, breaksw, builtins, case, cd, chdir, command, complete, continue, default, dirs, do, done, echo, echotc, elif, else, end, endif, endsw, esac, eval, exec, exit, export, false, fc, fg, filetest, fi, for, foreach, getopts, glob, goto, hash, hashstat, history, hup, if, jobid, jobs, kill, limit, local, log, login, logout, ls-F, nice, nohup, notify, onintr, popd, printenv, printf, pushd, pwd, read, readonly, rehash, repeat, return, sched, set, setenv, settc, setty, setvar, shift, source, stop, suspend, switch, telltc, test, then, time, times, trap, true, type, ulimit, umask, unalias, uncomplete, unhash, unlimit, unset, unsetenv, until, wait, where, which, while – shell built-in commands SYNOPSIS See the built-in command description in the appropriate shell manual page.</pre> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/zsh">zsh</a>でbuilt-in commandsを調べたいときは以下のようにするのが正しいです。</p> <pre class="code" data-lang="" data-unlink>man zshbuiltins</pre> <p>ちなみに <code>fc -l</code> と <code>history</code> は同じだそうです。</p> <pre class="code" data-lang="" data-unlink> history Same as fc -l. </pre> masasuz S3にオブジェクトをputしてもEventBridgeにイベントが飛ばないときは hatenablog://entry/4207112889920986580 2022-09-23T18:42:32+09:00 2022-09-23T18:42:32+09:00 S3バケットの設定でEventBridgeにイベントを通知する設定が有効になってるか確認しような。。。。。 これをやるのを忘れてて、なんでイベント飛ばないんだ!!!!!とはまってました。 EventBridge完全理解した— masasuzu (@masasuz) 2022年9月23日 <p>S3<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%B1%A5%C3%A5%C8">バケット</a>の設定でEventBridgeにイベントを通知する設定が有効になってるか確認しような。。。。。</p> <p>これをやるのを忘れてて、なんでイベント飛ばないんだ!!!!!とはまってました。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">EventBridge完全理解した</p>&mdash; masasuzu (@masasuz) <a href="https://twitter.com/masasuz/status/1573212073483386881?ref_src=twsrc%5Etfw">2022年9月23日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> masasuz 今日もまたVSCodeのタイムラインに救われてしまった hatenablog://entry/4207112889920213755 2022-09-21T15:58:56+09:00 2022-09-21T15:58:56+09:00 VSCodeにはタイムラインという履歴管理機能?があってこれが便利。gitの履歴とは別にファイルの変更履歴を取っていて、うっかりcommit せずに消してしまった箇所を復活させたりするのに役立ちます。 デフォルトだと左下あたりにこっそりいるはず。 タイムラインの表示はこんな感じ。ここで変更を選択するとdiff形式でエディター画面に表示されます。 今日もタイムラインに救われました <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>にはタイムラインという履歴管理機能?があってこれが便利。gitの履歴とは別にファイルの変更履歴を取っていて、うっかりcommit せずに消してしまった箇所を復活させたりするのに役立ちます。</p> <p>デフォルトだと左下あたりにこっそりいるはず。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masasuz/20220921/20220921155400.png" alt="" width="265" height="142" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>タイムラインの表示はこんな感じ。ここで変更を選択するとdiff形式でエディター画面に表示されます。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masasuz/20220921/20220921155239.png" width="414" height="858" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masasuz/20220921/20220921155711.png" alt="" width="1200" height="477" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>今日もタイムラインに救われました</p> masasuz terraformでCloudSQLのインスタンス作成に失敗した hatenablog://entry/4207112889920207833 2022-09-21T15:38:38+09:00 2022-09-21T15:38:38+09:00 こんなエラーが出てインスタンス作成に失敗した。 ╷ │ Error: Error, failed to create instance because the network doesn't have at least 1 private services connection. Please see https://cloud.google.com/sql/docs/mysql/private-ip#network_requirements for how to create this connection. │ │ with google_sql_database_instance.pri… <p>こんなエラーが出て<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>作成に失敗した。</p> <pre class="code" data-lang="" data-unlink>╷ │ Error: Error, failed to create instance because the network doesn&#39;t have at least 1 private services connection. Please see https://cloud.google.com/sql/docs/mysql/private-ip#network_requirements for how to create this connection. │ │ with google_sql_database_instance.primary, │ on database.tf line 1, in resource &#34;google_sql_database_instance&#34; &#34;primary&#34;: │ 1: resource &#34;google_sql_database_instance&#34; &#34;primary&#34; { │ ╵</pre> <p>terraformのコードとしてはこれ。原因としては、private_networkの指定が間違っていた。</p> <pre class="code" data-lang="" data-unlink>resource &#34;google_sql_database_instance&#34; &#34;primary&#34; { name = var.database.primary.name project = var.project_id region = var.database.primary.location database_version = var.database.primary.version settings { tier = var.database.primary.tier availability_type = var.database.primary.availability_type disk_size = var.database.primary.disk_size ip_configuration { ipv4_enabled = false private_network = var.database.private_network # &lt;= これ } backup_configuration { enabled = true binary_log_enabled = true } } deletion_protection = &#34;true&#34; }</pre> <p>エラーメッセージにネットワーク名が出てればすぐ原因にたどり着けたのに。。。無駄な時間をかけてしまった。</p> masasuz アプリケーションをメンテナンスモードにする方法について考えるメモ hatenablog://entry/13574176438066974618 2022-02-25T12:21:10+09:00 2022-02-25T12:36:42+09:00 前提 AWS上に構築されたwebサービス 構成要素 ALB ECS上でうごいているアプリケーション CloudWatch Eventのcronで起動するECSスケジュールタスク RDSなどのデータストア 現状 terrafromのmaintainance_mode変数を見てtrueであれば、ALBで503を返すようにして、スケジュールタスクを止めるように記述している。 問題 メンテナンス入れるたびにterrafrom applyをする必要がある 管理リソースが多いためterraform applyに時間がかかり、時間通りにメンテナンスの開始終了ができない 案 インフラ側で制御する Lambda… <h1>前提</h1> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>上に構築された<a class="keyword" href="http://d.hatena.ne.jp/keyword/web%A5%B5%A1%BC%A5%D3%A5%B9">webサービス</a></p> <h1>構成要素</h1> <ul> <li>ALB</li> <li>ECS上でうごいているアプリケーション</li> <li>CloudWatch Eventのcronで起動するECSスケジュールタスク</li> <li>RDSなどのデータストア</li> </ul> <h1>現状</h1> <p>terrafromのmaintainance_mode変数を見てtrueであれば、ALBで503を返すようにして、スケジュールタスクを止めるように記述している。</p> <h1>問題</h1> <ul> <li>メンテナンス入れるたびにterrafrom applyをする必要がある</li> <li>管理リソースが多いためterraform applyに時間がかかり、時間通りにメンテナンスの開始終了ができない</li> </ul> <h1>案</h1> <h2>インフラ側で制御する</h2> <h3>Lambdaで<a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>リソースの設定変更を行う</h3> <ul> <li>既存のやり方と同じ、設定方法がLambdaに変わっただけ</li> <li>terrafromのstateに一時的に差分ができてしまう。 <ul> <li>メンテナンス中に<a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>リソースの変更がしにくい</li> </ul> </li> <li>既存の方法と同じ</li> </ul> <h2>アプリケーション側で制御する</h2> <h3>データベースの値を参照する</h3> <ul> <li>DB(もしくはRedis等)に入っている値を参照してメンテナンスモードを切り替える</li> <li>DBの値を参照するので即時でメンテナンスに入れることができる</li> <li>メンテナンス時にRDSやElastiCacheを変更する際バッティングしてしまう</li> </ul> <h3>設定ファイルの値を参照する</h3> <ul> <li>設定ファイルにメンテナンス時間を記述しておき、アプリケーションはその値を参照してメンテナンスであるかを判断する</li> <li>メンテナンス開始の明示的な設定変更が不要であらかじめ設定しておける。</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%CE%A5%EA%A5%B9">モノリス</a>なら問題がないが、複数サービス存在する場合は複数箇所に設定を入れる必要がある <ul> <li>次善策としてS3に設定を置いておき、それを参照することで設定値は1つにできる。</li> </ul> </li> </ul> <h3>メンテナンスサービスの値を参照する</h3> <ul> <li>現在メンテナンス中なのかどうかを返す<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>サービスを作る <ul> <li>設定は直書きでも、S3上のファイルでも良い</li> <li>Parameter Storeでもいいか</li> </ul> </li> <li>メンテナンスサービスがキャッシュ、プロキシ的に動くので設定が書かれてる<a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>リソースへのリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>ト回数を減らすことができる</li> <li>アプリケーションはメンテナンスサービスが返す値をもとにメンテナンスかどうかを判断する。</li> </ul> <h3>直接S3やParameterStoreを参照すればいいのでは?</h3> <ul> <li>メンテナンスサービスを設置せずに、各アプリケーションが直接設定が書いてあるリソースにアクセスする</li> <li>リク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>ト回数が極端に多くなければこれでも</li> </ul> <h1>まとまらない</h1> <p>1つの方法が良いというわけではなく、メンテナンス箇所がインフラなのかアプリなのかによって方法を組み合わせなければいけないこともあると思います。ECS サービスの変更であれば、アプリケーションのECSタスクが死んでしまうのでアプリをメンテナンスモードにしても無駄だったりします。そういう場合はインフラ側でメンテに入れる必要があったりします。</p> <p>適材適所でいいのではないでしょうか?</p> <p>全然他社事例を調べずに書いてるので、他になにかいい方法があったら追記します。</p> masasuz EventBridgeのEventPatternで除外条件をつけたいとき hatenablog://entry/13574176438064545426 2022-02-17T23:24:06+09:00 2022-02-17T23:24:06+09:00 diary.masasuzu.net EventBridgeでECS Taskの終了ステータスが0以外のとき、つまり異常終了したときのイベントを拾うためにrange関数を使いました。 resource "aws_cloudwatch_event_rule" "main" { name = local.name event_pattern = jsonencode( { "detail-type" : [ "ECS Task State Change" ], "source" : [ "aws.ecs" ], "detail" : { "containers" : { "exitCode" : … <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdiary.masasuzu.net%2Fentry%2F2022%2F02%2F17%2F181640" title="terrafromでrange関数使いたい - ふり返る暇なんて無いね" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://diary.masasuzu.net/entry/2022/02/17/181640">diary.masasuzu.net</a></cite></p> <p>EventBridgeでECS Taskの終了ステータスが0以外のとき、つまり異常終了したときのイベントを拾うためにrange関数を使いました。</p> <pre class="code lang-hcl" data-lang="hcl" data-unlink><span class="synType">resource</span> <span class="synConstant">&quot;aws_cloudwatch_event_rule&quot;</span> <span class="synConstant">&quot;main&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">name</span> = local.name <span class="synIdentifier">event_pattern</span> = <span class="synIdentifier">jsonencode</span>( <span class="synSpecial">{</span> <span class="synConstant">&quot;detail-type&quot;</span> : <span class="synSpecial">[</span> <span class="synConstant">&quot;ECS Task State Change&quot;</span> <span class="synSpecial">]</span>, <span class="synConstant">&quot;source&quot;</span> : <span class="synSpecial">[</span> <span class="synConstant">&quot;aws.ecs&quot;</span> <span class="synSpecial">]</span>, <span class="synConstant">&quot;detail&quot;</span> : <span class="synSpecial">{</span> <span class="synConstant">&quot;containers&quot;</span> : <span class="synSpecial">{</span> <span class="synConstant">&quot;exitCode&quot;</span> : <span class="synIdentifier">range</span>(<span class="synConstant">1</span>, <span class="synConstant">256</span>), <span class="synConstant">&quot;lastStatus&quot;</span> : <span class="synSpecial">[</span> <span class="synConstant">&quot;STOPPED&quot;</span> <span class="synSpecial">]</span> <span class="synSpecial">}</span> <span class="synSpecial">}</span> <span class="synSpecial">}</span> ) } </pre> <p>が、よくよくドキュメントを見ると <code>“anything-but”</code> という比較<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>があるので、これを使えば素直に意図を表すことができそうです。</p> <ul> <li><a href="https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-event-patterns.html">Amazon EventBridge のイベントパターン - Amazon EventBridge</a></li> </ul> <pre class="code lang-hcl" data-lang="hcl" data-unlink><span class="synType">resource</span> <span class="synConstant">&quot;aws_cloudwatch_event_rule&quot;</span> <span class="synConstant">&quot;main&quot;</span> <span class="synSpecial">{</span> <span class="synIdentifier">name</span> = local.name <span class="synIdentifier">event_pattern</span> = <span class="synIdentifier">jsonencode</span>( <span class="synSpecial">{</span> <span class="synConstant">&quot;detail-type&quot;</span> : <span class="synSpecial">[</span> <span class="synConstant">&quot;ECS Task State Change&quot;</span> <span class="synSpecial">]</span>, <span class="synConstant">&quot;source&quot;</span> : <span class="synSpecial">[</span> <span class="synConstant">&quot;aws.ecs&quot;</span> <span class="synSpecial">]</span>, <span class="synConstant">&quot;detail&quot;</span> : <span class="synSpecial">{</span> <span class="synConstant">&quot;containers&quot;</span> : <span class="synSpecial">{</span> <span class="synConstant">&quot;exitCode&quot;</span> : <span class="synSpecial">[</span> <span class="synSpecial">{</span> <span class="synConstant">&quot;anything-but&quot;</span> : <span class="synSpecial">[</span><span class="synConstant">0</span><span class="synSpecial">]</span> <span class="synSpecial">}</span> <span class="synSpecial">]</span>, <span class="synConstant">&quot;lastStatus&quot;</span> : <span class="synSpecial">[</span> <span class="synConstant">&quot;STOPPED&quot;</span> <span class="synSpecial">]</span> <span class="synSpecial">}</span> <span class="synSpecial">}</span> <span class="synSpecial">}</span> ) } </pre> <p>スッキリとした解法を見つけたのでこれで安眠できますね。</p> masasuz terrafromでrange関数使いたい hatenablog://entry/13574176438064415156 2022-02-17T18:16:40+09:00 2022-02-17T18:18:33+09:00 Answer: 使えます range - Functions - Configuration Language | Terraform by HashiCorp 諸事情でECS Taskが失敗したとき、すなわち終了ステータスが1から255の条件のとき、のCloudWatch Event Ruleを書きたかったのですが、ベタに1から255のリスト書くのはつらすぎるので、range関数もしくは範囲記法ないかなあとググったらすぐ見つかりました。ありがたくrange(1, 256) を使わせていただきます。 というか、このルール自体いけてないのはわかってるんですけどね。。。。 <p>Answer: 使えます</p> <ul> <li><a href="https://www.terraform.io/language/functions/range">range - Functions - Configuration Language | Terraform by HashiCorp</a></li> </ul> <p>諸事情でECS Taskが失敗したとき、すなわち終了ステータスが1から255の条件のとき、のCloudWatch Event Ruleを書きたかったのですが、ベタに1から255のリスト書くのはつらすぎるので、range関数もしくは範囲記法ないかなあとググったらすぐ見つかりました。ありがたく<code>range(1, 256)</code> を使わせていただきます。</p> <p>というか、このルール自体いけてないのはわかってるんですけどね。。。。</p> masasuz インフラリソースとログのライフサイクルの違い hatenablog://entry/13574176438062171151 2022-02-11T09:46:48+09:00 2022-02-17T15:12:10+09:00 terraformとかでインフラリソースとログリソース(S3バケットとかCloudWatch log groupとか)を一緒のモジュールで管理することはよくあると思う。 一緒にすることのメリットとしては不要になったときに一気に消せることなのだが、逆にそれがデメリットでもある。ログに関してはインフラ自体がなくなっても、一定期間残したいという要件があるかもしれない。そのときにまあまあ困る。 対処作としては 最初からログとインフラを分けてモジュールを作る インフラを消すとき、モジュールからログだけ残して、インフラを消す となると思うけど、どっちもすっきりしないな。仕方ないけど。 これ以外にもライフサ… <p>terraformとかでイン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%E9%A5%EA">フラリ</a>ソースとログリソース(S3<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%B1%A5%C3%A5%C8">バケット</a>とかCloudWatch log groupとか)を一緒のモジュールで管理することはよくあると思う。</p> <p>一緒にすることのメリットとしては不要になったときに一気に消せることなのだが、逆にそれがデメリットでもある。ログに関してはインフラ自体がなくなっても、一定期間残したいという要件があるかもしれない。そのときにまあまあ困る。</p> <p>対処作としては</p> <ul> <li>最初からログとインフラを分けてモジュールを作る</li> <li>インフラを消すとき、モジュールからログだけ残して、インフラを消す</li> </ul> <p>となると思うけど、どっちもすっきりしないな。仕方ないけど。</p> <p>これ以外にもライフサイクルの違うものを管理するときどうすればいいのか。もうちょっと悩みたい。</p> <p>結論はまだない。</p> masasuz