Merge pull request #9082 from hashicorp/f-amazon_builder-ssm-session-tunnel-poc

builder/amazon: Add SSM Session Manager as a SSH interface connection
This commit is contained in:
Megan Marsh 2020-05-08 12:40:03 -07:00 committed by GitHub
commit fcef10fd2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 39471 additions and 19 deletions

View File

@ -387,8 +387,8 @@ type RunConfig struct {
// Communicator settings
Comm communicator.Config `mapstructure:",squash"`
// One of `public_ip`, `private_ip`, `public_dns`, or `private_dns`. If
// set, either the public IP address, private IP address, public DNS name
// One of `public_ip`, `private_ip`, `public_dns`, `private_dns` or `session_manager`.
// If set, either the public IP address, private IP address, public DNS name
// or private DNS name will be used as the host for SSH. The default behaviour
// if inside a VPC is to use the public IP address if available, otherwise
// the private IP address will be used. If not in a VPC the public DNS name
@ -398,7 +398,20 @@ type RunConfig struct {
// should be direct, `ssh_interface` must be set to `private_dns` and
// `<region>.compute.internal` included in the `NO_PROXY` environment
// variable.
//
// When using `session_manager` the machine running Packer must have
// the AWS Session Manager Plugin installed and within the users' or system path.
// https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html
// Remote connections via the `session_manager` interface establishes a secure tunnel
// between the local host and the remote host on an available local port to the specified `ssh_port`.
// Upon termination the secure tunnel will be terminated automatically, if however there is a failure in
// terminating the tunnel it will automatically terminate itself after 20 minutes of inactivity.
SSHInterface string `mapstructure:"ssh_interface"`
// Which port to connect the local end of the session tunnel to. If
// left blank, Packer will choose a port for you from available ports.
// This option is only used when `ssh_interface` is set `session_manager`.
SessionManagerPort int `mapstructure:"session_manager_port"`
}
func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
@ -441,10 +454,24 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
c.SSHInterface != "private_ip" &&
c.SSHInterface != "public_dns" &&
c.SSHInterface != "private_dns" &&
c.SSHInterface != "session_manager" &&
c.SSHInterface != "" {
errs = append(errs, fmt.Errorf("Unknown interface type: %s", c.SSHInterface))
}
// Connectivity via Session Manager has a few requirements
if c.SSHInterface == "session_manager" {
if c.Comm.Type == "winrm" {
msg := fmt.Errorf(`session_manager connectivity is not supported with the "winrm" communicator; please use "ssh"`)
errs = append(errs, msg)
}
if c.IamInstanceProfile == "" && c.TemporaryIamInstanceProfilePolicyDocument == nil {
msg := fmt.Errorf(`no iam_instance_profile defined; session_manager connectivity requires a valid instance profile with AmazonSSMManagedInstanceCore permissions. Alternatively a temporary_iam_instance_profile_policy_document can be used.`)
errs = append(errs, msg)
}
}
if c.Comm.SSHKeyPairName != "" {
if c.Comm.Type == "winrm" && c.Comm.WinRMPassword == "" && c.Comm.SSHPrivateKeyFile == "" {
errs = append(errs, fmt.Errorf("ssh_private_key_file must be provided to retrieve the winrm password when using ssh_keypair_name."))
@ -518,7 +545,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
if c.EnableT2Unlimited {
if c.SpotPrice != "" {
errs = append(errs, fmt.Errorf("Error: T2 Unlimited cannot be used in conjuction with Spot Instances"))
errs = append(errs, fmt.Errorf("Error: T2 Unlimited cannot be used in conjunction with Spot Instances"))
}
firstDotIndex := strings.Index(c.InstanceType, ".")
if firstDotIndex == -1 {
@ -534,3 +561,8 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
func (c *RunConfig) IsSpotInstance() bool {
return c.SpotPrice != "" && c.SpotPrice != "0"
}
func (c *RunConfig) SSMAgentEnabled() bool {
hasIamInstanceProfile := c.IamInstanceProfile != "" || c.TemporaryIamInstanceProfilePolicyDocument != nil
return c.SSHInterface == "session_manager" && hasIamInstanceProfile
}

View File

@ -28,6 +28,10 @@ func SSHHost(e ec2Describer, sshInterface string, host string) func(multistep.St
return host, nil
}
if sshInterface == "session_manager" {
return "localhost", nil
}
const tries = 2
// <= with current structure to check result of describing `tries` times
for j := 0; j <= tries; j++ {
@ -85,3 +89,20 @@ func SSHHost(e ec2Describer, sshInterface string, host string) func(multistep.St
return "", errors.New("couldn't determine address for instance")
}
}
// Port returns a function that can be given to the communicator
// for determining the port to use when connecting to an instance.
func Port(sshInterface string, port int) func(multistep.StateBag) (int, error) {
return func(state multistep.StateBag) (int, error) {
if sshInterface != "session_manager" {
return port, nil
}
port, ok := state.GetOk("sessionPort")
if !ok {
return 0, fmt.Errorf("no local port defined for session-manager")
}
return port.(int), nil
}
}

View File

@ -13,6 +13,7 @@ const (
publicIP = "192.168.1.1"
privateDNS = "private.dns.test"
publicDNS = "public.dns.test"
localhost = "localhost"
sshHostTemplate = "custom.host.value"
)
@ -32,11 +33,13 @@ func TestSSHHost(t *testing.T) {
}{
{1, "", "", true, publicDNS, ""},
{1, "", "private_ip", true, privateIP, ""},
{1, "", "session_manager", true, localhost, ""},
{1, "vpc-id", "", true, publicIP, ""},
{1, "vpc-id", "private_ip", true, privateIP, ""},
{1, "vpc-id", "private_dns", true, privateDNS, ""},
{1, "vpc-id", "public_dns", true, publicDNS, ""},
{1, "vpc-id", "public_ip", true, publicIP, ""},
{1, "vpc-id", "session_manager", true, localhost, ""},
{2, "", "", true, publicDNS, ""},
{2, "", "private_ip", true, privateIP, ""},
{2, "vpc-id", "", true, publicIP, ""},

View File

@ -0,0 +1,121 @@
package common
import (
"context"
"encoding/json"
"fmt"
"log"
"os/exec"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/mitchellh/iochan"
)
const sessionManagerPluginName string = "session-manager-plugin"
//sessionCommand is the AWS-SDK equivalent to the command you would specify to `aws ssm ...`
const sessionCommand string = "StartSession"
type SSMDriver struct {
Region string
ProfileName string
Session *ssm.StartSessionOutput
SessionParams ssm.StartSessionInput
SessionEndpoint string
PluginName string
}
// StartSession starts an interactive Systems Manager session with a remote instance via the AWS session-manager-plugin
func (d *SSMDriver) StartSession(ctx context.Context) error {
if d.PluginName == "" {
d.PluginName = sessionManagerPluginName
}
args, err := d.Args()
if err != nil {
err = fmt.Errorf("error encountered validating session details: %s", err)
return err
}
cmd := exec.CommandContext(ctx, d.PluginName, args...)
// Let's build up our logging
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return err
}
// Create the channels we'll use for data
stdoutCh := iochan.DelimReader(stdout, '\n')
stderrCh := iochan.DelimReader(stderr, '\n')
/* Loop and get all our output
This particular logger will continue to run through an entire Packer run.
The decision to continue logging is due to the fact that session-manager-plugin
doesn't give a good way of knowing if the command failed or was successful other
than looking at the logs. Seeing as the plugin is updated frequently and that the
log information is a bit sparse this logger will indefinitely relying on other
steps to fail if the tunnel is unable to be created. If successful then the user
will get more information on the tunnel connection when running in a debug mode.
*/
go func(ctx context.Context, prefix string) {
for {
select {
case <-ctx.Done():
return
case output := <-stderrCh:
if output != "" {
log.Printf("[ERROR] %s: %s", prefix, output)
}
case output := <-stdoutCh:
if output != "" {
log.Printf("[DEBUG] %s: %s", prefix, output)
}
}
}
}(ctx, d.PluginName)
log.Printf("[DEBUG %s] opening session tunnel to instance %q for session %q", d.PluginName, aws.StringValue(d.SessionParams.Target), aws.StringValue(d.Session.SessionId))
if err := cmd.Start(); err != nil {
err = fmt.Errorf("error encountered when calling %s: %s\n", d.PluginName, err)
return err
}
return nil
}
// Args validates the driver inputs before returning an ordered set of arguments to pass to the driver command.
func (d *SSMDriver) Args() ([]string, error) {
if d.Session == nil {
return nil, fmt.Errorf("an active Amazon SSM Session is required before trying to open a session tunnel")
}
// AWS session-manager-plugin requires a valid session be passed in JSON.
sessionDetails, err := json.Marshal(d.Session)
if err != nil {
return nil, fmt.Errorf("error encountered in reading session details %s", err)
}
// AWS session-manager-plugin requires the parameters used in the session to be passed in JSON as well.
sessionParameters, err := json.Marshal(d.SessionParams)
if err != nil {
return nil, fmt.Errorf("error encountered in reading session parameter details %s", err)
}
// Args must be in this order
args := []string{
string(sessionDetails),
d.Region,
sessionCommand,
d.ProfileName,
string(sessionParameters),
d.SessionEndpoint,
}
return args, nil
}

View File

@ -0,0 +1,95 @@
package common
import (
"context"
"fmt"
"strings"
"testing"
"github.com/aws/aws-sdk-go/service/ssm"
)
func TestSSMDriver_StartSession(t *testing.T) {
tt := []struct {
Name string
PluginName string
ErrorExpected bool
}{
{"NonExistingPlugin", "boguspluginname", true},
}
for _, tc := range tt {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
driver := SSMDriver{
Region: "region",
Session: new(ssm.StartSessionOutput),
SessionParams: ssm.StartSessionInput{},
SessionEndpoint: "endpoint",
PluginName: tc.PluginName}
ctx := context.TODO()
err := driver.StartSession(ctx)
if tc.ErrorExpected && err == nil {
t.Fatalf("Executing %q should have failed but instead no error was returned", tc.PluginName)
}
})
}
}
func TestSSMDriver_Args(t *testing.T) {
tt := []struct {
Name string
Session *ssm.StartSessionOutput
ProfileName string
ErrorExpected bool
}{
{
Name: "NilSession",
ErrorExpected: true,
},
{
Name: "NonNilSession",
Session: new(ssm.StartSessionOutput),
ErrorExpected: false,
},
{
Name: "SessionWithProfileName",
Session: new(ssm.StartSessionOutput),
ProfileName: "default",
ErrorExpected: false,
},
}
for _, tc := range tt {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
driver := SSMDriver{
Region: "region",
ProfileName: tc.ProfileName,
Session: tc.Session,
SessionParams: ssm.StartSessionInput{},
SessionEndpoint: "amazon.com/sessions",
}
args, err := driver.Args()
if tc.ErrorExpected && err == nil {
t.Fatalf("SSMDriver.Args with a %q should have failed but instead no error was returned", tc.Name)
}
if tc.ErrorExpected {
return
}
// validate launch script
expectedArgString := fmt.Sprintf(`{"SessionId":null,"StreamUrl":null,"TokenValue":null} %s StartSession %s {"DocumentName":null,"Parameters":null,"Target":null} %s`, driver.Region, driver.ProfileName, driver.SessionEndpoint)
argString := strings.Join(args, " ")
if argString != expectedArgString {
t.Errorf("Expected launch script to be %q but got %q", expectedArgString, argString)
}
})
}
}

View File

@ -0,0 +1,146 @@
package common
import (
"context"
"fmt"
"log"
"strconv"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/hashicorp/packer/common/net"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type StepCreateSSMTunnel struct {
AWSSession *session.Session
Region string
LocalPortNumber int
RemotePortNumber int
SSMAgentEnabled bool
instanceId string
session *ssm.StartSessionOutput
}
// Run executes the Packer build step that creates a session tunnel.
func (s *StepCreateSSMTunnel) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
if !s.SSMAgentEnabled {
return multistep.ActionContinue
}
ui := state.Get("ui").(packer.Ui)
if err := s.ConfigureLocalHostPort(ctx); err != nil {
err := fmt.Errorf("error finding an available port to initiate a session tunnel: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
instance, ok := state.Get("instance").(*ec2.Instance)
if !ok {
err := fmt.Errorf("error encountered in obtaining target instance id for session tunnel")
ui.Error(err.Error())
state.Put("error", err)
return multistep.ActionHalt
}
s.instanceId = aws.StringValue(instance.InstanceId)
log.Printf("Starting PortForwarding session to instance %q on local port %d to remote port %d", s.instanceId, s.LocalPortNumber, s.RemotePortNumber)
input := s.BuildTunnelInputForInstance(s.instanceId)
ssmconn := ssm.New(s.AWSSession)
err := retry.Config{
ShouldRetry: func(err error) bool { return isAWSErr(err, "TargetNotConnected", "") },
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 60 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) (err error) {
s.session, err = ssmconn.StartSessionWithContext(ctx, &input)
return err
})
if err != nil {
err = fmt.Errorf("error encountered in starting session for instance %q: %s", s.instanceId, err)
ui.Error(err.Error())
state.Put("error", err)
return multistep.ActionHalt
}
driver := SSMDriver{
Region: s.Region,
Session: s.session,
SessionParams: input,
SessionEndpoint: ssmconn.Endpoint,
}
if err := driver.StartSession(ctx); err != nil {
err = fmt.Errorf("error encountered in establishing a tunnel %s", err)
ui.Error(err.Error())
state.Put("error", err)
return multistep.ActionHalt
}
ui.Message(fmt.Sprintf("PortForwarding session %q to instance %q has been started", aws.StringValue(s.session.SessionId), s.instanceId))
state.Put("sessionPort", s.LocalPortNumber)
return multistep.ActionContinue
}
// Cleanup terminates an active session on AWS, which in turn terminates the associated tunnel process running on the local machine.
func (s *StepCreateSSMTunnel) Cleanup(state multistep.StateBag) {
ui := state.Get("ui").(packer.Ui)
ssmconn := ssm.New(s.AWSSession)
_, err := ssmconn.TerminateSession(&ssm.TerminateSessionInput{SessionId: s.session.SessionId})
if err != nil {
msg := fmt.Sprintf("Error terminating SSM Session %q. Please terminate the session manually: %s", aws.StringValue(s.session.SessionId), err)
ui.Error(msg)
}
}
// ConfigureLocalHostPort finds an available port on the localhost that can be used for the remote tunnel.
// Defaults to using s.LocalPortNumber if it is set.
func (s *StepCreateSSMTunnel) ConfigureLocalHostPort(ctx context.Context) error {
minPortNumber, maxPortNumber := 8000, 9000
if s.LocalPortNumber != 0 {
minPortNumber = s.LocalPortNumber
maxPortNumber = minPortNumber
}
// Find an available TCP port for our HTTP server
l, err := net.ListenRangeConfig{
Min: minPortNumber,
Max: maxPortNumber,
Addr: "0.0.0.0",
Network: "tcp",
}.Listen(ctx)
if err != nil {
return err
}
s.LocalPortNumber = l.Port
// Stop listening on selected port so that the AWS session-manager-plugin can use it.
// The port is closed right before we start the session to avoid two Packer builds from getting the same port - fingers-crossed
l.Close()
return nil
}
func (s *StepCreateSSMTunnel) BuildTunnelInputForInstance(instance string) ssm.StartSessionInput {
dst, src := strconv.Itoa(s.RemotePortNumber), strconv.Itoa(s.LocalPortNumber)
params := map[string][]*string{
"portNumber": []*string{aws.String(dst)},
"localPortNumber": []*string{aws.String(src)},
}
input := ssm.StartSessionInput{
DocumentName: aws.String("AWS-StartPortForwardingSession"),
Parameters: params,
Target: aws.String(instance),
}
return input
}

View File

@ -0,0 +1,60 @@
package common
import (
"context"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws"
)
func TestStepCreateSSMTunnel_BuildTunnelInputForInstance(t *testing.T) {
step := StepCreateSSMTunnel{
Region: "region",
LocalPortNumber: 8001,
RemotePortNumber: 22,
SSMAgentEnabled: true,
}
input := step.BuildTunnelInputForInstance("i-something")
target := aws.StringValue(input.Target)
if target != "i-something" {
t.Errorf("input should contain instance id as target but it got %q", target)
}
params := map[string][]*string{
"portNumber": []*string{aws.String("22")},
"localPortNumber": []*string{aws.String("8001")},
}
if !reflect.DeepEqual(input.Parameters, params) {
t.Errorf("input should contain the expected port parameters but it got %v", input.Parameters)
}
}
func TestStepCreateSSMTunnel_ConfigureLocalHostPort(t *testing.T) {
tt := []struct {
Name string
Step StepCreateSSMTunnel
PortCheck func(int) bool
}{
{"WithLocalPortNumber", StepCreateSSMTunnel{LocalPortNumber: 9001}, func(port int) bool { return port == 9001 }},
{"WithNoLocalPortNumber", StepCreateSSMTunnel{}, func(port int) bool { return port >= 8000 && port <= 9000 }},
}
for _, tc := range tt {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
step := tc.Step
if err := step.ConfigureLocalHostPort(context.TODO()); err != nil {
t.Errorf("failed to configure a port on localhost")
}
if !tc.PortCheck(step.LocalPortNumber) {
t.Errorf("failed to configure a port on localhost")
}
})
}
}

