CloudFormationで作成するサービスにタグを複数つけるには2パターンある

すごく地味な記事なります。
CloudFormationで作成するサービスにタグを複数つけるには2パターンの記述方法があることが分かりました。

1、記述パターン

パターン①
      Tags:
        - Key: Test1
          Value: "111"
        - Key: Test2
          Value: "222"


パターン②
      Tags:
        Test1: "111"
        Test2: "222"


2、記述方法の切り分け方

AWS公式サイトを見る。

EC2のインスタンス:「"Tags" : [ Tag, ... ],」

⇒これはパターン①でOK

docs.aws.amazon.com

AWS Systems Manager パラメータストア:「Key: Value」

⇒これはパターン②でOK

docs.aws.amazon.com


3、エラーの例

AWS Systems Manager パラメータストアにパターン①で記述すると、以下のエラーとなりました。

エラーメッセージ
Properties validation failed for resource SSMParameter2 with message: [#/Tags: expected type: JSONObject, found: JSONArray]


AWS Systems Manager パラメータストアにタグを複数つける正しい記述方法

以下のように「Key: Value」の形式で複数記述する

AWSTemplateFormatVersion: "2010-09-09"
Description: "Parameter Store"

Resources:

  SSMParameter1:
    Type: "AWS::SSM::Parameter"
    Properties:
      Name: "/cmn/envname"
      Type: "String"
      Value: "prd"
      DataType: "text"
      Description: "環境名"
      Tier: "Standard"
      Tags:
        Env: "prd"
        Test1: "111"
        Test2: "222"


AWS公式サイトをちゃんと参照すればわかるのですが、私はエラーが解決するまで時間がかかってしましました。

azd init で「ERROR: environment already initialized to XXX」エラーの対応方法

Azure OpenAI Serviceのハンズオンで発生したエラーと対処方法になります。
以下のgitからファイルを取得しデプロイすれば、社内文書検索が簡単に作成できます。
jp-azureopenai-samples/5.internal-document-search at main · Azure-Samples/jp-azureopenai-samples · GitHub

1、初期化済エラー

エラーメッセージ
ERROR: environment already initialized to xxxx

xxxxは作成済の環境名になります。

原因

既に「azd init 」した環境で「azd init 」コマンドを実行した。
ごちゃごちゃしてきたので、初期化しようと思ったのですが。。

対応方法

「.azure」配下のフォルダ及びファイルを全て削除する。
「C:\src\ai\5.internal-document-search.azure」にソースがある場合は
「C:\src\ai\5.internal-document-search.azure.azure」配下を全て削除する

「ai-rag」、「ai-rag2」・・・のフォルダは作った環境ごとに作成されます。
以下のコマンド新しい環境を作成できます。

azd env new 環境名

環境が多くなってきても「azd init 」せずに「azd env new」で新しい環境を作った方が良いのかな?と思います。

以下にも関連したエラーと対処方法を記載しています。
rikues2012.hatenablog.com

Amazon ECSで複数のコンテナがある場合、同じタスク内にするか?別々のタスクにするか?

ECSで複数のコンテナがある場合、同じタスク内にするか?別々のタスクにするか?
管理が簡単そうでなんとなく同じタスク内で定義していたのですが、理由を聞かれ困ったので構築後に調査しました。
システムの要件によって判断するということ分かりました。

公式サイトには以下の記載があります。
以下の要件がある場合、1 つのタスク定義にコンテナを配置することをお勧めします。

  • 各コンテナが同じライフサイクルを共有している (起動と終了が同時に行われる)。
  • 実行基盤となるホストが同じになるようにコンテナを実行する (あるコンテナが、localhost ポート上の別のコンテナを参照する) 必要がある。
  • 各コンテナがリソースを共有している。
  • コンテナでデータボリュームを共有している。

docs.aws.amazon.com

私が担当したシステムは以下のような要件でした。

  • コンテナ構成:Nginx と Spring Boot
  • システム概要:業務管理システム
  • Nginxではリソース共有、データボリュームは共有していない
  • 各コンテナのライフサイクルは共有しなくても良い(微妙ですが)
    ⇒ 「実行基盤となるホストが同じになるよう・・・」に当てはまる

NginxはWebサーバのみの機能でSpring Bootにリクエストを渡すだけ。
以下の構成図のように同じタスク内にコンテナを定義しました。

前置きが長くなってしまいましたが、回答は以下としました。

  • 本システムの要件(構成)では同じタスク内にコンテナを定義することがAWSのベストプラクティス
  • NginxがSpringBootアプリケーションに対してlocalhostを使用してリクエストを転送することでネットワークのオーバーヘッドを減らし、通信を効率化する

■ 補足
一般的には別々のタスクに定義することでスケーリングや障害対応が柔軟にでき、運用面での利便性が高まると言われていました。
別々のタスクにする場合はクラスター内にコンテナごとにサービスを作って、それぞれタスク数を設定していく感じだと思います。
理由を聞かれて即答できる人間になりたいです。

CodeBuildのイメージをstandard:5.0に変更時のエラーと対応方法

以前、CodeBuildのイメージ「x86_64 standard:4.0」でbuildspec.ymlを作成しました。
「x86_64-standard:5.0」にした際、いくつかエラーが発生しました。
エラー内容と対応方法を書きます。

前提知識

・x86_64 standard:4.0:Amazon Linux 2 のイメージ
・x86_64-standard:5.0:Amazon Linux 2023 のイメージ

docs.aws.amazon.com

AWSコンソールからだとどちらも「aws/codebuild/amazonlinux2-xxx」なので、Amazon Linux 2だと思っていました。

1、「LC_ALL: cannot change locale (en_US.utf8)」エラー

エラーメッセージ

buildspec.ymlに「export LC_ALL="en_US.utf8"」と記載し日本語ファイル対応していましたが、Amazon Linux 2023では存在しないロケールになった。(っぽい)

[Container] Running command export LC_ALL="en_US.utf8"
/codebuild/output/tmp/script.sh: line 4: warning: setlocale: LC_ALL: cannot change locale (en_US.utf8): No such file or directory
/codebuild/output/tmp/script.sh: line 4: warning: setlocale: LC_ALL: cannot change locale (en_US.utf8): No such file or directory
対応方法

最後の2行で対応しています。

# buildspec.yml
phases:
  install:
    runtime-versions:
      python: 3.9
  pre_build:
    commands:
      - dnf -y install glibc-langpack-ja
      - export LANG=ja_JP.utf8 LC_ALL=ja_JP.utf8 LANGUAGE=ja_JP:ja


2、ECRログイン時にエラー

エラーメッセージ
/codebuild/output/tmp/script.sh: 行 4: Login: コマンドが見つかりません

[Container] 2024/08/16 04:35:43.018293 Command did not exit successfully $(aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com) exit status 127
[Container] 2024/08/16 04:35:43.024047 Phase complete: PRE_BUILD State: FAILED
[Container] 2024/08/16 04:35:43.024064 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: $(aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com). Reason: exit status 127
原因

buildspec.ymlのECRログイン時の記述を「aws ecr get-login」が非推奨になったため、「get-login-password」に変更した。
get-login-passwordの場合は前後の「$()」が不要だった。

$(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)

↓

$(aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com)

公式サイト
get-login — AWS CLI 1.34.0 Command Reference

対応方法

buildspec.ymlを以下のように修正

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com



以下のサイトを参考にさせて頂きましたが、よく見たら前後の「$()」は付いていない。
人間の思い込みは怖いという話になります。
けっこう気が付かずに1時間ぐらい試行錯誤してしまいました。
qiita.com

Azure OpenAI Serviceのハンズオンでazd upで発生したエラーと対応方法

Azure OpenAI Serviceのハンズオンで発生したエラーと対処方法になります。
以下のgitからファイルを取得しデプロイすれば、社内文書検索が簡単に作成できます。
jp-azureopenai-samples/5.internal-document-search at main · Azure-Samples/jp-azureopenai-samples · GitHub

「azd up」コマンドでデプロイすればChat+社内文書検索できるのですが、
環境の不備や知識不足もあってエラーが発生しました。

1、リソースの再作成時エラー

エラーメッセージ
InvalidTemplateDeployment: The template deployment 'openai' is not valid according to the validation procedure. The tracking id is '<tracking id>'. See inner errors for details.
FlagMustBeSetForRestore: An existing resource with ID '/subscriptions/<サブスクリプション ID>/resourceGroups/<リソースグループ名>/providers/Microsoft.CognitiveServices/xxxxxx' has been soft-deleted. 
To restore the resource, you must specify 'restore' to be 'true' in the property. If you don't want to restore existing resource, please purge it first.
原因

リソースを削除すると、48 時間は同じ名前で別のリソースを作成することはできない。
エラー発生前にリソースを削除し、同じ環境でデプロイしてしまった。
Azure管理コンソール画面からは論理削除で、物理的にはリソースが残ってしまう。
ハンズオンのbicepファイルは「リソースグループ名」 + 「環境名」 +「リージョン」でリソース名を作成している。

対応方法

以下のどれかで対応
・対応パターン① 削除されたリソースを物理的に消去する
削除された Azure AI サービス リソースの復旧または消去 - Azure AI services | Microsoft Learn
・対応パターン② 別のリソース名で作成する
以下のコマンドで新しい環境名を作成する

azd env new 環境名

・対応パターン3:48時間後に作成する

私はパターン②で対応しました。

2、クォータ トークン不足

エラーメッセージ
InvalidTemplateDeployment: The template deployment 'openai' is not valid according to the validation procedure. The tracking id is '<tracking id>'. See inner errors for details.
InsufficientQuota: This operation require 120 new capacity in quota Tokens Per Minute (thousands) - GPT-35-Turbo, which is bigger than the current available capacity 0. The current quota usage is 500 and the quota limit is 500 for quota Tokens Per Minute (thousands) - GPT-35-Turbo.
原因

Azure OpenAI Service のクォータ不足

対応方法

以下のどれかで対応
・対応パターン① Azure OpenAI Service のクォータ引き上げ
Azure OpenAI Service のクォータと制限 - Azure AI services | Microsoft Learn
・対応パターン② トークンが空いている別リージョンを利用
・対応パターン③ bicepを修正しトークン数を減らす
以下の「main.bicep」ファイルを修正し、120 ⇒ 20に減らしました


私はパターン②と③で対応しました。

3、同時実行エラー

エラーメッセージ
Deployment Error Details: DeploymentActive: Unable to edit or replace deployment 'search-service': previous deployment from '6/7/2024 XX:XX:XX AM' is still active (expiration time is '6/14/2024 XX:XX:XX AM'). Please see https://aka.ms/arm-deploy-resources for usage details.
原因

同じサブスクリプションIDで同時にデプロイを実行したため
もしかすると同じリソースグループIDかも

対応方法

同じサブスクリプションIDで同時にデプロイを実行しない
もしかすると同じリソースグループIDかも



4、セッション切れ

エラーメッセージ

エラー詳細が何も出力されない

ERROR: error executing step command 'provision': deployment failed: error deploying infrastructure: deploying to resource group: Deployment Error Details:
原因

セッション切れの可能性がある
稀に発生するが実は原因は分かっていない。。

対応方法

再度、以下のコマンドでログインする

azd auth login



5、alpha機能無効のエラー

エラーメッセージ
ERROR: resource group scoped deployments are currently under alpha support and need to be explicitly enabled. Run `azd config set alpha.resourceGroupDeployments on` to enable this feature.
原因

alpha機能を有効化する
環境名ごとに設定が必要

対応方法

以下のコマンドでalpha機能を有効化

azd config set alpha.resourceGroupDeployments on


エラー時に日本語のサイトが少なかったので、参考にして頂ければ幸いです。

Azure OpenAI Serviceのハンズオンサイト
Azure OpenAI Service 入門ハンズオンラボ - HOME

Fargateでnginxとspring bootを連携

Amazon ECS on Fargateでnginxとspring bootを連携した際に躓いた点を記事にします。

以前に業務外ですが、EC2上でDockerを利用しNginxとSpriing bootを連携させたことはあったので少し知識はありました。

 

以下、EC2上でDockerを利用しNginxとSpriing bootさせた手順です

rikues2012.hatenablog.com

 

構成図になります。
nginxとspring bootのコンテナは同一Service内にあります。
nginxの前段にALBなどがありますが必要な箇所のみ構成図としました。

躓いた箇所

nginxのnginx.confでspring bootと連携する箇所の記載方法が不明。

連携できずにECSのタスク起動時にエラーが発生。

 

解決方法

nginxのnginx.confを以下のようにする

   server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        #root         /usr/share/nginx/html; ←ここをコメント

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                proxy_pass http://localhost:8080/; ←ここがポイント
        }

