MacOSでDocker Desktopの代替えとしてLima+docker環境を作ってみた
はじめに
MacOSでdockerを使おうとすると、第一候補は Docker Desktopになりますが、一定規模以上の企業で利用する場合は有料サブスクリプションが必要になります。*1
WindowsならWLS2でLinuxの仮想環境を作ってその上で、linuxのdocker(Docker Desktopでないので有料サブスクリプション不要)を動かすということができます。一方MacOSには標準でWLS2相当のものがないので、OSSのLima
を使ってLinux仮想環境を作って、その上でlinuxのdockerを動かします。
ここではそのセットアップ時の手順を備忘録として記載します。
セットアップ手順
前提のセットアップ
すでにセットアップされている場合はスキップしてください。
Limaのインストールとdockerインスタンスの作成
Limaのインストール
brew install lima
dockerが入ったLinux仮想環境の起動
Limaには多数のVMテンプレートがあり、それらテンプレートを利用して簡単に目的の仮想環境をセットアップすることができます。dockerの環境もLimaのテンプレートにあるため、ここではそのテンプレートを利用してdocker環境を起動する手順をまとめました。
limactl start --name=default template://docker
(参考)dockerが入ったLinux仮想環境の停止
limactl stop
(参考)dockerが入ったLinux仮想環境の2回目以降の起動
limactl start
dockerコマンドのセットアップ
dockerコマンドのインストール
brew install docker
dockerコマンドからLimaの仮想環境上のdockerデーモンへの接続
ここで記載した手順は、Limaのdocker環境を起動した時のメッセージの最後に表示されています。
lima-default
という名前のコンテキストを作成して、切り替える方法になります。
- dockerコンテキストの作成
docker context create lima-default --docker "host=unix:///Users/nobuyuf/.lima/default/sock/docker.sock"
- dockerで作成したコンテキストへの切り替え
docker context use lima-default
- テスト
docker run hello-world
下記メッセージが表示されればOKです。
Hello from Docker! This message shows that your installation appears to be working correctly.
docker起動スクリプト
上記手順で作成した環境をベースに、Limaのdocker仮想環境を起動しdockerのコンテキストを変更する一括のシェルスクリプトです。
start-docker.sh
#!env bash # start docker instance via Lima limactl start # change docker context docker context use lima-default
補足
補足1 Limaの操作
Limaで稼働している仮想環境の一覧
limactl list
固有のインスタンス名をつけた仮想環境の新規作成と起動
fedora仮想環境をfedoravm
というインスタンス名で起動する
limactl start --name=fedoravm template://fedora
起動中の仮想環境にインタラクティブなシェルで入る
limactl shell fedoravm
Limaの起動可能なテンプレート一覧参照
limactl start --list-templates
補足2 dockerのコンテキスト操作
コンテキスト一覧表示
docker context list
コンテキストの切り替え
docker context use <コンテキスト名>
コンテキストの削除
docker context rm <コンテキスト名>
*1:. Commercial use of Docker Desktop at a company of more than 250 employees OR more than $10 million in annual revenue requires a paid subscription (Pro, Team, or Business) to use Docker Desktop. Pricing | Docker
zshでコマンドライン実行で#コメントを使えるようにする設定
以下のコマンドでzshのプロファイルにコメントを有効化する設定を追加する。
設定後再ログインすれば、コメントがエラーにならないはず。
cat >> ~/.zshrc << EOL # enable comment on command line mode setopt interactivecomments EOL
Jira Service Management Rest APIでカスタム フィールドのオプションを変更したメモ
選択リスト型のカスタム フィールドの選択できる値のリスト更新を Rest APIで実行したメモです。
手順メモ
事前設定
ID="JiraユーザのID" PASSWD="API トークン" PROJECT_URL="プロジェクトのURLのxxxx.atlassian.netのxxxx部分"
カスタムフィールドのオプション(リストの選択値一覧)情報の取得
事前設定
FIELD_NAME='AwsSupportServices' PROJECT_NAME='aws portal' ISSUE_TYPE_NAME='AWS Support'
プロジェクトのID取得
PROJECT_ID=$( curl \ -s -u "${ID}:${PASSWD}" \ --request GET \ --header 'accept: application/json' \ --url "https://${PROJECT_URL}.atlassian.net/rest/api/2/project/search" | \ jq -r '.values[] | select ( .name == "'"${PROJECT_NAME}"'" ) | .id' ) echo ${PROJECT_ID}
課題タイプのID取得
ISSUE_TYPE_ID=$( curl \ -s -u "${ID}:${PASSWD}" \ --request GET \ --header 'accept: application/json' \ --url "https://${PROJECT_URL}.atlassian.net/rest/api/2/issuetype" | \ jq -r '.[] | select( .name == "'"${ISSUE_TYPE_NAME}"'" ) | .id' ) echo ${ISSUE_TYPE_ID}
カスタム フィールドのID取得
CUSTOME_FIELD_ID=$( curl \ -s -u "${ID}:${PASSWD}" \ --request GET \ --header 'accept: application/json' \ --url "https://${PROJECT_URL}.atlassian.net/rest/api/2/search?maxResults=1&expand=names" | \ jq -r '.names | to_entries | .[] | select( .value == "'"${FIELD_NAME}"'" ) | .key' ) echo $CUSTOME_FIELD_ID
カスタム フィールドの コンテキスト情報の取得
アトラシアンのドキュメントによると、「カスタム フィールド コンテキストは、同じフィールドの異なる設定です。プロジェクトに対して既定値が異なる複数のカスタム フィールドを作成する代わりに、コンテキストを使用して同じ結果を得られます。」とのことです。
同じカスタムフィールドでもプロジェクトごとにリストから選択できる値を変えることなどができるようです。
BODY_DATA='{ "mappings": [ { "issueTypeId": "'"${ISSUE_TYPE_ID}"'", "projectId": "'"${PROJECT_ID}"'" } ] }' CONTEXT_ID=$( \ curl \ -s -u "${ID}:${PASSWD}" \ --request POST \ --header 'Content-Type: application/json' \ --header 'accept: application/json' \ --url "https://${PROJECT_URL}.atlassian.net/rest/api/2/field/${CUSTOME_FIELD_ID}/context/mapping" \ --data "${BODY_DATA}" \ | jq -r '.values[0].contextId' ) echo $CONTEXT_ID
カスタム フィールドのオプション(リストの選択値一覧)の取得
curl \ -s -u "${ID}:${PASSWD}" \ --request GET \ --header 'accept: application/json' \ --url "https://${PROJECT_URL}.atlassian.net/rest/api/2/field/${CUSTOME_FIELD_ID}/context/${CONTEXT_ID}/option" | jq
カスタムフィールドのオプション更新
ここでは選択リスト(カスケード)のオプション変更を例にメモを記載します。
親リスト追加
BODY_DATA='{ "options": [ { "disabled": false, "value": "hoge hoge" } ] }' curl \ -s -u "${ID}:${PASSWD}" \ --request POST \ --header 'Content-Type: application/json' \ --header 'accept: application/json' \ --url "https://${PROJECT_URL}.atlassian.net/rest/api/2/field/${CUSTOME_FIELD_ID}/context/${CONTEXT_ID}/option" \ --data "${BODY_DATA}"
作成した親リストにカスタム フィールド オプションを追加する
PARENT_ID='作成した親のIDを指定'
BODY_DATA='{ "options": [ { "optionId": "'"${PARENT_ID}"'", "disabled": true, "value": "Manhattan" } ] }' curl \ -s -u "${ID}:${PASSWD}" \ --request POST \ --header 'Content-Type: application/json' \ --header 'accept: application/json' \ --url "https://${PROJECT_URL}.atlassian.net/rest/api/2/field/${CUSTOME_FIELD_ID}/context/${CONTEXT_ID}/option" \ --data "${BODY_DATA}"
既存のカスタムフィールド オプションの更新
CUSTOME_FIELD_OPTION_ID='変更したい既存フィールドのIDを指定'
BODY_DATA='{ "options": [ { "id": "'"${CUSTOME_FIELD_OPTION_ID}"'", "disabled": false, "value": "Manhattan" } ] }' curl \ -s -u "${ID}:${PASSWD}" \ --request PUT \ --header 'Content-Type: application/json' \ --header 'accept: application/json' \ --url "https://${PROJECT_URL}.atlassian.net/rest/api/2/field/${CUSTOME_FIELD_ID}/context/${CONTEXT_ID}/option" \ --data "${BODY_DATA}"
Jira Service ManagementでRest APIで課題を操作したメモ
はじめに
Jira Service ManagementのREST API操作を調査したメモです。
最終的にServer PlatformでREST APIを叩く必要があったため、Jira REST API V3ではなくJira REST API V2前提で調べていますので、注意ください。
JiraのREST API
REST API リファレンス
Jiraにはクラウド版とサーバ版があり、それぞれAPIのバージョンが異なるようです。
2022/9/1時点では、クラウド版がJira REST API V3で、サーバ版の最新が Jira REST API V2(Jira 9.2.0)のようです。
ただ使った限りではクラウド版でもJira REST API V2が実行できるようです。
REST APIで課題の情報を取得する
curl -u "${ID}:${PASSWD}" https://<Project-name>.atlassian.net/rest/api/2/issue/${ISSUE_ID} | jq
以下はあらかじめ変数で設定しておきます。
REST APIで課題をトラジションする
Transitionsの取得
curl -u "${ID}:${PASSWD}" https://<Project-name>.atlassian.net/rest/api/2/issue/${ISSUE_ID}/transitions
Transitionsする
Transitionsの取得で取得したデータから、実行したいTransitionのidを取得して以下を実行します。
TRANSITION_ID=99 #取得したISSUE IDに書き換え BODY='{ "transition": { "id": "'"${TRANSITION_ID}"'" } }' curl \ -u "${ID}:${PASSWD}" \ -X POST -d "${BODY}" \ --header 'Content-Type: application/json' \ --header 'accept: application/json' \ --url https://<Project-name>.atlassian.net/rest/api/2/issue/${ISSUE_ID}/transitions
Transitionsしてかつコメントを追記する
前提
前提として該当Transistionを実行したときに以下のような画面が出てくるよう、Transistionを設定する必要があります。
- Trasition時にコメント追加ができるようにする設定方法
- 画面(Screen)を新規作成します。
フィールドタブ
は何も設定しないでOKです。 - 該当ワークフローを編集します。
- 対象のトランジットを開き、
編集
を開きます 画面
で、新規作成した画面を指定して保存します。
- 対象のトランジットを開き、
- 画面(Screen)を新規作成します。
REST API実行
TRANSITION_ID=99 #取得したISSUE IDに書き換え BODY='{ "update": { "comment": [ { "add": { "body": "Test Message." } } ] }, "transition": { "id": "'"${TRANSITION_ID}"'" } }' curl \ -u "${ID}:${PASSWD}" \ -X POST -d "${BODY}" \ --header 'Content-Type: application/json' \ --header 'accept: application/json' \ --url https://<Project-name>.atlassian.net/rest/api/2/issue/${ISSUE_ID}/transitions
Transitions時に特定のフィールド値を変更する
前提
- その1) Transitionの画面設定
前提として、該当Transitionでフィールド更新ができるよう、Transitionに割り当てた画面
設定で、更新したいフィールドを追加する必要があります。
- その2) カスタムフィールドの内部キー取得
動かした限りでは、例えばカスタムフィールドAwsAccountId
を更新しようとする時、transitionでAwsAccountId
は指定できず、内部で管理しているcustomfield_10016
のような無機質なキーで指定する必要があるようです。Jiraの残念な仕様ですね。
カスタムフィールドの名前と内部のキーのマッピングの一覧は以下で取得することができるので、これで事前に変更したいカスタフィールドの内部キーが何かを確認しておく必要があります。
curl -u "${ID}:${PASSWD}" "https://<Project-name>.atlassian.net/rest/api/2/search?maxResults=1&expand=names"
REST API実行
TRANSITION_ID=99 #取得したISSUE IDに書き換え BODY='{ "fields": { "customfield_10075": "bbb hoge hoge" }, "transition": { "id": "'"${TRANSITION_ID}"'" } }' curl \ -u "${ID}:${PASSWD}" \ -X POST -d "${BODY}" \ --header 'Content-Type: application/json' \ --header 'accept: application/json' \ --url "https://<Project-name>.atlassian.net/rest/api/2/issue/${ISSUE_ID}/transitions?expand=transitions.fields"
課題(ISSUE)の特定フィールドを変更する
ISSUEの特定フィールドを更新する場合は、ISSUEの編集で対応できます。
BODY='{ "fields": { "customfield_10075": "000000000000" } }' curl \ -u "${ID}:${PASSWD}" \ -X PUT -d "${BODY}" \ --header 'Content-Type: application/json' \ --header 'accept: application/json' \ --url "https://<Project-name>.atlassian.net/rest/api/2/issue/${ISSUE_ID}"
Windowsサーバ ドメイン参加 + AD管理用サーバをPower Shellでやってみる
備忘録として、メモしておきます。
手順
AD管理ツールのセットアップ
- Windowsに管理者権限でログイン
- AD管理に必要なツールをPowerShellでインストールする。
Import-Module ServerManager Install-WindowsFeature -Name GPMC,RSAT-AD-PowerShell,RSAT-AD-AdminCenter,RSAT-ADDS-Tools,RSAT-DNS-Server
GitHub ActionsによるTerraform実行環境(更新ディレクトリ特定+checkovによるセキュリティチェック付き)
はじめに
GitHub ActionsによるTerraformのCIサンプルです。
実際のコードはGitHubのリポジトリを参照ください。
このサンプルの特徴は以下の通りです。
- OpenID Connect(OIDC)でのAWS認証によるActions実行により、アクセスキー&シークレットキー管理が不要
- Terraformのデファクトとなっているディレクトリ構成で作成
- その上でActionsでは、更新があったディレクトリを特定し、そのディレクトリのみTerraformを実行
- CIに、IaCコードの静的解析を行うcheckovを組み込み、Pull Requestで自動実行(最近流行りの、DevSecOpsぽいものを実現)
terrafrom/envs/xxx
のように環境面でTerraform実行先が固定されている場合(実行面数が増加しない場合)は、こんな面倒なやり方をせずワークフローを分けて
on:
で、paths:
条件で実行する構成にした方がシンプルで望ましいです。
一方で、アカウントやプロジェクトなどTerraform実行ディレクトリが単純増加するユースケースで、GitHub ActionsでTerraformを実行したいケースでは、このサンプルのワークフローが効果を発揮すると思います。
前提とするTerraformのディレクトリ構成
terraformのモジュールの標準的なディレクトリ構成を前提としています。
/terraform/accounts/
配下にそれぞれのアカウント単位でterrafomを管理するイメージです。
アカウントを追加する場合は、_template
フォルダを任意の名称でコピーして適切に設定を変更してterraformでapplyします。
. └── terraform ├── accounts │ ├── _template │ ├── user-a │ │ ├── backend.tf │ │ ├── main.tf │ │ ├── provider.tf │ │ └── terraform.tf │ ├── user-b │ └── user-c └── modules └── xxxxx
Actionsのワークフローコード
実際のコードはこちらのワークフローのYAMLファイルを確認ください。
ジョブは、(1)更新ディレクトリ特定ジョブと、(2)Terraform実行ジョブ、の2つで構成されています。
更新ディレクトリ特定ジョブ
シェル芸の塊です。ここではざっくりとは以下の処理をしています。
git log
による更新一覧取得sed
、awk
、uniq
などを駆使して、更新ディレクトリ情報のみ抽出- 抽出した情報を
jp
コマンドでJSONに変換 - 変換したJSONは、次のTerraform実行ジョブでのmatrixに利用
具体的な処理の中身については、GitHubのREADMEやこちらの記事を参照ください。
detect_dirs: name: "Detect modified directories" runs-on: ubuntu-latest defaults: run: shell: bash outputs: TARGET_DIR: ${{ steps.detectddir.outputs.TARGET_DIR }} steps: - name: Checkout repository uses: actions/checkout@v2 - name: Detect modified project directories id: detectddir run: | # git fetch echo "::group::git fetch" TARGET_BRANCH="${{ github.base_ref }}" echo "TAGET_BRANCE = ${TARGET_BRANCH}" git fetch --depth 1 origin ${TARGET_BRANCH} # If modules is changed, execute terraform to all . echo "::group::check modules directory" LINES=$( git diff origin/${TARGET_BRANCH} HEAD --name-only -- ${{env.TERRAFORM_MODULES_DIR}} | wc -l ) if [ ${LINES} -gt 0 ]; then flag_all_envs='true' else flag_all_envs='false' fi echo "::group::flag_all_envs = ${flag_all_envs}" # Detect target directories echo "::group::detect target directories" if [ "${flag_all_envs}" == 'true' ]; then TARGET_DIR=$( \ find ${{env.TERRAFORM_TARGET_DIR}} -type d -not -name ${{env.TERRAFORM_ENVS_EXCLUDED_DIR}} -maxdepth 1 -mindepth 1 | \ jq -scR 'split("\n") | .[:-1]' \ ); else TARGET_DIR=$( \ git diff origin/${TARGET_BRANCH} HEAD --name-only -- ${{ env.TERRAFORM_TARGET_DIR }} | \ sed -E 's:(^${{ env.TERRAFORM_TARGET_DIR }}/[^/]*/)(.*$):\1:' | \ sort | uniq | \ awk '{ if( system("[ -d "$1" ]") == 0 && $1 !~ /${{env.TERRAFORM_ENVS_EXCLUDED_DIR}}/ ){print $1} }' | \ jq -scR 'split("\n") | .[:-1]' ); fi # Output target directories echo "::endgroup::" # Output results echo "::group::results" echo "TARGET_DIR = ${TARGET_DIR}" echo "::endgroup::" # End processing echo "::set-output name=TARGET_DIR::${TARGET_DIR}" exit 0
Terraform実行ジョブ
先の更新ディレクトリ特定ジョブから、jobのoutputsを利用し特定したディレクトリ一覧を取得し、Matrixを利用し並列実行しています。
checkovの詳細については、こちらの記事を参照ください。
run_terraform: name: "Run terraform" needs: detect_dirs if: ${{ needs.detect_dirs.outputs.TARGET_DIR != '[]' }} strategy: fail-fast: false max-parallel: 2 matrix: target: ${{fromJson(needs.detect_dirs.outputs.TARGET_DIR)}} runs-on: ubuntu-latest defaults: run: shell: bash env: TERRAFORM_WORK_DIR: ${{ matrix.target }} permissions: id-token: write contents: read steps: - name: Checkout repository uses: actions/checkout@v2 with: fetch-depth: 0 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: ${{secrets.ASSUME_ROLE_ARN}} role-session-name: pullrequest aws-region: ap-northeast-1 - name: AWS Sts Get Caller Identity run: aws sts get-caller-identity - name: Setup terraform uses: hashicorp/setup-terraform@v1 with: terraform_version: ${{env.TERRAFORM_VERSION}} - name: Set up Python 3.9 uses: actions/setup-python@v4 with: python-version: 3.9 - name: Test with Checkov id: checkov uses: bridgecrewio/checkov-action@master with: directory: ${{env.TERRAFORM_ROOT_DIR}} framework: terraform quiet: true skip_check: ${{env.CHECKOV_SKIP_CHECK}} - name: Terraform Format run: terraform fmt -recursive -check=true - name: Terraform Init run: terraform -chdir=${TERRAFORM_WORK_DIR} init - name: Terraform Validate run: terraform -chdir=${TERRAFORM_WORK_DIR} validate -no-color - name: Terraform Plan run: terraform -chdir=${TERRAFORM_WORK_DIR} plan
セットアップ手順
具体的手順は、GitHubのリポジトリのREADMEに記載しています。
TerraformコードのセキュリティチェックでCheckovをGitHub Actionsに組み込んでみた