View File

@ -21,6 +21,7 @@ type StepSecurityGroup struct {
SecurityGroupFilter SecurityGroupFilterOptions
SecurityGroupIds []string
TemporarySGSourceCidrs []string
SkipSSHRuleCreation bool
createdGroupId string
}
@ -76,13 +77,6 @@ func (s *StepSecurityGroup) Run(ctx context.Context, state multistep.StateBag) m
return multistep.ActionContinue
}
port := s.CommConfig.Port()
if port == 0 {
if s.CommConfig.Type != "none" {
panic("port must be set to a non-zero value.")
}
}
// Create the group
groupName := fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID())
ui.Say(fmt.Sprintf("Creating temporary security group for this instance: %s", groupName))
@ -110,15 +104,15 @@ func (s *StepSecurityGroup) Run(ctx context.Context, state multistep.StateBag) m
GroupIds: []*string{aws.String(s.createdGroupId)},
},
)
if err == nil {
log.Printf("[DEBUG] Found security group %s", s.createdGroupId)
} else {
if err != nil {
err := fmt.Errorf("Timed out waiting for security group %s: %s", s.createdGroupId, err)
log.Printf("[DEBUG] %s", err.Error())
state.Put("error", err)
return multistep.ActionHalt
}
log.Printf("[DEBUG] Found security group %s", s.createdGroupId)
// map the list of temporary security group CIDRs bundled with config to
// types expected by EC2.
groupIpRanges := []*ec2.IpRange{}
@ -129,7 +123,15 @@ func (s *StepSecurityGroup) Run(ctx context.Context, state multistep.StateBag) m
groupIpRanges = append(groupIpRanges, &ipRange)
}
// Authorize the SSH access for the security group
// Set some state data for use in future steps
state.Put("securityGroupIds", []string{s.createdGroupId})
if s.SkipSSHRuleCreation {
return multistep.ActionContinue
}
port := s.CommConfig.Port()
// Authorize access for the provided port within the security group
groupRules := &ec2.AuthorizeSecurityGroupIngressInput{
GroupId: groupResp.GroupId,
IpPermissions: []*ec2.IpPermission{
@ -154,9 +156,6 @@ func (s *StepSecurityGroup) Run(ctx context.Context, state multistep.StateBag) m
return multistep.ActionHalt
}
// Set some state data for use in future steps
state.Put("securityGroupIds", []string{s.createdGroupId})
return multistep.ActionContinue
}

