LoginSignup
0
0

Step Functionsから、EC2上でコマンドを実行する

Posted at

はじめに

Step Functionsを使って、EC2上でコマンドを実行する方法の一つを記事としてまとめます。

概要

  • StateMachineでEC2のコマンドを実行する場合は、Systems ManagerのSendCommandを使用
    • 対象のEC2にはAmazonSSMManagedInstanceCoreを付与
  • SendCommandは実行のみで、完了を待たない
    • そのため、GetCommandInvocationで状態をチェックし、処理が終わるまでループする

コールバックを待つ方法もあるようですが、今回は上記の方法になります。

参考

ソース

概要の仕組みを作成するCloudFormationテンプレートは以下になります。
今回動かすコマンドはbash /home/ssm-user/scripts/start.shで、直書きしています。

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  InstanceId:
    Type: String

Resources:
  SMRole: 
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - states.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: "/"
      Policies:
        - PolicyName: allowSsm
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ssm:SendCommand
                  - ssm:GetCommandInvocation
                Resource: '*'

  SendCommandToEc2StateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties:
      RoleArn: !GetAtt SMRole.Arn
      Definition:
        StartAt: SendCommandToEc2
        States:
          SendCommandToEc2:
            Type: Task
            Resource: arn:aws:states:::aws-sdk:ssm:sendCommand
            Parameters:
              DocumentName: AWS-RunShellScript
              DocumentVersion: "1"
              InstanceIds: 
                - !Ref InstanceId
              MaxConcurrency: "50"
              MaxErrors: "50"
              Parameters:
                workingDirectory:
                  - ""
                executionTimeout:
                  - "3600"
                commands:
                  - "bash /home/ssm-user/scripts/start.sh"
              TimeoutSeconds: 60
            ResultPath: $.SendCommandOut
            Next: Wait
          Wait: 
            Type: Wait
            Seconds: 5
            Next: GetCommandInvocation
          GetCommandInvocation: 
            Type: "Task"
            Parameters: 
              CommandId.$: $.SendCommandOut.Command.CommandId
              InstanceId: !Ref InstanceId
            Resource: arn:aws:states:::aws-sdk:ssm:getCommandInvocation
            ResultPath: $.GetCommandInvocationOut
            Next: Is InProgress
          Is InProgress: 
            Type: Choice
            Choices: 
            - Variable: $.GetCommandInvocationOut.Status
              StringEquals: "InProgress"
              Next: Wait
            Default: Success
          Success: 
            Type: Succeed

作成されるState Machineは以下になります。
image.png

  1. SendCommandToEc2でコマンドを実行
  2. 数秒待機
  3. GetCommandInvocationで、1.の状況を取得
  4. 3.の結果が実行中の場合、2.に遷移。それ以外は正常終了

実行

実行前

概要にも書いたとおり、対象のEC2にはAmazonSSMManagedInstanceCoreを付与しておきます。
また、EC2の中に以下のファイルを作っておきます。

/home/ssm-user/scripts/start.sh
echo "Start Scripts:"`date '+%Y-%m-%d %H:%M:%S'` | tee -a /home/ssm-user/scripts/out.txt
sleep 7
echo "Stop Scripts:"`date '+%Y-%m-%d %H:%M:%S'` | tee -a /home/ssm-user/scripts/out.txt

exit 0

echoを書き込むファイルout.txtは、実行されたかのチェックのために作っているだけです。確認の際、内部からtail -f out.txtで監視していました。
不要であれば削除してください。

State Machine実行結果

実行した結果は以下です。7秒のSleepがかかっており、5秒間隔でチェックしているので、Wait->GetCommandInvocationが2回実行されているのがわかります。

image.png

コマンドの結果もStatusで確認できます。
image.png

エラーも確認できるか確認します。bashを修正してexit 1にします。

/home/ssm-user/scripts/start.sh
echo "Start Scripts:"`date '+%Y-%m-%d %H:%M:%S'` | tee -a /home/ssm-user/scripts/out.txt
sleep 7
echo "Stop Scripts:"`date '+%Y-%m-%d %H:%M:%S'` | tee -a /home/ssm-user/scripts/out.txt

- exit 0
+ exit 1

出力を見るとStatusがFailedであり、エラーがStep Functions側で確認できます。
image.png

おわりに

今回はStep FunctionsからEC2上のコマンドを実行し、結果を確認するStateMachineを作ってみました。
EC2側のコマンドは最小限で済みますが、Step Functionsが若干複雑なものになります。

この記事がどなたかのお役に立てれば幸いです。

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