「Systems ManagerでEC2へのMackerel Agentのインストール」をAWS CLIからやってみた

2019.09.30

AWS Loft好きのKyoです。以下をAWS CLIからやってみました。

  • 動作中の複数のEC2インスタンス群(Amazon Linux2)に対してMackerel Agentのインストール
  • バックアップのため、インストールの前後で無停止でAMIを取得
  • インストールはSSMのRun Commandとタグを利用して一括で実施

前提条件

  • SSMが利用できること
  • 対象にNameタグで名前が指定されていること(AMI取得の際に利用します)
  • 対象に任意のタグをつけて良いこと(Run Commandの対象をタグで指定します)
  • 対象にIAMロールがついていないこと
  • SSM利用のためのIAMロールが存在すること(ない場合は作ればOK)

動作確認環境

aws-cli/1.16.232 Python/3.7.3 Darwin/18.7.0 botocore/1.12.222

CLI操作

環境変数の設定

export AWS_DEFAULT_REGION='ap-northeast-1'
export iam_role_name='EnablesEC2ToAccessSystemsManagerRole'
export tag_name='monitoring'
export tag_value='true'

EnablesEC2ToAccessSystemsManagerRoleは任意のSSMが利用可能なロール名に変更してください。

対象のEC2インスタンスのインスタンスIDを配列として環境変数に設定

export TARGET_INSTANCE_IDS=(i-xxx i-yyy)

対象のインスタンスIDを配列で指定します。shellでの配列は(i-xxx i-yyy i-zzz)というスペース区切りです。

対象のインスタンスに対し、タグづけ、無停止AMI取得、SSM操作用のIAMロールのアタッチ

for instance_id in ${TARGET_INSTANCE_IDS[@]};
do
    # Nameを取得
    instance_name=$(\
     aws ec2 describe-instances\
      --instance-ids $instance_id\
      --query 'Reservations[].Instances[].Tags[?Key==`Name`].Value' --output text\
      )\
     && echo $instance_name

    # 作業前AMI名&説明を生成
    export before_install_ami_name=${instance_name}-before-install-$(date +%Y%m%d_%H%M%S)

    # AMIの取得
    aws ec2 create-image \
     --instance-id $instance_id \
     --name $before_install_ami_name\
     --description $before_install_ami_name\
     --no-reboot

    # タグをつける
    aws ec2 create-tags\
     --resources $instance_id\
     --tags Key=$tag_name,Value=$tag_value;

    # ロールをアタッチ
    aws ec2 associate-iam-instance-profile\
     --instance-id $instance_id\
     --iam-instance-profile Name=$iam_role_name
done

SSMのRun Commandによるエージェントインストール

SSMから対象のインスタンスIDが表示されることを確認

aws ssm describe-instance-information\
    --query InstanceInformationList[].InstanceId[]\
    --output text

※ロールをアタッチしてから表示されるまで数分かかるようです。

Run Command用の設定を環境変数に設定

export ssm_command="sudo curl -fsSL https://mackerel.io/file/script/amznlinux/setup-all-yum-v2.sh | MACKEREL_APIKEY=xxxxxxxxxxxxxxxx sh"
export ssm_comment='install-mackerel-agent'

MACKEREL_APIKEYはご自身の環境に合わせて適宜変更してください。

Run Commandの実行

※指定のタグとバリュー(今回は monitoring:true)がついているインスタンスすべてを対象として実行します。

aws ssm send-command\
    --targets Key=tag:$tag_name,Values=$tag_value\
    --document-name "AWS-RunShellScript"\
    --comment  "${ssm_comment}"\
    --parameters commands="${ssm_command}"\
    --output text\
    --cloud-watch-output-config "CloudWatchOutputEnabled=true,CloudWatchLogGroupName=/aws/ssm/AWS-RunShellScript"

インストールが完了したら、MackerelのWeb UIから対象のEC2インスタンスが追加されていることをご確認ください。

インストール後の無停止AMI取得と作業用ロールのデタッチ

for instance_id in ${TARGET_INSTANCE_IDS[@]};
do
    # Nameを取得
    instance_name=$(\
     aws ec2 describe-instances\
      --instance-ids $instance_id\
      --query 'Reservations[].Instances[].Tags[?Key==`Name`].Value'\
      --output text\
     )\
      && echo $instance_name

    # 作業後AMI名&説明を生成
    after_install_ami_name=${instance_name}-after-install-$(date +%Y%m%d_%H%M%S)

    # 無停止でAMIの取得
    aws ec2 create-image \
            --instance-id $instance_id \
            --name $after_install_ami_name\
            --description $after_install_ami_name\
            --no-reboot

    # Assocation IDの取得
    association_id=$(\
    aws ec2 describe-iam-instance-profile-associations\
            --filters "Name=instance-id,Values=$instance_id"\
            --query IamInstanceProfileAssociations[].AssociationId\
            --output text\
    )\
      && echo $association_id

    # IAMロールをデタッチ
    aws ec2 disassociate-iam-instance-profile\
     --association-id $association_id
done

終わりに

1回手順を作ってしまえば、安定かつ効率よくタスクを処理できるCLIって素敵だと思いませんか?定型的なタスクはどんどんCLIからやれるようにしていきたいと思いました。何かの参考になれば幸いです。