Add PoC of connectivity using session-manager-plugin
* Add a bunch of hard coded values for testing on port 8081; ssh configs are set to localhost and 8081 * Add a base drive for communicating with the session manager plugin * Update step for creating tunnel to actually create SSM session tunnel via driver
This commit is contained in:
parent
16604373ac
commit
3dd46eb5f4
|
@ -0,0 +1,50 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type SSMDriver struct {
|
||||
Ui packer.Ui
|
||||
Ctx *interpolate.Context
|
||||
|
||||
l sync.Mutex
|
||||
}
|
||||
|
||||
// sessJson, region, "StartSession", profile, paramJson, endpoint
|
||||
func (s *SSMDriver) StartSession(sessionData, region, profile, params, endpoint string) error {
|
||||
var stdout bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
|
||||
args := []string{
|
||||
sessionData,
|
||||
region,
|
||||
"StartSession",
|
||||
profile,
|
||||
params,
|
||||
endpoint,
|
||||
}
|
||||
|
||||
// Remove log statement
|
||||
log.Printf("Attempting to start session with the following args: %v", args)
|
||||
cmd := exec.Command("session-manager-plugin", args...)
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
err = fmt.Errorf("Error committing container: %s\nStderr: %s", err, stderr.String())
|
||||
s.Ui.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
log.Println(stdout.String())
|
||||
log.Println(stderr.String())
|
||||
|
||||
return nil
|
||||
}
|
|
@ -2,11 +2,17 @@ package common
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"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/retry"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
@ -20,31 +26,91 @@ type StepCreateSSMTunnel struct {
|
|||
SrcPort string
|
||||
|
||||
ssmSession *ssm.StartSessionOutput
|
||||
tunnel net.Listener
|
||||
}
|
||||
|
||||
func (s *StepCreateSSMTunnel) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
/*
|
||||
p, _ := strconv.Atoi(s.SrcPort)
|
||||
//TODO dynamically setup local port
|
||||
// Find an available TCP port for our HTTP server
|
||||
l, err := packernet.ListenRangeConfig{
|
||||
Min: p,
|
||||
Max: p,
|
||||
Addr: "0.0.0.0",
|
||||
Network: "tcp",
|
||||
}.Listen(ctx)
|
||||
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error finding port: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
*/
|
||||
params := map[string][]*string{
|
||||
"portNumber": []*string{aws.String(s.DstPort)},
|
||||
"localPortNumber": []*string{aws.String(s.SrcPort)},
|
||||
"localPortNumber": []*string{aws.String(strconv.Itoa(8081))},
|
||||
}
|
||||
instance, ok := state.Get("instance").(*ec2.Instance)
|
||||
if !ok {
|
||||
err := fmt.Errorf("error encountered in obtaining target instance id for SSM tunnel")
|
||||
ui.Error(err.Error())
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
s.InstanceID = aws.StringValue(instance.InstanceId)
|
||||
|
||||
ssmconn := ssm.New(s.AWSSession)
|
||||
input := ssm.StartSessionInput{
|
||||
DocumentName: aws.String("AWS-StartPortForwardingSession"),
|
||||
Parameters: params,
|
||||
Target: aws.String(s.InstanceID),
|
||||
}
|
||||
var output *ssm.StartSessionOutput
|
||||
var err error
|
||||
err = retry.Config{
|
||||
Tries: 11,
|
||||
ShouldRetry: func(err error) bool { return isAWSErr(err, "TargetNotConnected", "") },
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
output, err = ssmconn.StartSessionWithContext(ctx, &input)
|
||||
return err
|
||||
})
|
||||
|
||||
output, err := ssmconn.StartSession(&input)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error encountered in creating a connection to the SSM agent: %s", err)
|
||||
err = fmt.Errorf("error encountered in starting session: %s", err)
|
||||
ui.Error(err.Error())
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
s.ssmSession = output
|
||||
|
||||
sessJson, err := json.Marshal(s.ssmSession)
|
||||
if err != nil {
|
||||
ui.Error(err.Error())
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
paramsJson, err := json.Marshal(input)
|
||||
if err != nil {
|
||||
ui.Error(err.Error())
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
driver := SSMDriver{Ui: ui}
|
||||
// sessJson, region, "StartSession", profile, paramJson, endpoint
|
||||
if err := driver.StartSession(string(sessJson), "us-east-1", "packer", string(paramsJson), ssmconn.Endpoint); err != nil {
|
||||
err = fmt.Errorf("error encountered in creating a connection to the SSM agent: %s", err)
|
||||
ui.Error(err.Error())
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
@ -61,4 +127,5 @@ func (s *StepCreateSSMTunnel) Cleanup(state multistep.StateBag) {
|
|||
aws.StringValue(s.ssmSession.SessionId), err)
|
||||
ui.Error(msg)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ package ebs
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
|
@ -255,6 +256,11 @@ 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,
|
||||
DstPort: strconv.Itoa(22),
|
||||
SrcPort: "8081",
|
||||
},
|
||||
&communicator.StepConnect{
|
||||
Config: &b.config.RunConfig.Comm,
|
||||
Host: awscommon.SSHHost(
|
||||
|
|
Loading…
Reference in New Issue