View File

@ -239,6 +239,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
SecurityGroupIds: b.config.SecurityGroupIds,
CommConfig: &b.config.RunConfig.Comm,
TemporarySGSourceCidrs: b.config.TemporarySGSourceCidrs,
SkipSSHRuleCreation: b.config.SSMAgentEnabled(),
},
&awscommon.StepIamInstanceProfile{
IamInstanceProfile: b.config.IamInstanceProfile,
@ -255,6 +256,13 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Timeout: b.config.WindowsPasswordTimeout,
BuildName: b.config.PackerBuildName,
},
&awscommon.StepCreateSSMTunnel{
AWSSession: session,
Region: *ec2conn.Config.Region,
LocalPortNumber: b.config.SessionManagerPort,
RemotePortNumber: b.config.Comm.Port(),
SSMAgentEnabled: b.config.SSMAgentEnabled(),
},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,
Host: awscommon.SSHHost(
@ -262,6 +270,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
b.config.SSHInterface,
b.config.Comm.Host(),
),
SSHPort: awscommon.Port(
b.config.SSHInterface,
b.config.Comm.Port(),
),
SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(),
},
&common.StepProvision{},

View File

@ -126,6 +126,7 @@ type FlatConfig struct {
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
SSHInterface *string `mapstructure:"ssh_interface" cty:"ssh_interface"`
SessionManagerPort *int `mapstructure:"session_manager_port" cty:"session_manager_port"`
AMIMappings []common.FlatBlockDevice `mapstructure:"ami_block_device_mappings" required:"false" cty:"ami_block_device_mappings"`
LaunchMappings []common.FlatBlockDevice `mapstructure:"launch_block_device_mappings" required:"false" cty:"launch_block_device_mappings"`
VolumeRunTags common.TagMap `mapstructure:"run_volume_tags" cty:"run_volume_tags"`
@ -259,6 +260,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
"ssh_interface": &hcldec.AttrSpec{Name: "ssh_interface", Type: cty.String, Required: false},
"session_manager_port": &hcldec.AttrSpec{Name: "session_manager_port", Type: cty.Number, Required: false},
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
"launch_block_device_mappings": &hcldec.BlockListSpec{TypeName: "launch_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
"run_volume_tags": &hcldec.AttrSpec{Name: "run_volume_tags", Type: cty.Map(cty.String), Required: false},

View File

@ -262,6 +262,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
SecurityGroupIds: b.config.SecurityGroupIds,
CommConfig: &b.config.RunConfig.Comm,
TemporarySGSourceCidrs: b.config.TemporarySGSourceCidrs,
SkipSSHRuleCreation: b.config.SSMAgentEnabled(),
},
&awscommon.StepIamInstanceProfile{
IamInstanceProfile: b.config.IamInstanceProfile,
@ -278,6 +279,13 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Timeout: b.config.WindowsPasswordTimeout,
BuildName: b.config.PackerBuildName,
},
&awscommon.StepCreateSSMTunnel{
AWSSession: session,
Region: *ec2conn.Config.Region,
LocalPortNumber: b.config.SessionManagerPort,
RemotePortNumber: b.config.Comm.Port(),
SSMAgentEnabled: b.config.SSMAgentEnabled(),
},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,
Host: awscommon.SSHHost(
@ -285,6 +293,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
b.config.SSHInterface,
b.config.Comm.Host(),
),
SSHPort: awscommon.Port(
b.config.SSHInterface,
b.config.Comm.Port(),
),
SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(),
},
&common.StepProvision{},

View File

@ -148,6 +148,7 @@ type FlatConfig struct {
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
SSHInterface *string `mapstructure:"ssh_interface" cty:"ssh_interface"`
SessionManagerPort *int `mapstructure:"session_manager_port" cty:"session_manager_port"`
AMIName *string `mapstructure:"ami_name" required:"true" cty:"ami_name"`
AMIDescription *string `mapstructure:"ami_description" required:"false" cty:"ami_description"`
AMIVirtType *string `mapstructure:"ami_virtualization_type" required:"false" cty:"ami_virtualization_type"`
@ -282,6 +283,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
"ssh_interface": &hcldec.AttrSpec{Name: "ssh_interface", Type: cty.String, Required: false},
"session_manager_port": &hcldec.AttrSpec{Name: "session_manager_port", Type: cty.Number, Required: false},
"ami_name": &hcldec.AttrSpec{Name: "ami_name", Type: cty.String, Required: false},
"ami_description": &hcldec.AttrSpec{Name: "ami_description", Type: cty.String, Required: false},
"ami_virtualization_type": &hcldec.AttrSpec{Name: "ami_virtualization_type", Type: cty.String, Required: false},

View File

@ -238,6 +238,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
SecurityGroupIds: b.config.SecurityGroupIds,
CommConfig: &b.config.RunConfig.Comm,
TemporarySGSourceCidrs: b.config.TemporarySGSourceCidrs,
SkipSSHRuleCreation: b.config.SSMAgentEnabled(),
},
&awscommon.StepIamInstanceProfile{
IamInstanceProfile: b.config.IamInstanceProfile,
@ -255,6 +256,13 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Timeout: b.config.WindowsPasswordTimeout,
BuildName: b.config.PackerBuildName,
},
&awscommon.StepCreateSSMTunnel{
AWSSession: session,
Region: *ec2conn.Config.Region,
LocalPortNumber: b.config.SessionManagerPort,
RemotePortNumber: b.config.Comm.Port(),
SSMAgentEnabled: b.config.SSMAgentEnabled(),
},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,
Host: awscommon.SSHHost(
@ -262,6 +270,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
b.config.SSHInterface,
b.config.Comm.Host(),
),
SSHPort: awscommon.Port(
b.config.SSHInterface,
b.config.Comm.Port(),
),
SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(),
},
&common.StepProvision{},