「localhost:8080」と記述し、
spring boot側で8080で受信できるようにして連携することができました。
別々のコンテナ間でlocalhostを認識することができました。

EC2上では以下で連携できますが、Fargateは「link」オプションを利用できないです。

① nginx.confに「proxy_pass http://app:8080/;」と記述

② 「docker run -d --link spring-container:app ・・・」のようにlinkオプションを利用

 

そもそも公式サイトに「link」オプションは非推奨と記載されていました。。

docs.docker.com

 

今回記事にした箇所で半日ぐらい躓きました。

ECSも初めて利用したため「どの箇所が間違っているのか?」特定するのに時間がかかりました。

気になっていること

・ネットでいろいろな構成図を参照するとnginxとspring bootのコンテナを別々のServiceにした方が良さそうな気もします。

 

ECS on Fargate 構築時のエラーと対応方法

ECS on Fargate 構築時のエラー一覧と対応方法です。
約半年ぐらい前に構築した内容で自分への振り返りとして纏めました。
初めてECSを業務で利用したので振り返ると初歩的なエラーばかりです。

一部環境ですが、以下構成イメージです。(CI/CD含む)

1、AWSServiceRoleForECSが存在しないエラー

エラーメッセージ

CloudFormationでECS Cluster作成時にエラーが発生

