When running SFTP Gateway in a multi instance configuration, there are times when you need to run a bash command on each instance. Fortunately, commonly used configuration files are stored on EFS, so they have a single point of change. But to apply the configuration changes, you need to restart a service on each EC2 instance.

It’s not practical to SSH into each EC2 instance to run the same commands. Instead, you can use SSM to send a single command to all instances within an autoscaling group.

You need to send the SSM command from your own desktop or bastion host, and you need an AWS profile with proper IAM permissions. For security reasons, the SFTP Gateway instance IAM roles do not have the permissions to send SSM commands.

Defining variables

We pull all the variables to the top, so everything you need to edit is all in once place.

Edit these values to match your use case.

# The AWS profile determines the AWS account and access credentials
export AWS_PROFILE=sftpgateway-dev

COMMAND="sudo service sshd restart"
CLOUDFORMATION_STACK_NAME="my-sftpgw-multi-instance-cf-stack"
COMMENT="this restarts the sshd service"
REGION="us-east-1"

Send the SSM command

The SSM command is kind of wordy, so you want to avoid editing it directly.

Just paste in these two lines into the command line:

ASG_NAME=$(aws cloudformation describe-stack-resources --stack-name $CLOUDFORMATION_STACK_NAME --query 'StackResources[?ResourceType==`AWS::AutoScaling::AutoScalingGroup`][PhysicalResourceId][0]' --output text)
COMMAND_ID=$(aws ssm send-command --document-name "AWS-RunShellScript" --targets Key=tag:aws:autoscaling:groupName,Values=$ASG_NAME --comment "$COMMENT" --parameters commands="$COMMAND" --region $REGION --query Command.CommandId  --output text)

Here’s what’s going on:

  • ASG_NAME: You extract the Autoscaling Group name from the CloudFormation stack.
  • COMMAND_ID: You use SSM to run the bash command you defined earlier. This runs against every EC2 instance within the Autoscaling Group. The command ID is saved to a variable so you can check the status.

Check the status of the command

You can check whether your commands ran successfully:

aws ssm list-command-invocations --command-id $COMMAND_ID --query CommandInvocations

You’ll see the following output:

[
    {
        "Comment": "this restarts the sshd service", 
        "Status": "Success", 
        "InstanceId": "i-0588e705a76619387", 
        "DocumentName": "AWS-RunShellScript"
    }, 
    {
        "Comment": "this restarts the sshd service", 
        "Status": "Success", 
        "InstanceId": "i-09366d26cdbee2af4", 
        "DocumentName": "AWS-RunShellScript"
    }
]