View File

@ -150,6 +150,7 @@ type FlatConfig struct {
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
SSHInterface *string `mapstructure:"ssh_interface" cty:"ssh_interface"`
SessionManagerPort *int `mapstructure:"session_manager_port" cty:"session_manager_port"`
AMIENASupport *bool `mapstructure:"ena_support" required:"false" cty:"ena_support"`
AMISriovNetSupport *bool `mapstructure:"sriov_support" required:"false" cty:"sriov_support"`
VolumeMappings []FlatBlockDevice `mapstructure:"ebs_volumes" required:"false" cty:"ebs_volumes"`
@ -263,6 +264,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
"ssh_interface": &hcldec.AttrSpec{Name: "ssh_interface", Type: cty.String, Required: false},
"session_manager_port": &hcldec.AttrSpec{Name: "session_manager_port", Type: cty.Number, Required: false},
"ena_support": &hcldec.AttrSpec{Name: "ena_support", Type: cty.Bool, Required: false},
"sriov_support": &hcldec.AttrSpec{Name: "sriov_support", Type: cty.Bool, Required: false},
"ebs_volumes": &hcldec.BlockListSpec{TypeName: "ebs_volumes", Nested: hcldec.ObjectSpec((*FlatBlockDevice)(nil).HCL2Spec())},

View File

@ -324,6 +324,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
SecurityGroupFilter: b.config.SecurityGroupFilter,
SecurityGroupIds: b.config.SecurityGroupIds,
TemporarySGSourceCidrs: b.config.TemporarySGSourceCidrs,
SkipSSHRuleCreation: b.config.SSMAgentEnabled(),
},
&awscommon.StepIamInstanceProfile{
IamInstanceProfile: b.config.IamInstanceProfile,
@ -337,13 +338,26 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Timeout: b.config.WindowsPasswordTimeout,
BuildName: b.config.PackerBuildName,
},
&awscommon.StepCreateSSMTunnel{
AWSSession: session,
Region: *ec2conn.Config.Region,
LocalPortNumber: b.config.SessionManagerPort,
RemotePortNumber: b.config.Comm.Port(),
SSMAgentEnabled: b.config.SSMAgentEnabled(),
},
&communicator.StepConnect{
// StepConnect is provided settings for WinRM and SSH, but
// the communicator will ultimately determine which port to use.
Config: &b.config.RunConfig.Comm,
Host: awscommon.SSHHost(
ec2conn,
b.config.SSHInterface,
b.config.Comm.Host(),
),
SSHPort: awscommon.Port(
b.config.SSHInterface,
b.config.Comm.Port(),
),
SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(),
},
&common.StepProvision{},

View File

