0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CodeBuildを使ったEC2インスタンス等のリソース状態変更処理

Posted at

定型的なデプロイ作業。これの1つ1つを自動にしたいと考えていて。
大抵そういう場合Lambdaを使うが、わざわざリソースの状態を変更したいがために、Pythonなどを覚えて、エラーハンドリングまで考えて作りこむことは何か時間の無駄な気がしていて。awscliコマンドでできることを、何を頑張ってPythonやらのソースコードで作りこむのか?という疑問があり、そこからこの発想が思い浮かんだ。

LambdaもCodeBuildと同じくコンテナを動かしてコードを動かすが、Lambdaはawscliが利用できない。CodeBuildならそのあたりができるため、いざ活用。

image.png

「プロジェクトを作成」で簡単に作れます。

指定したEC2インスタンスのシャットダウン

前提として、EC2インスタンスの名前付与にNameタグを利用している。
プロジェクト作成で、CodeBuildをよしなに作る。OS等は既定値のAL2023を指定、最低スペックでよい。権限はこのビルドプロジェクト作成後にできるIAMロールに付与していく。EC2FullAccessを付与したり、お好みで最小権限などにしてみてください。
BuildSpec.ymlに以下を書くと、特定のEC2インスタンスに対するシャットダウン処理が完成。

buildspec.yml
version: 0.2
phases:
   install:
     commands:
       - echo install aws cli v2
       - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
       - unzip -q awscliv2.zip
       - ./aws/install --bin-dir /root/.pyenv/shims --install-dir /usr/local/aws-cli --update
   pre_build:
     commands:
       - echo ${EC2_NAME}
       - export INSTANCE_ID=`aws ec2 describe-instances --filter "Name=tag:Name,Values=${EC2_NAME}" --query "Reservations[].Instances[?State.Name!='terminated'].InstanceId" --output text | column -t`
       - export EC2_STATUS=`aws ec2 describe-instances --filter "Name=tag:Name,Values=${EC2_NAME}" --query "Reservations[].Instances[?State.Name!='terminated'].State.Name" --output text`
       - echo "EC2 instance ${EC2_NAME} is ${INSTANCE_ID} . The status is ${EC2_STATUS}"
   build:
     commands:
       - echo "EC2 instance ${EC2_NAME} is ${INSTANCE_ID}. Shutdown."
       - aws ec2 stop-instances --instance-ids ${INSTANCE_ID}
   post_build:
     commands:
       - sleep 10
       - export EC2_STATUS=`aws ec2 describe-instances --filter "Name=tag:Name,Values=${EC2_NAME}" --query "Reservations[].Instances[?State.Name!='terminated'].State.Name" --output text`
       - echo "EC2 instance ${EC2_NAME} is ${INSTANCE_ID} . The status is ${EC2_STATUS}"

CodeBuildの環境変数には以下を作る。

名前 タイプ
EC2_NAME 検索するインスタンスNameタグ PLAINTEXT


Nameタグをつけておらず、インスタンスID直指定する場合は、以下のような環境変数を作る。

名前 タイプ
INSTANCE_ID i-XXXX(対象のインスタンスID) PLAINTEXT

Nameタグをつけておらず、インスタンスID直指定する場合は、buildspecも以下に変更。

buildspec.yml(インスタンスID直指定)
version: 0.2
phases:
   install:
     commands:
       - echo install aws cli v2
       - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
       - unzip -q awscliv2.zip
       - ./aws/install --bin-dir /root/.pyenv/shims --install-dir /usr/local/aws-cli --update
   build:
     commands:
       - aws ec2 stop-instances --instance-ids ${INSTANCE_ID}
   post_build:
     commands:
       - echo "EC2 instance ${INSTANCE_ID}. Shutdown."

よく使う細かいビルド設定

同時実行数の制限

今回のようなシャットダウン処理は多重化されると困るため、この設定を入れておく。
image.png

DockerLayerCache有効化