Resource handler returned message: "Invalid request provided: CreateService error: Unable to assume the service linked role. Please verify that the ECS service linked role exists.
(Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException; Request ID: xxxxxxxxxx; Proxy: null)" (RequestToken: xxxxxxxxxx, HandlerErrorCode: InvalidRequest)
原因

IAMロール「AWSServiceRoleForECS」が存在しない

対応方法

以下のどちらかで対応
対応パターン① AWSマネジメントコンソールからECSを作成する
       ⇒「AWSServiceRoleForECS」が自動で生成
対応パターン② CloudFormationでAWSServiceRoleForECSを作成。

  IAMRoleAWSServiceRoleForECS:
    Type: "AWS::IAM::ServiceLinkedRole"
    Properties:
      AWSServiceName: "ecs.amazonaws.com"
      Description: "Role to enable Amazon ECS to manage your cluster."

複数の環境でECSを作成するため、私は②(CloudFormation)で対応しました。
異なるエラーコード、メッセージでも「AWSServiceRoleForECS」が存在しないために発生するエラーがあるため、このIAMロールの存在は確認したほうが良いです。

詳細については以下のサイトに説明されています。
IAMのService-Linked RolesがCloudFormationに対応したので、とてもナイスなリリースということを詳しく書いてみた。 | DevelopersIO

