func runCommand(instList *SSMInstances, command string, dryRun bool) (*CommandInvocations, error) {
	regionInstanceIds := make(map[string][]string)
	regionInstanceNames := make(map[string][]string)
	for _, instance := range *instList {
		regionInstanceIds[instance.Region] = append(regionInstanceIds[instance.Region], instance.InstanceID)
		regionInstanceNames[instance.Region] = append(regionInstanceNames[instance.Region], instance.Name)
	}
	cmdInvocationsCombined := new(CommandInvocations)
	if dryRun {
		return cmdInvocationsCombined, nil
	}
	var wg sync.WaitGroup
	for region, instanceIds := range regionInstanceIds {
		wg.Add(1)
		terminal.Delta("Sending Command [" + command + "] to instances [" + strings.Join(regionInstanceNames[region], ", ") + "] in [" + region + "]!")
		go func(region string, instanceIds []string, command string) {
			defer wg.Done()
			sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
			svc := ssm.New(sess)
			params := &ssm.SendCommandInput{
				DocumentName: aws.String("AWS-RunShellScript"),
				InstanceIds:  aws.StringSlice(instanceIds),
				Parameters: map[string][]*string{
					"commands": {
						aws.String(command),
					},
				},
				Comment: aws.String("awsm sendCommand: " + command),
			}
			resp, err := svc.SendCommand(params)
			if err != nil {
				terminal.ErrorLine(err.Error())
				return
			} else {
				terminal.Information("Sent Command [" + command + "] [" + aws.StringValue(resp.Command.CommandId) + "] to instances [" + strings.Join(regionInstanceNames[region], ", ") + "] in [" + region + "]!")
			}
			targetCount := int(aws.Int64Value(resp.Command.TargetCount))
			for {
				cmdInvocations, err := GetRegionCommandInvocationsByCommandID(region, aws.StringValue(resp.Command.CommandId), true)
				if err != nil {
					terminal.ErrorLine(err.Error())
					break
				}
				if len(cmdInvocations) != targetCount || !cmdInvocations.Finished() {
					terminal.Notice("Waiting for response from [" + region + "]..")
					time.Sleep(time.Second * 10)
				} else {
					terminal.Information("Recieved a response from [" + region + "]!")
					*cmdInvocationsCombined = append(*cmdInvocationsCombined, cmdInvocations...)
					break
				}
			}
		}(region, instanceIds, command)
	}
	wg.Wait()
	return cmdInvocationsCombined, nil
}
private function without the confirmation terminal prompts
package aws
import (
	"errors"
	"fmt"
	"os"
	"reflect"
	"regexp"
	"strings"
	"sync"
	"time"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ssm"
	humanize "github.com/dustin/go-humanize"
	"github.com/murdinc/awsm/models"
	"github.com/murdinc/terminal"
	"github.com/olekukonko/tablewriter"
)
var ssmRegions = []string{
	"us-east-1", "us-east-2", "us-west-1", "us-west-2",
	"ap-southeast-1", "ap-southeast-2", "ap-northeast-1",
	"ap-northeast-2", "eu-central-1", "eu-west-1", "sa-east-1",
}
type Inventory []Entity
type Entity models.Entity
type SSMInstances []SSMInstance
type SSMInstance models.SSMInstance
type CommandInvocations []CommandInvocation
type CommandInvocation models.CommandInvocation
type CommandPlugins []CommandPlugin
type CommandPlugin models.CommandPlugin
func GetSSMInstanceById(region, id string) (SSMInstance, error) {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ssm.New(sess)
	params := &ssm.DescribeInstanceInformationInput{
		InstanceInformationFilterList: []*ssm.InstanceInformationFilter{
			{
				Key: aws.String("InstanceIds"),
				ValueSet: []*string{
					aws.String(id),
				},
			},
		},
	}
	result, err := svc.DescribeInstanceInformation(params)
	if err != nil {
		return SSMInstance{}, err
	}
	if len(result.InstanceInformationList) == 0 {
		return SSMInstance{}, errors.New("No SSM Instances found matching instance ID [" + id + "] in [" + region + "].")
	}
	instList := new(Instances)
	GetRegionInstances(region, instList, "", true)
	instances := make(SSMInstances, len(result.InstanceInformationList))
	for i, inst := range result.InstanceInformationList {
		instances[i].Marshal(inst, region, instList)
	}
	return instances[0], err
}
func GetSSMInstances(search string) (*SSMInstances, []error) {
	var wg sync.WaitGroup
	var errs []error
	ssmInstList := new(SSMInstances)
	for _, region := range ssmRegions {
		wg.Add(1)
		go func(region string) {
			defer wg.Done()
			err := GetRegionSSMInstances(region, ssmInstList, search)
			if err != nil {
				terminal.ShowErrorMessage(fmt.Sprintf("Error gathering instance list for region [%s]", region), err.Error())
				errs = append(errs, err)
			}
		}(region)
	}
	wg.Wait()
	return ssmInstList, errs
}
func GetRegionSSMInstances(region string, ssmInstList *SSMInstances, search string) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ssm.New(sess)
	result, err := svc.DescribeInstanceInformation(&ssm.DescribeInstanceInformationInput{})
	if err != nil {
		return err
	}
	instList := new(Instances)
	GetRegionInstances(region, instList, "", true)
	instances := make(SSMInstances, len(result.InstanceInformationList))
	for i, inst := range result.InstanceInformationList {
		instances[i].Marshal(inst, region, instList)
	}
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, in := range instances {
			rInst := reflect.ValueOf(in)
			for k := 0; k < rInst.NumField(); k++ {
				sVal := rInst.Field(k).String()
				if term.MatchString(sVal) {
					*ssmInstList = append(*ssmInstList, instances[i])
					continue Loop
				}
			}
		}
	} else {
		*ssmInstList = append(*ssmInstList, instances[:]...)
	}
	return nil
}
func GetInventory(search string) (*Inventory, []error) {
	var wg sync.WaitGroup
	var errs []error
	invList := new(Inventory)
	for _, region := range ssmRegions {
		wg.Add(1)
		go func(region string) {
			defer wg.Done()
			err := GetRegionInventory(region, invList, search)
			if err != nil {
				terminal.ShowErrorMessage(fmt.Sprintf("Error gathering inventory list for region [%s]", region), err.Error())
				errs = append(errs, err)
			}
		}(region)
	}
	wg.Wait()
	return invList, errs
}
func GetRegionInventory(region string, invList *Inventory, search string) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ssm.New(sess)
	result, err := svc.GetInventory(&ssm.GetInventoryInput{})
	if err != nil {
		return err
	}
	instList := new(Instances)
	GetRegionInstances(region, instList, "", true)
	inventory := make(Inventory, len(result.Entities))
	for i, entity := range result.Entities {
		inventory[i].Marshal(entity, region, instList)
	}
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, in := range inventory {
			rInst := reflect.ValueOf(in)
			for k := 0; k < rInst.NumField(); k++ {
				sVal := rInst.Field(k).String()
				if term.MatchString(sVal) {
					*invList = append(*invList, inventory[i])
					continue Loop
				}
			}
		}
	} else {
		*invList = append(*invList, inventory[:]...)
	}
	return nil
}
func ListCommandInvocations(search string, details bool) (*CommandInvocations, []error) {
	var wg sync.WaitGroup
	var errs []error
	cmdInvocationsList := new(CommandInvocations)
	for _, region := range ssmRegions {
		wg.Add(1)
		go func(region string) {
			defer wg.Done()
			err := GetRegionCommandInvocations(region, cmdInvocationsList, search, details)
			if err != nil {
				terminal.ShowErrorMessage(fmt.Sprintf("Error gathering command invocations list for region [%s]", region), err.Error())
				errs = append(errs, err)
			}
		}(region)
	}
	wg.Wait()
	return cmdInvocationsList, errs
}
func GetRegionCommandInvocations(region string, cmdInvocationsList *CommandInvocations, search string, details bool) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ssm.New(sess)
	result, err := svc.ListCommandInvocations(&ssm.ListCommandInvocationsInput{
		Details: aws.Bool(details),
	})
	if err != nil {
		return err
	}
	instList := new(Instances)
	GetRegionInstances(region, instList, "", false)
	cmdInvo := make(CommandInvocations, len(result.CommandInvocations))
	for i, invocation := range result.CommandInvocations {
		cmdInvo[i].Marshal(invocation, region, instList)
	}
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, in := range cmdInvo {
			rInst := reflect.ValueOf(in)
			for k := 0; k < rInst.NumField(); k++ {
				sVal := rInst.Field(k).String()
				if term.MatchString(sVal) {
					*cmdInvocationsList = append(*cmdInvocationsList, cmdInvo[i])
					continue Loop
				}
			}
		}
	} else {
		*cmdInvocationsList = append(*cmdInvocationsList, cmdInvo[:]...)
	}
	return nil
}
func GetRegionCommandInvocationsByCommandID(region string, commandId string, details bool) (CommandInvocations, error) {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ssm.New(sess)
	result, err := svc.ListCommandInvocations(&ssm.ListCommandInvocationsInput{
		CommandId: aws.String(commandId),
		Details:   aws.Bool(details),
	})
	if err != nil {
		return CommandInvocations{}, err
	}
	if len(result.CommandInvocations) == 0 {
		return CommandInvocations{}, nil
	}
	instList := new(Instances)
	GetRegionInstances(region, instList, "", false)
	cmdInvocations := make(CommandInvocations, len(result.CommandInvocations))
	for i, invocation := range result.CommandInvocations {
		cmdInvocations[i].Marshal(invocation, region, instList)
	}
	return cmdInvocations, nil
}
func RunCommand(search, command string, dryRun bool) (*CommandInvocations, error) {
	if dryRun {
		terminal.Information("--dry-run flag is set, not making any actual changes!")
	}
	instList, errs := GetSSMInstances(search)
	if errs != nil {
		return &CommandInvocations{}, errors.New("Error gathering Instance list")
	}
	if len(*instList) > 0 {
		instList.PrintTable()
	} else {
		return &CommandInvocations{}, errors.New("No SSM Instances found matching your search term, Aborting!")
	}
	if !terminal.PromptBool("Are you sure you want to run the command [" + command + "] on these instances?") {
		return &CommandInvocations{}, errors.New("Aborting!")
	}
	commandInvocations, err := runCommand(instList, command, dryRun)
	if err != nil {
		return commandInvocations, err
	}
	terminal.Information("Done!")
	return commandInvocations, nil
}