@ -126,6 +126,7 @@ type FlatConfig struct {
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
SSHInterface *string `mapstructure:"ssh_interface" cty:"ssh_interface"`
SessionManagerPort *int `mapstructure:"session_manager_port" cty:"session_manager_port"`
AMIMappings []common.FlatBlockDevice `mapstructure:"ami_block_device_mappings" required:"false" cty:"ami_block_device_mappings"`
LaunchMappings []common.FlatBlockDevice `mapstructure:"launch_block_device_mappings" required:"false" cty:"launch_block_device_mappings"`
AccountId *string `mapstructure:"account_id" required:"true" cty:"account_id"`
@ -266,6 +267,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
"ssh_interface": &hcldec.AttrSpec{Name: "ssh_interface", Type: cty.String, Required: false},
"session_manager_port": &hcldec.AttrSpec{Name: "session_manager_port", Type: cty.Number, Required: false},
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
"launch_block_device_mappings": &hcldec.BlockListSpec{TypeName: "launch_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
"account_id": &hcldec.AttrSpec{Name: "account_id", Type: cty.String, Required: false},

37952
vendor/github.com/aws/aws-sdk-go/service/ssm/api.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

45
vendor/github.com/aws/aws-sdk-go/service/ssm/doc.go generated vendored Normal file
View File

@ -0,0 +1,45 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
// Package ssm provides the client and types for making API
// requests to Amazon Simple Systems Manager (SSM).
//
// AWS Systems Manager is a collection of capabilities that helps you automate
// management tasks such as collecting system inventory, applying operating
// system (OS) patches, automating the creation of Amazon Machine Images (AMIs),
// and configuring operating systems (OSs) and applications at scale. Systems
// Manager lets you remotely and securely manage the configuration of your managed
// instances. A managed instance is any Amazon EC2 instance or on-premises machine
// in your hybrid environment that has been configured for Systems Manager.
//
// This reference is intended to be used with the AWS Systems Manager User Guide
// (http://docs.aws.amazon.com/systems-manager/latest/userguide/).
//
// To get started, verify prerequisites and configure managed instances. For
// more information, see Setting Up AWS Systems Manager (http://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-setting-up.html)
// in the AWS Systems Manager User Guide.
//
// For information about other API actions you can perform on Amazon EC2 instances,
// see the Amazon EC2 API Reference (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/).
// For information about how to use a Query API, see Making API Requests (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/making-api-requests.html).
//
// See https://docs.aws.amazon.com/goto/WebAPI/ssm-2014-11-06 for more information on this service.
//
// See ssm package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/ssm/
//
// Using the Client
//
// To contact Amazon Simple Systems Manager (SSM) with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently.
//
// See the SDK's documentation for more information on how to use the SDK.
// https://docs.aws.amazon.com/sdk-for-go/api/
//
// See aws.Config documentation for more information on configuring SDK clients.
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
//
// See the Amazon Simple Systems Manager (SSM) client SSM for more
// information on creating client for this service.
// https://docs.aws.amazon.com/sdk-for-go/api/service/ssm/#New
package ssm

753
vendor/github.com/aws/aws-sdk-go/service/ssm/errors.go generated vendored Normal file
View File

@ -0,0 +1,753 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
package ssm
const (
// ErrCodeAlreadyExistsException for service response error code
// "AlreadyExistsException".
//
// Error returned if an attempt is made to register a patch group with a patch
// baseline that is already registered with a different patch baseline.
ErrCodeAlreadyExistsException = "AlreadyExistsException"
// ErrCodeAssociatedInstances for service response error code
// "AssociatedInstances".
//
// You must disassociate a document from all instances before you can delete
// it.
ErrCodeAssociatedInstances = "AssociatedInstances"
// ErrCodeAssociationAlreadyExists for service response error code
// "AssociationAlreadyExists".
//
// The specified association already exists.
ErrCodeAssociationAlreadyExists = "AssociationAlreadyExists"
// ErrCodeAssociationDoesNotExist for service response error code
// "AssociationDoesNotExist".
//
// The specified association does not exist.
ErrCodeAssociationDoesNotExist = "AssociationDoesNotExist"
// ErrCodeAssociationExecutionDoesNotExist for service response error code
// "AssociationExecutionDoesNotExist".
//
// The specified execution ID does not exist. Verify the ID number and try again.
ErrCodeAssociationExecutionDoesNotExist = "AssociationExecutionDoesNotExist"
// ErrCodeAssociationLimitExceeded for service response error code
// "AssociationLimitExceeded".
//
// You can have at most 2,000 active associations.
ErrCodeAssociationLimitExceeded = "AssociationLimitExceeded"
// ErrCodeAssociationVersionLimitExceeded for service response error code
// "AssociationVersionLimitExceeded".
//
// You have reached the maximum number versions allowed for an association.
// Each association has a limit of 1,000 versions.
ErrCodeAssociationVersionLimitExceeded = "AssociationVersionLimitExceeded"
// ErrCodeAutomationDefinitionNotFoundException for service response error code
// "AutomationDefinitionNotFoundException".
//
// An Automation document with the specified name could not be found.
ErrCodeAutomationDefinitionNotFoundException = "AutomationDefinitionNotFoundException"
// ErrCodeAutomationDefinitionVersionNotFoundException for service response error code
// "AutomationDefinitionVersionNotFoundException".
//
// An Automation document with the specified name and version could not be found.
ErrCodeAutomationDefinitionVersionNotFoundException = "AutomationDefinitionVersionNotFoundException"
// ErrCodeAutomationExecutionLimitExceededException for service response error code
// "AutomationExecutionLimitExceededException".
//
// The number of simultaneously running Automation executions exceeded the allowable
// limit.
ErrCodeAutomationExecutionLimitExceededException = "AutomationExecutionLimitExceededException"
// ErrCodeAutomationExecutionNotFoundException for service response error code
// "AutomationExecutionNotFoundException".
//
// There is no automation execution information for the requested automation
// execution ID.
ErrCodeAutomationExecutionNotFoundException = "AutomationExecutionNotFoundException"
// ErrCodeAutomationStepNotFoundException for service response error code
// "AutomationStepNotFoundException".
//
// The specified step name and execution ID don't exist. Verify the information
// and try again.
ErrCodeAutomationStepNotFoundException = "AutomationStepNotFoundException"
// ErrCodeComplianceTypeCountLimitExceededException for service response error code
// "ComplianceTypeCountLimitExceededException".
//
// You specified too many custom compliance types. You can specify a maximum
// of 10 different types.
ErrCodeComplianceTypeCountLimitExceededException = "ComplianceTypeCountLimitExceededException"
// ErrCodeCustomSchemaCountLimitExceededException for service response error code
// "CustomSchemaCountLimitExceededException".
//
// You have exceeded the limit for custom schemas. Delete one or more custom
// schemas and try again.
ErrCodeCustomSchemaCountLimitExceededException = "CustomSchemaCountLimitExceededException"
// ErrCodeDocumentAlreadyExists for service response error code
// "DocumentAlreadyExists".
//
// The specified document already exists.
ErrCodeDocumentAlreadyExists = "DocumentAlreadyExists"
// ErrCodeDocumentLimitExceeded for service response error code
// "DocumentLimitExceeded".
//
// You can have at most 500 active Systems Manager documents.
ErrCodeDocumentLimitExceeded = "DocumentLimitExceeded"
// ErrCodeDocumentPermissionLimit for service response error code
// "DocumentPermissionLimit".
//
// The document cannot be shared with more AWS user accounts. You can share
// a document with a maximum of 20 accounts. You can publicly share up to five
// documents. If you need to increase this limit, contact AWS Support.
ErrCodeDocumentPermissionLimit = "DocumentPermissionLimit"
// ErrCodeDocumentVersionLimitExceeded for service response error code
// "DocumentVersionLimitExceeded".
//
// The document has too many versions. Delete one or more document versions
// and try again.
ErrCodeDocumentVersionLimitExceeded = "DocumentVersionLimitExceeded"
// ErrCodeDoesNotExistException for service response error code
// "DoesNotExistException".
//
// Error returned when the ID specified for a resource, such as a maintenance
// window or Patch baseline, doesn't exist.
//
// For information about resource limits in Systems Manager, see AWS Systems
// Manager Limits (http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_ssm).
ErrCodeDoesNotExistException = "DoesNotExistException"
// ErrCodeDuplicateDocumentContent for service response error code
// "DuplicateDocumentContent".
//
// The content of the association document matches another document. Change
// the content of the document and try again.
ErrCodeDuplicateDocumentContent = "DuplicateDocumentContent"
// ErrCodeDuplicateDocumentVersionName for service response error code
// "DuplicateDocumentVersionName".
//
// The version name has already been used in this document. Specify a different
// version name, and then try again.
ErrCodeDuplicateDocumentVersionName = "DuplicateDocumentVersionName"
// ErrCodeDuplicateInstanceId for service response error code
// "DuplicateInstanceId".
//
// You cannot specify an instance ID in more than one association.
ErrCodeDuplicateInstanceId = "DuplicateInstanceId"
// ErrCodeFeatureNotAvailableException for service response error code
// "FeatureNotAvailableException".
//
// You attempted to register a LAMBDA or STEP_FUNCTIONS task in a region where
// the corresponding service is not available.
ErrCodeFeatureNotAvailableException = "FeatureNotAvailableException"
// ErrCodeHierarchyLevelLimitExceededException for service response error code
// "HierarchyLevelLimitExceededException".
//
// A hierarchy can have a maximum of 15 levels. For more information, see Requirements
// and Constraints for Parameter Names (http://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-parameter-name-constraints.html)
// in the AWS Systems Manager User Guide.
ErrCodeHierarchyLevelLimitExceededException = "HierarchyLevelLimitExceededException"
// ErrCodeHierarchyTypeMismatchException for service response error code
// "HierarchyTypeMismatchException".
//
// Parameter Store does not support changing a parameter type in a hierarchy.
// For example, you can't change a parameter from a String type to a SecureString
// type. You must create a new, unique parameter.
ErrCodeHierarchyTypeMismatchException = "HierarchyTypeMismatchException"
// ErrCodeIdempotentParameterMismatch for service response error code
// "IdempotentParameterMismatch".
//
// Error returned when an idempotent operation is retried and the parameters
// don't match the original call to the API with the same idempotency token.
ErrCodeIdempotentParameterMismatch = "IdempotentParameterMismatch"
// ErrCodeIncompatiblePolicyException for service response error code
// "IncompatiblePolicyException".
//
// There is a conflict in the policies specified for this parameter. You can't,
// for example, specify two Expiration policies for a parameter. Review your
// policies, and try again.
ErrCodeIncompatiblePolicyException = "IncompatiblePolicyException"
// ErrCodeInternalServerError for service response error code
// "InternalServerError".
//
// An error occurred on the server side.
ErrCodeInternalServerError = "InternalServerError"
// ErrCodeInvalidActivation for service response error code
// "InvalidActivation".
//
// The activation is not valid. The activation might have been deleted, or the
// ActivationId and the ActivationCode do not match.
ErrCodeInvalidActivation = "InvalidActivation"
// ErrCodeInvalidActivationId for service response error code
// "InvalidActivationId".
//
// The activation ID is not valid. Verify the you entered the correct ActivationId
// or ActivationCode and try again.
ErrCodeInvalidActivationId = "InvalidActivationId"
// ErrCodeInvalidAggregatorException for service response error code
// "InvalidAggregatorException".
//
// The specified aggregator is not valid for inventory groups. Verify that the
// aggregator uses a valid inventory type such as AWS:Application or AWS:InstanceInformation.
ErrCodeInvalidAggregatorException = "InvalidAggregatorException"
// ErrCodeInvalidAllowedPatternException for service response error code
// "InvalidAllowedPatternException".
//
// The request does not meet the regular expression requirement.
ErrCodeInvalidAllowedPatternException = "InvalidAllowedPatternException"
// ErrCodeInvalidAssociation for service response error code
// "InvalidAssociation".
//
// The association is not valid or does not exist.
ErrCodeInvalidAssociation = "InvalidAssociation"
// ErrCodeInvalidAssociationVersion for service response error code
// "InvalidAssociationVersion".
//
// The version you specified is not valid. Use ListAssociationVersions to view
// all versions of an association according to the association ID. Or, use the
// $LATEST parameter to view the latest version of the association.
ErrCodeInvalidAssociationVersion = "InvalidAssociationVersion"
// ErrCodeInvalidAutomationExecutionParametersException for service response error code
// "InvalidAutomationExecutionParametersException".
//
// The supplied parameters for invoking the specified Automation document are
// incorrect. For example, they may not match the set of parameters permitted
// for the specified Automation document.
ErrCodeInvalidAutomationExecutionParametersException = "InvalidAutomationExecutionParametersException"
// ErrCodeInvalidAutomationSignalException for service response error code
// "InvalidAutomationSignalException".
//
// The signal is not valid for the current Automation execution.
ErrCodeInvalidAutomationSignalException = "InvalidAutomationSignalException"
// ErrCodeInvalidAutomationStatusUpdateException for service response error code
// "InvalidAutomationStatusUpdateException".
//
// The specified update status operation is not valid.
ErrCodeInvalidAutomationStatusUpdateException = "InvalidAutomationStatusUpdateException"
// ErrCodeInvalidCommandId for service response error code
// "InvalidCommandId".
ErrCodeInvalidCommandId = "InvalidCommandId"
// ErrCodeInvalidDeleteInventoryParametersException for service response error code
// "InvalidDeleteInventoryParametersException".
//
// One or more of the parameters specified for the delete operation is not valid.
// Verify all parameters and try again.
ErrCodeInvalidDeleteInventoryParametersException = "InvalidDeleteInventoryParametersException"
// ErrCodeInvalidDeletionIdException for service response error code
// "InvalidDeletionIdException".
//
// The ID specified for the delete operation does not exist or is not valid.
// Verify the ID and try again.
ErrCodeInvalidDeletionIdException = "InvalidDeletionIdException"
// ErrCodeInvalidDocument for service response error code
// "InvalidDocument".
//
// The specified document does not exist.
ErrCodeInvalidDocument = "InvalidDocument"
// ErrCodeInvalidDocumentContent for service response error code
// "InvalidDocumentContent".
//
// The content for the document is not valid.
ErrCodeInvalidDocumentContent = "InvalidDocumentContent"
// ErrCodeInvalidDocumentOperation for service response error code
// "InvalidDocumentOperation".
//
// You attempted to delete a document while it is still shared. You must stop
// sharing the document before you can delete it.
ErrCodeInvalidDocumentOperation = "InvalidDocumentOperation"
// ErrCodeInvalidDocumentSchemaVersion for service response error code
// "InvalidDocumentSchemaVersion".
//
// The version of the document schema is not supported.
ErrCodeInvalidDocumentSchemaVersion = "InvalidDocumentSchemaVersion"
// ErrCodeInvalidDocumentVersion for service response error code
// "InvalidDocumentVersion".
//
// The document version is not valid or does not exist.
ErrCodeInvalidDocumentVersion = "InvalidDocumentVersion"
// ErrCodeInvalidFilter for service response error code
// "InvalidFilter".
//
// The filter name is not valid. Verify the you entered the correct name and
// try again.
ErrCodeInvalidFilter = "InvalidFilter"
// ErrCodeInvalidFilterKey for service response error code
// "InvalidFilterKey".
//
// The specified key is not valid.
ErrCodeInvalidFilterKey = "InvalidFilterKey"
// ErrCodeInvalidFilterOption for service response error code
// "InvalidFilterOption".
//
// The specified filter option is not valid. Valid options are Equals and BeginsWith.
// For Path filter, valid options are Recursive and OneLevel.
ErrCodeInvalidFilterOption = "InvalidFilterOption"
// ErrCodeInvalidFilterValue for service response error code
// "InvalidFilterValue".
//
// The filter value is not valid. Verify the value and try again.
ErrCodeInvalidFilterValue = "InvalidFilterValue"
// ErrCodeInvalidInstanceId for service response error code
// "InvalidInstanceId".
//
// The following problems can cause this exception:
//
// You do not have permission to access the instance.
//
// SSM Agent is not running. Verify that SSM Agent is running.
//
// SSM Agent is not registered with the SSM endpoint. Try reinstalling SSM Agent.
//
// The instance is not in valid state. Valid states are: Running, Pending, Stopped,
// Stopping. Invalid states are: Shutting-down and Terminated.
ErrCodeInvalidInstanceId = "InvalidInstanceId"
// ErrCodeInvalidInstanceInformationFilterValue for service response error code
// "InvalidInstanceInformationFilterValue".
//
// The specified filter value is not valid.
ErrCodeInvalidInstanceInformationFilterValue = "InvalidInstanceInformationFilterValue"
// ErrCodeInvalidInventoryGroupException for service response error code
// "InvalidInventoryGroupException".
//
// The specified inventory group is not valid.
ErrCodeInvalidInventoryGroupException = "InvalidInventoryGroupException"
// ErrCodeInvalidInventoryItemContextException for service response error code
// "InvalidInventoryItemContextException".
//
// You specified invalid keys or values in the Context attribute for InventoryItem.
// Verify the keys and values, and try again.
ErrCodeInvalidInventoryItemContextException = "InvalidInventoryItemContextException"
// ErrCodeInvalidInventoryRequestException for service response error code
// "InvalidInventoryRequestException".
//
// The request is not valid.
ErrCodeInvalidInventoryRequestException = "InvalidInventoryRequestException"
// ErrCodeInvalidItemContentException for service response error code
// "InvalidItemContentException".
//
// One or more content items is not valid.
ErrCodeInvalidItemContentException = "InvalidItemContentException"
// ErrCodeInvalidKeyId for service response error code
// "InvalidKeyId".
//
// The query key ID is not valid.
ErrCodeInvalidKeyId = "InvalidKeyId"
// ErrCodeInvalidNextToken for service response error code
// "InvalidNextToken".
//
// The specified token is not valid.
ErrCodeInvalidNextToken = "InvalidNextToken"
// ErrCodeInvalidNotificationConfig for service response error code
// "InvalidNotificationConfig".
//
// One or more configuration items is not valid. Verify that a valid Amazon
// Resource Name (ARN) was provided for an Amazon SNS topic.
ErrCodeInvalidNotificationConfig = "InvalidNotificationConfig"
// ErrCodeInvalidOptionException for service response error code
// "InvalidOptionException".
//
// The delete inventory option specified is not valid. Verify the option and
// try again.
ErrCodeInvalidOptionException = "InvalidOptionException"
// ErrCodeInvalidOutputFolder for service response error code
// "InvalidOutputFolder".
//
// The S3 bucket does not exist.
ErrCodeInvalidOutputFolder = "InvalidOutputFolder"
// ErrCodeInvalidOutputLocation for service response error code
// "InvalidOutputLocation".
//
// The output location is not valid or does not exist.
ErrCodeInvalidOutputLocation = "InvalidOutputLocation"
// ErrCodeInvalidParameters for service response error code
// "InvalidParameters".
//
// You must specify values for all required parameters in the Systems Manager
// document. You can only supply values to parameters defined in the Systems
// Manager document.
ErrCodeInvalidParameters = "InvalidParameters"
// ErrCodeInvalidPermissionType for service response error code
// "InvalidPermissionType".
//
// The permission type is not supported. Share is the only supported permission
// type.
ErrCodeInvalidPermissionType = "InvalidPermissionType"
// ErrCodeInvalidPluginName for service response error code
// "InvalidPluginName".
//
// The plugin name is not valid.
ErrCodeInvalidPluginName = "InvalidPluginName"
// ErrCodeInvalidPolicyAttributeException for service response error code
// "InvalidPolicyAttributeException".
//
// A policy attribute or its value is invalid.
ErrCodeInvalidPolicyAttributeException = "InvalidPolicyAttributeException"
// ErrCodeInvalidPolicyTypeException for service response error code
// "InvalidPolicyTypeException".
//
// The policy type is not supported. Parameter Store supports the following
// policy types: Expiration, ExpirationNotification, and NoChangeNotification.
ErrCodeInvalidPolicyTypeException = "InvalidPolicyTypeException"
// ErrCodeInvalidResourceId for service response error code
// "InvalidResourceId".
//
// The resource ID is not valid. Verify that you entered the correct ID and
// try again.
ErrCodeInvalidResourceId = "InvalidResourceId"
// ErrCodeInvalidResourceType for service response error code
// "InvalidResourceType".
//
// The resource type is not valid. For example, if you are attempting to tag
// an instance, the instance must be a registered, managed instance.
ErrCodeInvalidResourceType = "InvalidResourceType"
// ErrCodeInvalidResultAttributeException for service response error code
// "InvalidResultAttributeException".
//
// The specified inventory item result attribute is not valid.
ErrCodeInvalidResultAttributeException = "InvalidResultAttributeException"
// ErrCodeInvalidRole for service response error code
// "InvalidRole".
//
// The role name can't contain invalid characters. Also verify that you specified
// an IAM role for notifications that includes the required trust policy. For
// information about configuring the IAM role for Run Command notifications,
// see Configuring Amazon SNS Notifications for Run Command (http://docs.aws.amazon.com/systems-manager/latest/userguide/rc-sns-notifications.html)
// in the AWS Systems Manager User Guide.
ErrCodeInvalidRole = "InvalidRole"
// ErrCodeInvalidSchedule for service response error code
// "InvalidSchedule".
//
// The schedule is invalid. Verify your cron or rate expression and try again.
ErrCodeInvalidSchedule = "InvalidSchedule"
// ErrCodeInvalidTarget for service response error code
// "InvalidTarget".
//
// The target is not valid or does not exist. It might not be configured for
// EC2 Systems Manager or you might not have permission to perform the operation.
ErrCodeInvalidTarget = "InvalidTarget"
// ErrCodeInvalidTypeNameException for service response error code
// "InvalidTypeNameException".
//
// The parameter type name is not valid.
ErrCodeInvalidTypeNameException = "InvalidTypeNameException"
// ErrCodeInvalidUpdate for service response error code
// "InvalidUpdate".
//
// The update is not valid.
ErrCodeInvalidUpdate = "InvalidUpdate"
// ErrCodeInvocationDoesNotExist for service response error code
// "InvocationDoesNotExist".
//
// The command ID and instance ID you specified did not match any invocations.
// Verify the command ID and the instance ID and try again.
ErrCodeInvocationDoesNotExist = "InvocationDoesNotExist"
// ErrCodeItemContentMismatchException for service response error code
// "ItemContentMismatchException".
//
// The inventory item has invalid content.
ErrCodeItemContentMismatchException = "ItemContentMismatchException"
// ErrCodeItemSizeLimitExceededException for service response error code
// "ItemSizeLimitExceededException".
//
// The inventory item size has exceeded the size limit.
ErrCodeItemSizeLimitExceededException = "ItemSizeLimitExceededException"
// ErrCodeMaxDocumentSizeExceeded for service response error code
// "MaxDocumentSizeExceeded".
//
// The size limit of a document is 64 KB.
ErrCodeMaxDocumentSizeExceeded = "MaxDocumentSizeExceeded"
// ErrCodeOpsItemAlreadyExistsException for service response error code
// "OpsItemAlreadyExistsException".
//
// The OpsItem already exists.
ErrCodeOpsItemAlreadyExistsException = "OpsItemAlreadyExistsException"
// ErrCodeOpsItemInvalidParameterException for service response error code
// "OpsItemInvalidParameterException".
//
// A specified parameter argument isn't valid. Verify the available arguments
// and try again.
ErrCodeOpsItemInvalidParameterException = "OpsItemInvalidParameterException"
// ErrCodeOpsItemLimitExceededException for service response error code
// "OpsItemLimitExceededException".
//
// The request caused OpsItems to exceed one or more limits. For information
// about OpsItem limits, see What are the resource limits for OpsCenter? (http://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-learn-more.html#OpsCenter-learn-more-limits).
ErrCodeOpsItemLimitExceededException = "OpsItemLimitExceededException"
// ErrCodeOpsItemNotFoundException for service response error code
// "OpsItemNotFoundException".
//
// The specified OpsItem ID doesn't exist. Verify the ID and try again.
ErrCodeOpsItemNotFoundException = "OpsItemNotFoundException"
// ErrCodeParameterAlreadyExists for service response error code
// "ParameterAlreadyExists".
//
// The parameter already exists. You can't create duplicate parameters.
ErrCodeParameterAlreadyExists = "ParameterAlreadyExists"
// ErrCodeParameterLimitExceeded for service response error code
// "ParameterLimitExceeded".
//
// You have exceeded the number of parameters for this AWS account. Delete one
// or more parameters and try again.
ErrCodeParameterLimitExceeded = "ParameterLimitExceeded"
// ErrCodeParameterMaxVersionLimitExceeded for service response error code
// "ParameterMaxVersionLimitExceeded".
//
// The parameter exceeded the maximum number of allowed versions.
ErrCodeParameterMaxVersionLimitExceeded = "ParameterMaxVersionLimitExceeded"
// ErrCodeParameterNotFound for service response error code
// "ParameterNotFound".
//
// The parameter could not be found. Verify the name and try again.
ErrCodeParameterNotFound = "ParameterNotFound"
// ErrCodeParameterPatternMismatchException for service response error code
// "ParameterPatternMismatchException".
//
// The parameter name is not valid.
ErrCodeParameterPatternMismatchException = "ParameterPatternMismatchException"
// ErrCodeParameterVersionLabelLimitExceeded for service response error code
// "ParameterVersionLabelLimitExceeded".
//
// A parameter version can have a maximum of ten labels.
ErrCodeParameterVersionLabelLimitExceeded = "ParameterVersionLabelLimitExceeded"
// ErrCodeParameterVersionNotFound for service response error code
// "ParameterVersionNotFound".
//
// The specified parameter version was not found. Verify the parameter name
// and version, and try again.
ErrCodeParameterVersionNotFound = "ParameterVersionNotFound"
// ErrCodePoliciesLimitExceededException for service response error code
// "PoliciesLimitExceededException".
//
// You specified more than the maximum number of allowed policies for the parameter.
// The maximum is 10.
ErrCodePoliciesLimitExceededException = "PoliciesLimitExceededException"
// ErrCodeResourceDataSyncAlreadyExistsException for service response error code
// "ResourceDataSyncAlreadyExistsException".
//
// A sync configuration with the same name already exists.
ErrCodeResourceDataSyncAlreadyExistsException = "ResourceDataSyncAlreadyExistsException"
// ErrCodeResourceDataSyncCountExceededException for service response error code
// "ResourceDataSyncCountExceededException".
//
// You have exceeded the allowed maximum sync configurations.
ErrCodeResourceDataSyncCountExceededException = "ResourceDataSyncCountExceededException"
// ErrCodeResourceDataSyncInvalidConfigurationException for service response error code
// "ResourceDataSyncInvalidConfigurationException".
//
// The specified sync configuration is invalid.
ErrCodeResourceDataSyncInvalidConfigurationException = "ResourceDataSyncInvalidConfigurationException"
// ErrCodeResourceDataSyncNotFoundException for service response error code
// "ResourceDataSyncNotFoundException".
//
// The specified sync name was not found.
ErrCodeResourceDataSyncNotFoundException = "ResourceDataSyncNotFoundException"
// ErrCodeResourceInUseException for service response error code
// "ResourceInUseException".
//
// Error returned if an attempt is made to delete a patch baseline that is registered
// for a patch group.
ErrCodeResourceInUseException = "ResourceInUseException"
// ErrCodeResourceLimitExceededException for service response error code
// "ResourceLimitExceededException".
//
// Error returned when the caller has exceeded the default resource limits.
// For example, too many maintenance windows or patch baselines have been created.
//
// For information about resource limits in Systems Manager, see AWS Systems
// Manager Limits (http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_ssm).
ErrCodeResourceLimitExceededException = "ResourceLimitExceededException"
// ErrCodeServiceSettingNotFound for service response error code
// "ServiceSettingNotFound".
//
// The specified service setting was not found. Either the service name or the
// setting has not been provisioned by the AWS service team.
ErrCodeServiceSettingNotFound = "ServiceSettingNotFound"
// ErrCodeStatusUnchanged for service response error code
// "StatusUnchanged".
//
// The updated status is the same as the current status.
ErrCodeStatusUnchanged = "StatusUnchanged"
// ErrCodeSubTypeCountLimitExceededException for service response error code
// "SubTypeCountLimitExceededException".
//
// The sub-type count exceeded the limit for the inventory type.
ErrCodeSubTypeCountLimitExceededException = "SubTypeCountLimitExceededException"
// ErrCodeTargetInUseException for service response error code
// "TargetInUseException".
//
// You specified the Safe option for the DeregisterTargetFromMaintenanceWindow
// operation, but the target is still referenced in a task.
ErrCodeTargetInUseException = "TargetInUseException"
// ErrCodeTargetNotConnected for service response error code
// "TargetNotConnected".
//
// The specified target instance for the session is not fully configured for
// use with Session Manager. For more information, see Getting Started with
// Session Manager (http://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started.html)
// in the AWS Systems Manager User Guide.
ErrCodeTargetNotConnected = "TargetNotConnected"
// ErrCodeTooManyTagsError for service response error code
// "TooManyTagsError".
//
// The Targets parameter includes too many tags. Remove one or more tags and
// try the command again.
ErrCodeTooManyTagsError = "TooManyTagsError"
// ErrCodeTooManyUpdates for service response error code
// "TooManyUpdates".
//
// There are concurrent updates for a resource that supports one update at a
// time.
ErrCodeTooManyUpdates = "TooManyUpdates"
// ErrCodeTotalSizeLimitExceededException for service response error code
// "TotalSizeLimitExceededException".
//
// The size of inventory data has exceeded the total size limit for the resource.
ErrCodeTotalSizeLimitExceededException = "TotalSizeLimitExceededException"
// ErrCodeUnsupportedFeatureRequiredException for service response error code
// "UnsupportedFeatureRequiredException".
//
// Microsoft application patching is only available on EC2 instances and Advanced
// Instances. To patch Microsoft applications on on-premises servers and VMs,
// you must enable Advanced Instances. For more information, see Using the Advanced-Instances
// Tier (http://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-managedinstances-advanced.html)
// in the AWS Systems Manager User Guide.
ErrCodeUnsupportedFeatureRequiredException = "UnsupportedFeatureRequiredException"
// ErrCodeUnsupportedInventoryItemContextException for service response error code
// "UnsupportedInventoryItemContextException".
//
// The Context attribute that you specified for the InventoryItem is not allowed
// for this inventory type. You can only use the Context attribute with inventory
// types like AWS:ComplianceItem.
ErrCodeUnsupportedInventoryItemContextException = "UnsupportedInventoryItemContextException"
// ErrCodeUnsupportedInventorySchemaVersionException for service response error code
// "UnsupportedInventorySchemaVersionException".
//
// Inventory item type schema version has to match supported versions in the
// service. Check output of GetInventorySchema to see the available schema version
// for each type.
ErrCodeUnsupportedInventorySchemaVersionException = "UnsupportedInventorySchemaVersionException"
// ErrCodeUnsupportedOperatingSystem for service response error code
// "UnsupportedOperatingSystem".
//
// The operating systems you specified is not supported, or the operation is
// not supported for the operating system. Valid operating systems include:
// Windows, AmazonLinux, RedhatEnterpriseLinux, and Ubuntu.
ErrCodeUnsupportedOperatingSystem = "UnsupportedOperatingSystem"
// ErrCodeUnsupportedParameterType for service response error code
// "UnsupportedParameterType".
//
// The parameter type is not supported.
ErrCodeUnsupportedParameterType = "UnsupportedParameterType"
// ErrCodeUnsupportedPlatformType for service response error code
// "UnsupportedPlatformType".
//
// The document does not support the platform type of the given instance ID(s).
// For example, you sent an document for a Windows instance to a Linux instance.
ErrCodeUnsupportedPlatformType = "UnsupportedPlatformType"
)

View File

@ -0,0 +1,97 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
package ssm
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
)
// SSM provides the API operation methods for making requests to
// Amazon Simple Systems Manager (SSM). See this package's package overview docs
// for details on the service.
//
// SSM methods are safe to use concurrently. It is not safe to
// modify mutate any of the struct's properties though.
type SSM struct {
*client.Client
}
// Used for custom client initialization logic
var initClient func(*client.Client)
// Used for custom request initialization logic
var initRequest func(*request.Request)
// Service information constants
const (
ServiceName = "ssm" // Name of service.
EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "SSM" // ServiceID is a unique identifer of a specific service.
)
// New creates a new instance of the SSM client with a session.
// If additional configuration is needed for the client instance use the optional
// aws.Config parameter to add your extra config.
//
// Example:
// // Create a SSM client from just a session.
// svc := ssm.New(mySession)
//
// // Create a SSM client with additional configuration
// svc := ssm.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *SSM {
c := p.ClientConfig(EndpointsID, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
}
// newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *SSM {
svc := &SSM{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName,
SigningRegion: signingRegion,
Endpoint: endpoint,
APIVersion: "2014-11-06",
JSONVersion: "1.1",
TargetPrefix: "AmazonSSM",
},
handlers,
),
}
// Handlers
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
svc.Handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler)
// Run custom client initialization if present
if initClient != nil {
initClient(svc.Client)
}
return svc
}
// newRequest creates a new request for a SSM operation and runs any
// custom request initialization.
func (c *SSM) newRequest(op *request.Operation, params, data interface{}) *request.Request {
req := c.NewRequest(op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}

1
vendor/modules.txt vendored
View File

@ -160,6 +160,7 @@ github.com/aws/aws-sdk-go/service/s3/s3iface
github.com/aws/aws-sdk-go/service/s3/s3manager
github.com/aws/aws-sdk-go/service/secretsmanager
github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface
github.com/aws/aws-sdk-go/service/ssm
github.com/aws/aws-sdk-go/service/sts
github.com/aws/aws-sdk-go/service/sts/stsiface
# github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d

View File

@ -79,6 +79,8 @@ necessary for this build to succeed and can be found further down the page.
@include 'builder/amazon/common/RunConfig-not-required.mdx'
@include 'builders/aws-sesson-manager.mdx'
### Block Devices Configuration
Block devices can be nested in the

View File

@ -298,8 +298,8 @@
password for Windows instances. Defaults to 20 minutes. Example value:
10m
- `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns`, or `private_dns`. If
set, either the public IP address, private IP address, public DNS name
- `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns`, `private_dns` or `session_manager`.
If set, either the public IP address, private IP address, public DNS name
or private DNS name will be used as the host for SSH. The default behaviour
if inside a VPC is to use the public IP address if available, otherwise
the private IP address will be used. If not in a VPC the public DNS name
@ -310,3 +310,15 @@
`<region>.compute.internal` included in the `NO_PROXY` environment
variable.
When using `session_manager` the machine running Packer must have
the AWS Session Manager Plugin installed and within the users' or system path.
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html
Remote connections via the `session_manager` interface establishes a secure tunnel
between the local host and the remote host on an available local port to the specified `ssh_port`.
Upon termination the secure tunnel will be terminated automatically, if however there is a failure in
terminating the tunnel it will automatically terminate itself after 20 minutes of inactivity.
- `session_manager_port` (int) - Which port to connect the local end of the session tunnel to. If
left blank, Packer will choose a port for you from available ports.
This option is only used when `ssh_interface` is set `session_manager`.

View File

@ -0,0 +1,55 @@
### Session Manager Connections
Support for the AWS Systems Manager session manager capability lets users manage EC2 instances without the need to open inbound ports, or maintain bastion hosts. Session manager connectivity relies on the use of the [session manager plugin](#session-manager-plugin) to open a secure tunnel between the local machine and the remote instance. Once the tunnel has been created all SSH communication will be tunneled through the SSM to the remote instance.
To use the session manager as the connection interface for the SSH communicator you need to add the following configuration options to the Amazon builder options:
* `ssh_interface`: The ssh interface must be set to "session_manager". When using this option the builder will create an SSM tunnel to the configured `ssh_port` (defaults to 22) on the remote host.
* `iam_instance_profile`: A valid instance profile granting Systems Manger permissions to manage the remote instance is required in order for the aws ssm-agent to start and stop session connections. See below for more details on IAM instance profile for Systems Manager(#iam-instance-profile-for-systems-manager).
#### Optional
* `temporary_iam_instance_profile_policy_document`: A temporary instance profile policy document can be used of an existing `iam_instance_profile`.
* `session_manager_port`: A local port on the host machine that should be used as the local end of the session tunnel to the remote host. If not specified Packer will find an available port to use.
```json
{
"builders": [
{
"type": "amazon-ebs",
"ami_name": "packer-ami-{{timestamp}}",
"instance_type": "t2.micro",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
"root-device-type": "ebs"
},
"owners": [
"099720109477"
],
"most_recent": true
},
"ssh_username": "ubuntu",
"ssh_interface": "session_manager",
"communicator": "ssh",
"iam_instance_profile": "{{user `iam_instance_profile`}}"
}
],
"provisioners": [
{
"type": "shell",
"inline": [ "echo Connected via SSM at '{{build `User`}}@{{build `Host`}}:{{build `Port`}}'" ]
}
]
}
```
#### Session Manager Plugin
Connectivity via the session manager requires the use of a session-manger-plugin which can be downloaded and installed along side Packer and an instance AMI that is capable of running the AWS ssm-agent - see [About SSM Agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/prereqs-ssm-agent.html) for details on supported AMIs.
In order for Packer to start and end sessions that connect you to your managed instances, you must first install the Session Manager plugin on your local machine. The plugin can be installed on supported versions of Microsoft Windows, macOS, Linux, and Ubuntu Server.
[Installation instructions for the session-manager-plugin](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)
#### IAM instance profile for Systems Manager
By default systems manager doesn't have permission to perform actions on the instances so you must grant SSM access by creating an instance profile with the `AmazonSSMManagedInstanceCore` policy. The instance profile can then be attached to any instance you wish to manage via the sesson-manager. See [Adding System Manager instance profile](https://docs.aws.amazon.com/systems-manager/latest/userguide/setup-instance-profile.html#instance-profile-add-permissions) for details on creating the required instance profile.