2、IAMポリシーの不足

エラーメッセージ

CodePipelineのCodeCommitでエラーが発生

The service role or action role doesn’t have the permissions required to access the Amazon S3 bucket named 検証環境S3バケット名
Update the IAM role permissions, and then try again. Error: Amazon S3:AccessDenied:User: arn:aws:sts::111111111111:assumed-role/ロール名/222222222222 is not authorized to perform:
kms:GenerateDataKey on this resource because no identity-based policy allows the kms:GenerateDataKey action
(Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: xxxxx; S3 Extended Request ID: xxxxx; Proxy: null)
原因

dev環境(111111111111)のロールにKMSのポリシーが不足していて、検証環境のS3バケットを参照できない

対応方法

dev環境(111111111111)のロールにKMSのポリシー(kms:GenerateDataKey)を追加


3、KMSのエイリアスが利用できないエラー

エラーメッセージ

CodePipelineのCodeCommitでエラーが発生

The service role or action role doesn’t have the permissions required to access the Amazon S3 bucket named xxx. Update the IAM role permissions, and then try again.
Error: Amazon S3:AccessDenied:Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: xxxxx; S3 Extended Request ID: xxxxx; Proxy: null)
原因

KMSを作成していないアカウント(構成図ではdev環境)からだとKMSのエイリアスは利用できないためエラー。

対応方法

KMSのエイリアスを利用しないように変更しました。
今振り返るともっと良い対応方法があったはず。


4、ECR参照先が存在しない

エラーメッセージ

CodePipelineのCodeBuildでエラーが発生

COMMAND_EXECUTION_ERROR: Error while executing command: docker push $REPOSITORY_URI:latest. Reason: exit status 1
CLIENT_ERROR: no matching artifact paths found
原因

buildspec.ymlに設定したECR参照先が存在しない

対応方法

buildspec.ymlに正しいECRの参照先を設定


5、buildspec.yml内の変数の規定外の文字列(記号)を使用

エラーメッセージ

CodePipelineのCodeBuildでエラーが発生

s3-cicd-api: not a valid identifier
原因

buildspec.yml内の変数に「-」があったため

対応方法

buildspec.ymlの変数に「-」などの記号を取る
詳細は以下の記事にしました。 rikues2012.hatenablog.com

6、エンドポイントが未作成

エラーメッセージ

CodePipelineのCodeDeployでエラーが発生

Resourceinitializationerror: unable to pull secrets or registry auth: execution resource retrieval failed:
unable to retrieve ecr registry auth: service call has been retried 3 time(s): RequestError: send request failed caused by:
Post "https://api.ecr.ap-northeast-1.amazonaws.com/": dial tcp xx.xx.xx.xx:443: i/o timeout
原因

ECRのエンドポイントが未作成のため、イメージを取得できない

対応方法

ECRのエンドポイントを作成
・サービス名:com.amazonaws.ap-northeast-1.ecr.api



参考サイト

以下、FargateのCI/CDパイプラインのエラー原因ポイントが記載されています。

AWS Fargate with CI/CDパイプラインでデプロイ失敗する原因について | クラウド・AWSのIT技術者向けブログ SKYARCH BROADCASTING

以下、CodeBuildのエラー原因のポイントが記載されています。

AWS CodeBuildで失敗したときに確認するポイント #AWS - Qiita