[アップデート]AWS CodeBuildの新しいデバッグ機能であるSandbox環境によるデバッグを試してみた
お疲れさまです。とーちです。
AWS CodeBuildでデバッグ機能が強化されたというアップデートがありました。今回はこの新機能を実際に試してみたので、その内容をお届けします。
今回のアップデート内容
What's Newの記載だと若干わかりづらいかもしれないので、まとめると以下のようなアップデートになっています。
-
従来のデバッグ方法: CodeBuildのデバッグをするには、AWS Systems Manager セッションマネージャーを使ったビルドコンテナへのログインという方法がサポートされていました
-
今回のアップデート: CodeBuild Sandbox環境という機能が使えるようになりました
- この機能はビルドプロジェクトさえ作ればビルドを開始しなくても使える機能です
- 実際のビルド環境をSandbox環境として立ち上げ、そこにマネージメントコンソールからコマンド実行したり、SSH、IDE(VSCode等)などを使って接続できます
- Sandbox環境は実際のビルド環境と同じようにCodeBuildプロジェクトで設定したサービスロールの権限に基づき周辺AWSサービスにもアクセスできます(Sandbox環境にawscliがインストールされているので、それを使ってS3等にアクセスできるということです)
それではさっそく試してみましょう。
Sandbox環境を使ってみる
事前準備
まずはCodeBuildプロジェクトを作ります。今回は以下のような内容にしました。プロジェクト作成では特に気をつけることはありませんが、一点だけプロジェクトに紐づけるサービスロールのポリシーにだけはご注意ください。この後説明します。
CodeBuildプロジェクトの設定
今回はプロジェクト作成後にサービスロールに権限を追加しました。プロジェクトの詳細から、このCodeBuildプロジェクトに紐づくサービスロールを見つけます。
このサービスロールに以下のポリシーを追加します。これはSandbox環境への接続に必要な権限です。(<region>
と <account-id>
は、ご自身の環境に合わせて置き換えてください。)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": [
"arn:aws:codebuild:<region>:<account-id>:build/*",
"arn:aws:ssm:<region>::document/AWS-StartSSHSession"
]
}
]
}
コンソールからのコマンド実行
この状態で画面上部から「デバッグビルド」を選択します。
適当なコマンドを入力してコマンドを実行してみます。
すると以下のようにコマンド結果が出力されました。
これは便利ですね。実際のビルド環境と同様の環境で各コマンド動作を確認できるので、デバッグが捗りそうです。
なお、Sandbox環境実行中は以下のような表示が出ています。
SSHクライアントでの接続
Sandbox環境を実行状態にしたまま、次はSSHクライアントでの接続を試してみます。
SSHクライアントのタブを開くと以下のような表示がされています。
どうやら、シェルスクリプトをダウンロードして実行する必要があるようですね。参考までにダウンロードしたシェルスクリプトの内容を記載しておきます(2025/4/11時点のもの)
シェルスクリプトの中身
#!/bin/bash
set -e
_wait() {
read -p "Press return to continue "
}
_print() {
printf "$1\n"
}
install_session_manager_plugin() {
# get session manager installer url based on CPU architecture
architecture=$(uname -m)
case $architecture in
"arm" | "arm64" | "aarch64")
installer_url="https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac_arm64/session-manager-plugin.pkg"
;;
"x86_64")
installer_url="https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/session-manager-plugin.pkg"
;;
*)
echo "Unsupported CPU architecture. Couldn't install AWS Session Manager plugin"
exit 1
;;
esac
if command -v session-manager-plugin; then
echo "Updating Session Manager plugin from signed installer"
else
echo "Installing Session Manager plugin from signed installer"
fi
_wait
curl $installer_url -o "session-manager-plugin.pkg"
sudo installer -pkg session-manager-plugin.pkg -target /
# Do not fail if symlink exists
set +e && sudo ln -s /usr/local/sessionmanagerplugin/bin/session-manager-plugin /usr/local/bin/session-manager-plugin && set -e
rm "session-manager-plugin.pkg"
session-manager-plugin
echo "Successfully installed AWS Session Manager plugin"
}
update_ssh_config() {
ssh_config_content="\nHost codebuild-sandbox-ssh*
StrictHostKeyChecking no
LogLevel INFO
ForwardAgent yes
ControlMaster auto
ControlPersist 10m
ProxyCommand sh -c \"$HOME/.aws/codebuild-dev-env/codebuild-sandbox-connect.sh %%n\""
mkdir -p ~/.ssh
touch ~/.ssh/config
found_ssh_config=0
grep -Fxq "Host codebuild-sandbox-ssh*" ~/.ssh/config || found_ssh_config=$?
if [ $found_ssh_config -eq 0 ]; then
echo "Found SSH config for hostname alias 'codebuild-sandbox-ssh*'. Skipping SSH config update"
else
echo "Adding the following lines to ~/.ssh/config:"
_print "$ssh_config_content\n"
_wait
_print "$ssh_config_content" >> ~/.ssh/config
echo "Successfully modified local SSH configuration"
fi
}
# define proxy command script content
start_connection_script_content=$(cat <<- "END"
#!/bin/bash
set -e
start_dev_environment_connection() {
export AWS_EXECUTION_ENV="DevEnvSSHAccess"
if ! command -v aws; then
echo "Please make sure you have AWS CLI installed. Refer to the documentation for installation steps: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" >> /dev/stderr
exit 1
fi
aws_cli_version_string_temp=$(aws --version)
aws_cli_version="$(echo $aws_cli_version_string_temp | grep -ozE "aws-cli/([0-9]{1,}\.)+[0-9]{1,}" | grep -aoE "([0-9]{1,}\.)+[0-9]{1,}")"
# compare installed AWS CLI version with minimum supported version
if (echo minimum 2.9.4; echo installed $aws_cli_version) | sort -Vk2 | tail -1 | grep -q minimum; then
echo "You are using an older version of AWS CLI that doesn't support CodeBuild commands. Please update AWS CLI to the latest version to be able connect to the dev environment via SSH." >> /dev/stderr
echo "Refer to the documentation for installation steps: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" >> /dev/stderr
exit 1
fi
hostname=$1
OLDIFS=$IFS
IFS='='
if [[ $hostname == *"?"* ]]; then
IFS='?'
fi
sandboxId=""
region=""
read -a input_array <<< "$hostname"
if [ ${#input_array[*]} -eq 2 ]
then
sandboxId=${input_array[1]}
region=$(echo $sandboxId | grep -oE ":[a-z]{2}-[a-z]{1,}-[0-9]{1,}:" | tr -d ':')
else
region=${input_array[1]}
accountId=${input_array[2]}
projectName=${input_array[3]}
sandboxUUID=${input_array[4]}
sandboxId="arn:aws:codebuild:${region}:${accountId}:sandbox/${projectName}:${sandboxUUID}"
fi
IFS=$OLDIFS
response=$(
aws codebuild start-sandbox-connection \\
--sandbox-id $sandboxId \\
--region $region
)
if [ $? -ne 0 ]; then
>/dev/stderr echo $response
exit 1
fi
read SESSION_ID STREAM_URL TOKEN_VALUE <<< $(echo $response | jq --raw-output '.ssmSession.sessionId, .ssmSession.streamUrl, .ssmSession.tokenValue')
export AWS_SSM_START_SESSION_RESPONSE="
{
\\"streamUrl\\": \\"$STREAM_URL\\",
\\"tokenValue\\": \\"$TOKEN_VALUE\\",
\\"sessionId\\": \\"$SESSION_ID\\"
}
"
session-manager-plugin AWS_SSM_START_SESSION_RESPONSE $region "StartSession"
}
start_dev_environment_connection $1
END
)
place_proxy_command_script() {
mkdir -p ~/.aws/codebuild-dev-env
touch ~/.aws/codebuild-dev-env/codebuild-sandbox-connect.sh
# Do not touch proxy command script if it doesn't need to be updated
if [ "$(cat ~/.aws/codebuild-dev-env/codebuild-sandbox-connect.sh)" == "$start_connection_script_content" ]; then
return
fi
echo
echo "Placing SSH proxy command script in ~/.aws/codebuild-dev-env/codebuild-sandbox-connect.sh"
_wait
_print "$start_connection_script_content" > ~/.aws/codebuild-dev-env/codebuild-sandbox-connect.sh
chmod +x ~/.aws/codebuild-dev-env/codebuild-sandbox-connect.sh
echo "Successfully placed SSH proxy command script in ~/.aws/codebuild-dev-env/"
}
check_aws_cli_version() {
if ! command -v aws; then
echo
echo "ERROR: "
echo "Please make sure you have AWS CLI installed. Refer to the documentation for installation steps: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"
exit 1
fi
aws --version &> aws_cli_version_string_temp.txt
aws_cli_version="$(cat aws_cli_version_string_temp.txt | grep -ozE "aws-cli/([0-9]{1,}\.)+[0-9]{1,}" | grep -aoE "([0-9]{1,}\.)+[0-9]{1,}")"
rm aws_cli_version_string_temp.txt
# compare installed AWS CLI version with minimum supported version
if (echo minimum 2.9.4; echo installed $aws_cli_version) | sort -Vk2 | tail -1 | grep -q minimum; then
echo
echo "ERROR: "
echo "You are using an older version of AWS CLI that doesn't support CodeBuild commands. Please update AWS CLI to the latest version to be able connect to the dev environment via SSH." >> /dev/stderr
echo "Refer to the documentation for installation steps: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" >> /dev/stderr
exit 1
fi
}
install_jq_tool() {
if ! command -v jq; then
if command -v brew
then
echo "Found brew. Installing jq tool"
_wait
brew install jq
elif command -v port
then
echo "Found port. Installing jq tool"
_wait
port install jq
elif command -v fink
then
echo "Found dnf. Installing jq tool"
_wait
fink install jq
else
echo
echo "ERROR: "
echo "Please make sure you have the jq tool installed: https://jqlang.org/"
exit 1
fi
fi
}
_main() {
check_aws_cli_version
install_jq_tool
install_session_manager_plugin
update_ssh_config
place_proxy_command_script
_print "Configured local environment for SSH access to CodeBuild Sandboxes"
}
_main
シェルスクリプトの内容と注意点
ダウンロードしたシェルスクリプトの内容を確認してみると、ざっくり以下のような処理を行うようです。なんというか、、私の印象だとスクリプトを実行する開発端末の環境への影響が少なからずありそうな処理に見えるので、実行する際はご注意ください。
動作の流れ
- AWS CLI のバージョンチェック
- jq ツールのインストール確認/インストール
- AWS Session Manager プラグインのインストール/更新
- SSH 設定ファイル(
~/.ssh/config
)の更新 - 接続用プロキシコマンドスクリプトを
~/.aws/codebuild-dev-env/codebuild-sandbox-connect.sh
に配置
一応、実行時には以下のような形で処理してもいいか確認してくれます。
> ./mac-sandbox-ssh.sh
<中略>
Updating Session Manager plugin from signed installer
Press return to continue
AWS CLIバージョンに関する注意点
スクリプトの中でAWS CLIのバージョンチェック処理が行われていますが、このチェックは十分ではないようです。スクリプトでは 2.9.4
以上であることをチェックしていますが、実際にはもう少し新しいバージョンのAWS CLIが必要です。
check_aws_cli_version() {
# 省略...
# compare installed AWS CLI version with minimum supported version
if (echo minimum 2.9.4; echo installed $aws_cli_version) | sort -Vk2 | tail -1 | grep -q minimum; then
echo
echo "ERROR: "
echo "You are using an older version of AWS CLI that doesn't support CodeBuild commands. Please update AWS CLI to the latest version to be able connect to the dev environment via SSH." >> /dev/stderr
echo "Refer to the documentation for installation steps: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" >> /dev/stderr
exit 1
fi
}
実際に試したところ、AWS CLIのバージョン 2.24.15
では、以下のようにエラーとなりました。
> ssh -vvv codebuild-sandbox-ssh=arn:aws:codebuild:ap-northeast-1:<account-id>:sandbox/codebuild-debugupdate:<sandbox-id>
OpenSSH_9.9p1, LibreSSL 3.3.6
debug1: Reading configuration data /Users/<username>/.ssh/config
<中略>
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: argument operation: Invalid choice, valid choices are:
batch-delete-builds | batch-get-build-batches
batch-get-builds | batch-get-fleets
batch-get-projects | batch-get-report-groups
batch-get-reports | create-fleet
create-project | create-report-group
create-webhook | delete-build-batch
delete-fleet | delete-project
delete-report | delete-report-group
delete-resource-policy | delete-source-credentials
delete-webhook | describe-code-coverages
describe-test-cases | get-report-group-trend
get-resource-policy | import-source-credentials
invalidate-project-cache | list-build-batches
list-build-batches-for-project | list-builds
list-builds-for-project | list-curated-environment-images
list-fleets | list-projects
list-report-groups | list-reports
list-reports-for-report-group | list-shared-projects
list-shared-report-groups | list-source-credentials
put-resource-policy | retry-build
retry-build-batch | start-build
start-build-batch | stop-build
stop-build-batch | update-fleet
update-project | update-project-visibility
update-report-group | update-webhook
help
kex_exchange_identification: Connection closed by remote host
Connection closed by UNKNOWN port 65535
分かりづらいのですが、aws: error: argument operation: Invalid choice, valid choices are:
から続くリストの中にstart-sandbox-connection
の文字列がありません。これはAWS CLIのバージョン 2.24.15
では、start-sandbox-connection
のサブコマンドが存在しないことを示しています。
もう少し詳しく説明すると、~/.ssh/config
に行われた設定により、codebuild-sandbox-ssh
で始まる接続先にSSHをした際に、~/.aws/codebuild-dev-env/codebuild-sandbox-connect.sh
スクリプトが実行されています。
このスクリプトの中で、以下のようにaws codebuild start-sandbox-connection
コマンドを使っています。しかし、AWS CLIのバージョン 2.24.15
では、start-sandbox-connection
のサブコマンドが存在しないのでエラーになったという具合です。
response=$(
aws codebuild start-sandbox-connection \
--sandbox-id $sandboxId \
--region $region
)
start-sandbox-connection
のサブコマンドの具体的なリリースバージョンまではわかりませんが、AWS CLIのバージョンを以下のようにアップグレードしたところ、正常にSSH接続できるようになりました。
==> Upgrading awscli
2.24.15 -> 2.25.14
SSH接続の実行
実際にSSHでの接続を試してみます。
> ssh codebuild-sandbox-ssh=arn:aws:codebuild:ap-northeast-1:<account-id>:sandbox/codebuild-debugupdate:<sandbox-id>
sh-5.2# ls
buildspec.yml package.json package-lock.json
sh-5.2# pwd
/codebuild/output/src3247352091/src/github.com/ice1203/cachekey-update
これは良いですね。マネージメントコンソール上でのコマンド実行よりもレスポンスが早いので、本格的にデバッグするならこちらのほうが良さそうです。
今回は試していませんが、VSCodeからの接続の場合でも基本的な仕組みは一緒のようです。
まとめ
AWS CodeBuildのデバッグ機能が強化され、Sandbox環境によるデバッグができるようになったというアップデートを試してみました。
ビルドを開始しなくてもビルド環境に入って色々試せるというのは非常に便利です。まずSandbox環境でビルドコマンドを試して、試したコマンドをbuildspec.ymlに書くみたいな流れで進めるとスムーズに構築できそうです。
特に、以下のようなケースで役立ちそうです。
- ビルド環境内のファイル構造やパスを確認したい場合
- 特定のコマンドがビルド環境で正常に動作するか確認したい場合
- buildspec.ymlの作成・修正前に試行錯誤したい場合
- 環境変数や権限の設定が正しいか確認したい場合
以上、とーちでした。