中身はDockerコンテナという事で、コンテナのキャッシュを有効にしておく。これにより繰り返し処理が早くなる。
image.png

コンテナの設定

image.png
基本的に上記のような既定値でよいが、イメージやイメージのバージョンは以下のように最新を使うようにする。変にバージョンを固定すると、起動が遅くなる。

image.png

カスタムイメージ

Dockerが作成できるなら、カスタムイメージも登録してデプロイ可能。
image.png

作成したDockerイメージを、ECRに登録してCodeBuildで指定する。
image.png

既定値のコンテナよりも高速に動くので、余裕がある人はカスタムイメージ作成をおすすめする。

ELBのターゲット除外

これもbuildspecで以下のように記載できる。わたしの環境はターゲットグループの登録方法がIPアドレスなので、インスタンスで登録している場合は環境に応じてコマンドを要修正。

buildspec.yml
version: 0.2
phases:
   install:
     commands:
       - echo install aws cli v2
       - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
       - unzip -q awscliv2.zip
       - ./aws/install --bin-dir /root/.pyenv/shims --install-dir /usr/local/aws-cli --update
   pre_build:
     commands:
       - export TZ="Asia/Tokyo"
       - echo "elb target check"
       - aws elbv2 describe-target-health --target-group-arn ${ELBTG} --query 'TargetHealthDescriptions[].{Id:Target.Id,Port:Target.Port,State:TargetHealth.State}' --output text | column -t
   build:
     commands:
       - echo "ELBTG target deregister ${TARGET_IP}"
       - aws elbv2 deregister-targets --target-group-arn ${ELBTG} --targets Id=${TARGET_IP}
   post_build:
     commands:
       - echo "ELBTG target check"
       - aws elbv2 describe-target-health --target-group-arn ${ELBTG} --query 'TargetHealthDescriptions[].{Id:Target.Id,Port:Target.Port,State:TargetHealth.State}' --output text | column -t

CodeBuildの環境変数には以下を作る。

名前 タイプ
ELBTG ターゲットグループのARN(arn…) PLAINTEXT
TARGET_IP 除外するターゲットIP PLAINTEXT


ELBのターゲット登録

ELBのターゲットグループからの除外とは反対に今度は登録。
これもIPアドレス登録の場合なので、インスタンス登録の場合は要修正。

buildspec.yml
version: 0.2
phases:
   install:
     commands:
       - echo install aws cli v2
       - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
       - unzip -q awscliv2.zip
       - ./aws/install --bin-dir /root/.pyenv/shims --install-dir /usr/local/aws-cli --update
   pre_build:
     commands:
       - export TZ="Asia/Tokyo"
       - echo "ELBTG target check"
       - aws elbv2 describe-target-health --target-group-arn ${ELBTG} --query 'TargetHealthDescriptions[].{Id:Target.Id,Port:Target.Port,State:TargetHealth.State}' --output text | column -t
   build:
     commands:
       - echo "ELBTG target register ${TARGET_IP}"
       - aws elbv2 register-targets --target-group-arn ${ELBTG} --targets Id=${TARGET_IP},Port=${PORT}
   post_build:
     commands:
       - echo "ELBTG target check"
       - aws elbv2 describe-target-health --target-group-arn ${ELBTG} --query 'TargetHealthDescriptions[].{Id:Target.Id,Port:Target.Port,State:TargetHealth.State}' --output text | column -t

CodeBuildの環境変数には以下を作る。

名前 タイプ
ELBTG ターゲットグループのARN(arn…) PLAINTEXT
TARGET_IP 登録するターゲットIP PLAINTEXT
PORT 登録するポート番号 PLAINTEXT

登録時はポート番号も必要のため、環境変数に忘れずに記載する。


おわりに

このように、わざわざLambdaでプログラム言語を覚える間もなく、簡単にAWSCLIコマンドで定型的な処理を、冪等性を持たせて作ることができる。おすすめ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?