はじめに
Terraformコードのセキュリティーチェックを行う必要があり、IaC用の静的コード解析ツールであるcheckovをGitHub ActionsのCIに組み込んでみた時のメモです。
最初にcheckovをローカルで実行する場合のやりかたを説明して、最後にActionsへの組み込み方法を説明します。
Checkovとは
Checkovは、Infrastracture as code(IaC)コード用の静的コード解析ツールです。Checkovを利用することで、セキュリティやコンプライアンスの問題につながる可能性のある箇所を摘出することができます。解析可能なIaCは以下の通りです(2022/5現在)
- Terraform (for AWS, GCP, Azure and OCI)
- CloudFormation (including AWS SAM)
- Azure Resource Manager (ARM)
- Serverless framework
- Helm charts
- Kubernetes
- Docker
ローカルPCでの使い方
インストール
インストール方法は、checkovドキュメントのinstalling Checkovを参照ください。
たとえばpip3を利用してインストールする場合は以下のようになります。
pip3 install checkov
インストール後、下記のようにコマンドを打って実行可能なことを確認します。
checkov --version 2.0.1211
(留意事項)レベルアップ
なお、引数なしで実行すると下記のような画面で「追加機能を使えるようレベルアップするか?」という質問が出ます。このレベルアップをするためにy
を選択すると、レベルアップに必須となるhttps://www.bridgecrew.cloud/gettingStartedのアカウント作成に必要な情報を対話形式で入力する流れになります。
この設定をすると、checkov
の実行結果がbridgecrew.cloudのサイトにアップされることになるようなので、アップされるのを回避したい場合はn
を選択して終了するようにしてください。
もしレベルアップを選択してbridgecrew.cloudのサイトにアップされるようになった後に解除する場合ですが、~/.bridgecrew/credentials
にサイトに接続するためのトークンがあるので、このファイルを削除してしまうことで接続されないようになります。
静的解析のやりかた
静的解析の実行方法
たとえばTerraformの実行ディレクトリが/data/HogeHogeSystem/envs/development/
の場合、以下のコマンドで静的解析を実施することができます。
checkov --quiet -d /data/HogeHogeSystem/envs/development/
--quiet
: FAILEDになったものだけ表示されます。(quietをつけない場合は、PASSした結果も表示されます)
実行結果の例です。
指摘事項のスキップ方法(Terraformのオブジェクト単位)
上記の例では、セキュリティーグループを作成しているけど使用されていないよというエラーになります。
ここで指摘内容が正しければコード修正しますが、問題ない場合は該当モジュールにcheckov:skip=check_id:suppression_comment
の形式でコメントを追加すると、checkovでチェックをスキップすることができます。
# SG for EC2 instances resource "aws_security_group" "ec2" { #checkov:skip=CKV2_AWS_5:There is no problem because it will be used in the EC2 instance to be added later. name = "${var.vpcname}-ec2" description = "For EC2" vpc_id = aws_vpc.this.id egress { description = "Allow all traffic." from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${var.vpcname}-sg-ec2" } }
詳しい内容は、Suppressing and Skipping Policies - checkovを参照ください。
指摘事項のスキップ方法(ルール単位)
また、--skip-check
で指定することで、チェック全体から特定のルールを除外することができます。
たとえばcheckovでは、LOW
、MEDIUM
、HIGH
、CRITICAL
の4つのseverity区分があります。またルールには、CKV_123
のような番号が振られています。
severityがLOW
のものと、CKV_123
をチェックから除外する場合は、以下のように実行します。
checkov --quiet --skip-check LOW,CKV_123 -d /data/HogeHogeSystem/envs/development/
GitHub ActionsへのCheckovの組み込み
GitHub Actionsのワークフローに、checkovを組み込むことができます。詳細については以下のドキュメントを確認ください。
- Github Actions - checkov
- GitHub - bridgecrewio/checkov-action: A Github Action to run Checkov against an Infrastructure-as-Code repository. Checkov does static security analysis of Terraform, CloudFormation, Kubernetes, serverless framework and ARM templates
具体的にはGitHub Actionsに以下のような記載をすることで、Actionsでcheckovを実行することができます。この場合FAILEDになるルールが発生した場合はcheckovコマンドのリターン値が0
ではないので、その時点でエラーでフローがアベンドします。
またcheckovの前提でpythonが必要になるため、 actions/setup-python@v4
を利用しPythonをセットアップします。
- name: Terraform Format run: terraform fmt -recursive -check -diff - name: Set up Python 3.9 uses: actions/setup-python@v4 with: python-version: 3.9 - name: Test with Checkov id: checkov uses: bridgecrewio/checkov-action@master with: directory: . framework: terraform quiet: true skip_check: LOW - name: Terraform Init run: terraform init -no-color
エラーが発生した時のスキップ方法など運用方法は、ローカルPCの時と同じになります。
運用としては、このcheckovをmainブランチへのPull Request & Push時のフローに組み込み、セキュリティチェックが通過しないとmainブランチにマージできないようにするなどが考えられます。
テストでプロセスをハングアップさせる方法
テストケースでプロセスハングがあり、どうやろうかと調べたので簡単にメモします。
プロセスの一時停止
対象のプロセスにSIGSTOPを送るとプロセスが一時停止します。これでプロセスのハングアップ状況を作ります。
※ アプリ側でSIGSTOPを受け付けないよう実装されている場合は効かないです。
sudo kill -s SIGSTOP <対象プロセスのPID>
プロセスの再開
再開する場合は対象のプロセスにSIGCONTを送ります。ただ正常に再開してくれるかは該当アプリの実装によります。
なのでサービスであればsystemctl restart XXXXX
で再起動してしまったほうが確実です。
sudo kill -s SIGCONT <対象プロセスのPID>
なんで調べたのか
kubernetes(EKS+ワーカーノードEC2構成)の障害テストで、kubeletのハング時を再現したくて調べたものです。
ちなみにテスト結果は以下のとおりです。
- EC2インスタンスは正常稼働のママ(インスタンスやOSは正常なので、AutoScalingでは当然検知できない)
- kubernetesで該当ノードは
NotReady
状態になる - 該当ノード上のPodは検証では
Terminating
になり、最終的に別のノードに再配置され復旧する - アプリ(ALB経由の簡易的なhttpdのPod)は一時的にエラー(50x)が発生する場合も
SSH接続型のCloud9をセットアップする手順
はじめに
AWS Cloud9は、ブラウザのみでコードを記述、実行、デバッグできるクラウドベースの統合開発環境 (IDE) です。IDEの画面はこんな感じです。
AWS Cloud9で、AWS Cloud9サービスからCloud9を動かすEC2インスタンス or VMへの接続方式は以下の3種類があります。
- ダイレクトアクセス
- Systems Manager経由
- SSH接続
この記事ではSSH接続方式の場合のCloud9のセットアップ手順を説明します。
結論としては面倒なので、EC2インスタンスタイプで特にこの方式を採用するメリットはないと思います。しいて言えばCloud9をEC2インスタンス以外で動作させたい場合はこの方式になるのではないでしょうか。
手順
インスタンス作成
インスタンス作成
#設定が必要なパラメータ PROFILE="<対象アカウントのプロファイル(デフォルトプロファイル利用時はdefaultを指定)>" REGION="<インスタンスを作成するリージョンのコード。東京リージョンならap-northeast-1>" SUBNET_ID="<パブリックサブネットのID>" SG_ID="<インバウンドでsshを許可しているセキュリティーグループのID>" KEYNAME="<EC2インスタンスにSSHログインするためのキーペア名>" #基本固定で良いパラメータ INSTANCE_TYPE="t2.micro" #AMI ID取得(ubuntuイメージ利用) UBUNTU_AMI_ID=$(aws --profile ${PROFILE} --region ${REGION} --output text \ ec2 describe-images \ --filters 'Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-????????' \ 'Name=state,Values=available' \ --query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ); echo " UBUNTU_AMI_ID = ${UBUNTU_AMI_ID} " #タグ設定 TAGJSON=' [ { "ResourceType": "instance", "Tags": [ { "Key": "Name", "Value": "Cloud9-SshType" } ] } ]' # サーバの起動 aws --profile ${PROFILE} --region ${REGION} \ ec2 run-instances \ --image-id ${UBUNTU_AMI_ID} \ --instance-type ${INSTANCE_TYPE} \ --key-name ${KEYNAME} \ --subnet-id ${SUBNET_ID} \ --security-group-ids ${SG_ID} \ --associate-public-ip-address \ --tag-specifications "${TAGJSON}" ;
Cloud9用ユーザ準備
インスタンスへのログイン
#作成したインスタンスのPublic IP取得 PUBLIC_IP=$( aws --profile ${PROFILE} --region ${REGION} --output text \ ec2 describe-instances \ --filters \ "Name=instance-state-name,Values=running" \ "Name=tag:Name,Values=Cloud9-SshType" \ --query 'Reservations[].Instances[].PublicIpAddress' ); echo "PUBLIC_IP = ${PUBLIC_IP}" #インスタンスへのssh接続 ssh "ubuntu@${PUBLIC_IP}"
Cloud9用ユーザ追加
sudo adduser --quiet --gid 100 --disabled-password cloud9 Changing the user information for cloud9 Enter the new value, or press ENTER for the default Full Name []: Room Number []: Work Phone []: Home Phone []: Other []: Is the information correct? [Y/n] Y
cloud9ユーザでパスワード無しでのsudoでのroot権限利用が必要なため、sudo設定を追加します。
sudo -i echo 'cloud9 ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/99-cloud9-user exit
Cloud9の前提パッケージセットアップ
Python2.7
デフォルトではPython3しかインストールされていないので、追加でのインストールが必要なはずです。
#pythonの確認 python2 --version #インストールされていない場合は下記コマンドでインストール sudo apt update sudo apt install -y python2
Node.js
恐らくインストールされていないので、Node.jsのインストールが必要なはずです。
#Node.jsの確認(多分コマンドがないはず) node --version #Node.jsのインストール sudo apt update sudo apt install -y nodejs
Cloud9のセットアップ
セットアップに必要なパッケージのインストール
パッケージインストールでgccとmakeを利用するため、先にパッケージをインストールします。
sudo apt update
sudo apt install -y make gcc
Cloud9セットアップ
Cのビルドが走り完了までに数分かかります。
curl -L https://raw.githubusercontent.com/c9/install/master/install.sh | bash
(マネコン)Cloud9サービスでの設定
- マネージメントコンソールでAWS Cloud9を表示します。(リージョンはどこでもOK)
Create environment
でCloud9環境作成のウィザードを開きます- 下図を参照に必要項目を入力し公開鍵をコピーします(
Next step
は進まない)
(ubuntu)Cloud9サービスからのSSH接続設定
コピーした公開鍵を、ubuntsのcloud9ユーザに設定します。
sudo -i -u cloud9 echo "[コピーした公開鍵]" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
(マネコン)environment作成の続き
Next step
を実行します- ssh接続が成功すると確認画面が表示されるので、
Create environment
を実行します。
Pythonで署名付きURLを作成し S3オブジェクトをGET/PUTしてみた
はじめに
この記事は、S3の署名付きURLの学習のために署名付きURLを利用してS3のオブジェクトをPUT/GETしたときの手順をまとめたものです。
ポイントは以下のとおりです。
手順
環境準備
プロファイル設定
#プロファイルとリージョン設定 PROFILE="<利用したいプロファイル名:デフォルトの場合はdefaultを指定>" REGION="<実行したいリージョン:ap-northeast-1など>" aws --profile ${PROFILE} --region ${REGION} sts get-caller-identity
S3バケット作成
#S3バケット作成 GET_BUCKET="xxxxx-get-bucket" PUT_BUCKET="xxxxx-put-bucket" OBJECT="hello-world.txt" aws --profile ${PROFILE} --region ${REGION} s3api create-bucket --bucket "${GET_BUCKET}" --create-bucket-configuration "LocationConstraint=${REGION}" aws --profile ${PROFILE} --region ${REGION} s3api create-bucket --bucket "${PUT_BUCKET}" --create-bucket-configuration "LocationConstraint=${REGION}" #GET用バケットへのオブジェクト配置 echo 'Hello World!!' > ${OBJECT} aws s3 --profile ${PROFILE} --region ${REGION} cp "${OBJECT}" "s3://${GET_BUCKET}" aws s3 --profile ${PROFILE} --region ${REGION} ls "s3://${GET_BUCKET}"
EC2用のインスタンスロール作成
#S3アクセス用のインスタンスロール作成 #IAMロール作成 POLICY='{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }' aws --profile ${PROFILE} \ iam create-role \ --role-name "EC2-PreSignS3Test" \ --assume-role-policy-document "${POLICY}" \ --max-session-duration 43200 # SSM用カスタマー管理ポリシーのアタッチ(SSMでインスタンスログインするためで検証自体としては不要) aws --profile ${PROFILE} \ iam attach-role-policy \ --role-name "EC2-PreSignS3Test" \ --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore #S3アクセス用のインラインポリシー追加 InlinePolicyDocument='{ "Version": "2012-10-17", "Statement": [ { "Sid": "ForGetBucket", "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetObject" ], "Resource": [ "arn:aws:s3:::'"${GET_BUCKET}"'", "arn:aws:s3:::'"${GET_BUCKET}"'/*" ] }, { "Sid": "ForPutBucket", "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::'"${PUT_BUCKET}"'", "arn:aws:s3:::'"${PUT_BUCKET}"'/*" ] } ] }' aws --profile ${PROFILE} \ iam put-role-policy \ --role-name "EC2-PreSignS3Test" \ --policy-name "AllowS3Bucket" \ --policy-document "${InlinePolicyDocument}" #インスタンスプロファイルの作成 aws --profile ${PROFILE} \ iam create-instance-profile \ --instance-profile-name "EC2-PreSignS3Test"; aws --profile ${PROFILE} \ iam add-role-to-instance-profile \ --instance-profile-name "EC2-PreSignS3Test" \ --role-name "EC2-PreSignS3Test" ;
|
EC2用インスタンス作成
PubSubnetID="<インスタンスを作成するパブリックサブネットのID: subnet-xxxx>" SgId="<インスタンスに付与するサブネットID>" KEYNAME="<SSH接続する場合はキーペア指定>" #最新のAmazon Linux2のAMI IDを取得します。 AL2_AMIID=$(aws --profile ${PROFILE} --region ${REGION} --output text \ ec2 describe-images \ --owners amazon \ --filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????.?-x86_64-gp2' \ 'Name=state,Values=available' \ --query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ) ; echo -e "PubSubnetID = ${PubSubnetID}\nSgId = ${SgId}\nKEYNAME = ${KEYNAME}\nAL2_AMIID = ${AL2_AMIID}" #インスタンスの作成 #インスタンスタイプ設定 INSTANCE_TYPE="t2.micro" #タグ設定 TAGJSON=' [ { "ResourceType": "instance", "Tags": [ { "Key": "Name", "Value": "PreSignS3Test" } ] } ]' # サーバの起動 aws --profile ${PROFILE} --region ${REGION} \ ec2 run-instances \ --image-id ${AL2_AMIID} \ --instance-type "t2.micro" \ --subnet-id ${PubSubnetID} \ --security-group-ids ${SgId} \ --associate-public-ip-address \ --tag-specifications "${TAGJSON}" \ --iam-instance-profile "Name=EC2-PreSignS3Test" \ --key-name ${KEYNAME} ; #SSH接続しない場合はこの行を削除する
インスタンス上でのAWS CLI設定
#AWS CLI環境の設定 REGION=$(TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//') aws configure set region ${REGION} aws configure set output json #接続確認 aws sts get-caller-identity
S3署名付きURLでのオブジェクト取得(GET)
AWS CLIでのオブジェクト取得確認
#S3バケット情報の設定 GET_BUCKET="xxxxx-get-bucket" OBJECT="hello-world.txt" #AWS CLIでのオブジェクト確認(ファイル一覧にオブジェクトが表示されること) aws s3 ls "s3://${GET_BUCKET}" #AWS CLIでのオブジェクト取得確認 aws s3 cp "s3://${GET_BUCKET}/${OBJECT}" .
署名付きURLでのオブジェクト取得用のpythonスクリプト配置
- python3とboto3のセットアップ
sudo yum -y install python3
sudo pip3 install boto3
get.py
というファイル名で以下のファイルを格納
#!/usr/bin/env python3 import sys import boto3 #引数からバケットとオブジェクト情報を取得 BUCKET_NAME = sys.argv[1] OBJECT_KEY = sys.argv[2] EXPIRESIN = sys.argv[3] url = boto3.client('s3').generate_presigned_url( ClientMethod='get_object', Params={'Bucket': BUCKET_NAME, 'Key': OBJECT_KEY }, ExpiresIn=EXPIRESIN) print(url)
- 以下のコマンドを実行して署名付きURLを生成
python3 get.py ${GET_BUCKET} ${OBJECT} 60
put.py
というファイル名で以下のファイルを格納
#!/usr/bin/env python3 import sys import boto3 #引数からバケットとオブジェクト情報を取得 BUCKET_NAME = sys.argv[1] OBJECT_KEY = sys.argv[2] EXPIRESIN = sys.argv[3] url = boto3.client('s3').generate_presigned_url( ClientMethod='put_object', Params={'Bucket': BUCKET_NAME, 'Key': OBJECT_KEY }, ExpiresIn=EXPIRESIN) print(url)
python3 put.py ${PUT_BUCKET} ${OBJECT} 60
curl -X PUT --upload-file <ファイルパス> "<取得したPre-Signed URL>"
IAM Policy Simulatorの結果をJSON/CSV形式で出力するツール
作成したIAMポリシーやPermissions BoundaryのテストのためにIAM Policy Simulatorを利用すると便利ですが、テスト用のIAMアクションをGUIで作成しないといけないとか、結果をJSONやCSV形式の簡易な一覧で取得できない点が悩みでしたので、Pythonで簡単なツールを作ってみました。
使い方
コードは下記のGitHubレポジトリを参照下さい。セットアップ方法も以下のGitHubレポジトリを参照下さい。
評価対象のアクション一覧を準備
IAM Policy Simulatorで評価したいアクション一覧を以下の形式のJSONで準備します。
{ "Action": [ "iam:CreateServiceSpecificCredential", "iam:DeactivateMFADevice", <中略> "iam:DeletePolicyVersion", "iam:ListUserTags" ] } {{< ** IAM Policy Simulatorでの評価 ツールの実行 >|sh| ./simulate_iampolicy.py [-h] [-P PROFILE] [-c] -p POLICY_SOURCE_ARN -a ACTION_LIST_FILE
- 必須オプション
-p POLICY_SOURCE_ARN
: IAMユーザ/グループ/ロールのARNを指定-a ACTION_LIST_FILE
: 評価したいアクション一覧のJSONファイルパスを指定
- 任意オプション
(実行例1) IAMロールに対して、IAMのアクション一覧を評価しJSON形式で出力する
./simulate_iampolicy.py -p 'arn:aws:iam::999999999999:role/RoleName' -a 'actions/iam_all_actions.json'
実行結果
- JSON形式
[ { "EvalActionName": "iam:CreateServiceSpecificCredential", "EvalDecision": "allowed" }, { "EvalActionName": "iam:DeactivateMFADevice", "EvalDecision": "explicitDeny" }, ]
- CSV形式
EvalActionName,EvalDecision iam:CreateServiceSpecificCredential,allowed iam:DeactivateMFADevice,explicitDeny
- 結果内容
EvalActionName
: 評価対象のアクション名EvalDecision
: 評価結果allowed
: アクションを許可explicitDeny
: アクションを明示的に拒否implicitDeny
: アクションを暗黙的に拒否
Amazon Linux2にterraformをセットアップする
Googleで検索すれば記事は多数出てくるのですが、勉強と備忘録のために記録します。
Terraformのセットアップ
Cloud9(Amazon Linux2ベース)はデフォルトでterraformが入ってるので、セットアップはスキップできます。
セットアップする場合は、Terraformのドキュメントにインストール手順が記載されているので、その内容を見ながらセットアップすればOKです。
learn.hashicorp.com
TerraformのYumレポジトリ の登録
Terraformのrpmパッケージは、Terraform提供元のHashiCorpのオフィシャルのyumレポジトリ から取得することができます。(Amazon LinuxではTerraformのパッケージは配布していない)
そのため、まずHashiCorpのオフィシャルのyumレポジトリをyumに登録する必要があります。
- yum-config-managerコマンドのインストール
sudo yum install -y yum-utils
- HashiCorpのオフィシャルのyumレポジトリの追加
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
Terraformのインストール
sudo yum -y install terraform
Terraformのテスト
terraform -help
フォワードプロキシ(NLB+EC2(AutoScaling))を作成するCloudFormation
利用方法
前提条件
(オプション)AWS CLIのための準備
export PROFILE="default" #Specify a profile with AdministratorAccess privileges export REGION="ap-northeast-1" #Specify Region #動作テスト aws --profile ${PROFILE} --region ${REGION} sts get-caller-identity #以下のようにUserID/Account/Arnが表示されればOK { "UserId": "AROAZKIQKBDEIBOE2MGEJ:botocore-session-xxxxxxxxxx", "Account": "999999999999", "Arn": "arn:aws:sts::999999999999:assumed-role/OrganizationAccountAccessRole/botocore-session-xxxxxxxxxx" }
コードのダウンロード
git clone https://github.com/Noppy/CFn_ForwardProxy.git
cd CFn_ForwardProxy
設定情報の取得
CloudFormationのスタック作成時のパラメーターに設定する以下の情報を事前に控えておく
- VPC構成情報
- Amazon Linux2(x86_64)のAMI ID
- マネージメントコンソールの場合:
- Amazon EC2のコンソールhttps://console.aws.amazon.com/ec2/ を開く
- From the console dashboard, choose Launch Instance.
Amazon Linux 2 AMI (HVM) - Kernel 5.10, SSD Volume Type
のx86_64
アーキテクチャのAMIを確認する- 表示されているAMI(e.g. `ami-xxxxxxxxxxxxxxxxx`)を控える
- CUIの場合:
- マネージメントコンソールの場合:
AMZ2_AMIID=$(aws --profile ${PROFILE} --region ${REGION} --output text \ ec2 describe-images \ --owners amazon \ --filters 'Name=name,Values=amzn2-ami-kernel-5.10-hvm-2.0.????????.?-x86_64-gp2' \ 'Name=state,Values=available' \ --query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ) ; echo "AMZ2_AMIID = ${AMZ2_AMIID}"
CloudFormationによるデプロイ
- マネージメントコンソールの場合:
- 具体的な操作手順は、CloudFormationのユーザーガイドを参照下さい。
- テンプレートは、
./src/forward_proxy.yaml
- パラメータ: 上記の「設定情報の取得」で確認した情報を設定します。
- CUIの場合:
# 「設定情報の取得」で確認した情報を設定 VPCID="<VPC ID>" PubSubIds="<PubSub1Id>,<PubSub2Id>,<Pubsub3Id>" ElbSubIds="<ElbSub1Id>,<Elbsub2Id>,<ElbSub3Id>" SrcCidr="<CIDR of VPC>" # パラメータ用のJSON生成 CFN_STACK_PARAMETERS=' [ { "ParameterKey": "VpcId", "ParameterValue": "'"${VPCID}"'" }, { "ParameterKey": "PublicSubnets", "ParameterValue": "'"${PubSubIds}"'" }, { "ParameterKey": "ElbSubnets", "ParameterValue": "'"${ElbSubIds}"'" }, { "ParameterKey": "ProxyAmiId", "ParameterValue": "'"${AMZ2_AMIID}"'" }, { "ParameterKey": "AllowCidrBlockForProxy", "ParameterValue": "'"${SrcCidr}"'" } ]' # スタックの作成 aws --profile ${PROFILE} --region ${REGION} \ cloudformation create-stack \ --stack-name "ForwardProxy" \ --template-body "file://./src/forward_proxy.yaml" \ --parameters "${CFN_STACK_PARAMETERS}" \ --capabilities CAPABILITY_IAM ;
NLBのDNS取得
- マネージメントコンソールの場合:
- 作成したスタックの
Outputs
で確認する
- 作成したスタックの
- CUIの場合:
ProxyDns=$(aws --profile ${PROFILE} --region ${REGION} --output text \ cloudformation describe-stacks \ --stack-name "ForwardProxy" \ --query 'Stacks[].Outputs[?OutputKey==`LoadBalancerDns`].[OutputValue]') echo "ProxyDns = ${ProxyDns}"
テスト
Linuxサーバをクライアントとしてテストする場合の手順をいかに示します。
ProxyDns="<「NLBのDNS取得」で取得したDNS情報>" export http_proxy="http://${ProxyDns}:3128" export https_proxy="http://${ProxyDns}:3128" # Test # "https://www.google.co.jp" is allowed, "https://www.yahoo.co.jp" is denied. curl https://www.google.co.jp curl https://www.yahoo.co.jp
Amazon Linux2にCloudWatchエージェントを設定する手順(ユーザデータでの手順あり)
- はじめに
- CloudWatchエージェントとは*1
- CloudWatchエージェント設定手順概要
- CloudWatchエージェントの初期設定手順
- (事前準備) IAMロール&EC2インスタンスの作成
- CloudWatchエージェントのインストール
- CloudWatch設定ファイル作成
- CloudWatch設定ファイルのフェッチ
- CloudWatchエージェントの起動*5
- 補足
- 設定フェッチと再起動を1コマンドで実行する
- CloudWatchエージェントのログファイル
- Systems Manager Parameter Storeで設定を配布する場合
- Parameter Storeへの設定ファイル格納
- CloudWatchエージェントを稼働させるAmazon Linux2サーバでの操作
- ユーザデータでCloudWatchエージェントを設定する
はじめに
Amazon Linux2にCloudWatchエージェントをセットアップする手順をまとめました。ドキュメントではSSMから操作する手順をメインにしていますが、AutoScalingなどでUserDataにセットアップ手順を埋め込むことを考慮し全てコマンドラインでセットアップが完結するように手順を整理しています。
ポイントは以下の4点です。
- エージェントの操作は
amazon-cloudwatch-agent-ctl
を利用する - Wizardや手動作成した設定ファイルはフェッチしないと有効化されない
- OS自動起動は
amazon-cloudwatch-agent-ctl
からのエージェント起動時に自動設定される collectd
を未使用時でも、Wizardではデフォルトcollectdを有効化するためcollectdパケージをインストールしておくほうが無難
なおCloudWatchエージェントの標準のカスタムメトリクスとログ取得の範囲で利用している場合は、collectdとStatsDは必要ありません。
CloudWatchエージェントとは*1
CloudWatchエージェントは、EC2やオンプレのLinux/Windowsで稼働し、OSやアプリケーションの情報をCloudWatchに送信するエージェントソフトウェアです。
具体的には以下の情報をCloudWatchに送信することができます。
- OSの稼働情報(CPU/メモリ/ディスクなど)を取得し、カスタムメトリクスとしてCloudWatchへ送信する
- (Option)CloudWatch エージェントで定義されていない稼働情報は、
collectdプロトコル
やStatsDプロトコル
を介して取得することでカスタムメトリクスとしてCloudWatchへ送信する事が可能 - (Option)指定したログファイルをCloudWatch Logsへ送信する

なおcollectd
とStatsD
の要否は以下の通りです。
CloudWatchエージェントの標準のカスタムメトリクスとログ取得の範囲で利用している場合は、どちらの機能も不要となります。
collectd
: CloudWatchエージェントで準備されているメトリクス(CPU/メモリ/ディスク)以外に追加のメトリクスを独自取得したい場合に利用するStatsD
: ユーザアプリケーションから出力される稼働データをCloudWatchエージェントからカスタムメトリクスとして送信したい場合(ユーザアプリでStatsDプロトコルでの送信の実装が必要)
CloudWatchエージェント設定手順概要
CloudWatchエージェントは、Amazon Linux2の場合/opt/aws/amazon-cloudwatch-agent
にインストールされ、操作用のコマンドは/opt/aws/amazon-cloudwatch-agent/bin
に配置されます。主に利用するコマンドは、(1)設定ファイル生成用ウィザードのamazon-cloudwatch-agent-ctl
、の2つになります。
CloudWatchエージェントを利用するための手順概要は以下の通りです。
- CloudWatchエージェントのインストール
- 設定ファイルの作成(手動または
amazon-cloudwatch-agent-config-wizardによる作成) - 設定ファイルのフェッチ
- CloudWatchエージェントの起動

*1:参考: Collecting metrics and logs from Amazon EC2 instances and on-premises servers with the CloudWatch agent - Amazon CloudWatch
AutoScaling Groupや起動テンプレートでEC2インスタンスの送信元/送信先チェックを変更する方法
EC2インスタンスの送信元/送信先チェック(source/destination checking)を、AutoScalingするインスタンスに設定しようとしても、Auto Scalingグループや起動テンプレートでは、送信元/送信先チェックの設定用のパラメータがないため設定できない。そのため、インスタンスのユーザデータでインスタンスIDとリージョン情報を取得して無理くり実行するしかない。
ということで起動サンプルが以下です。
設定
ユーザデータ
ユーザでは、EC2インスタンスのメタデータからインスタンスIDとリージョン情報を取得して、AWS CLIを利用し自分自身のEC2インスタンスの設定変更を行います。
こちらでは、Instance Metadata Service Version 2 (IMDSv2)に対応した書き方になっています。
#!/bin/sh # Disable Source/Destination Check yum -y install jq INSTANCE_ID=$( TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v "http://169.254.169.254/latest/meta-data/instance-id"); REGION=$( TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v "http://169.254.169.254/latest/dynamic/instance-identity/document" | \ jq -r '.region' ) aws --region "${REGION}" ec2 modify-instance-attribute --instance-id "${INSTANCE_ID}" --source-dest-check '{"Value": false}'