Skip to content

Commit

Permalink
Implement 'aws_ssm' connection type #26
Browse files Browse the repository at this point in the history
  • Loading branch information
dominik-przybyl-wttech committed Jan 24, 2024
1 parent 6b05fe7 commit b4d8d3b
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 38 deletions.
2 changes: 1 addition & 1 deletion examples/aws_ssm/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ locals {
env_type = "aem-single"
host = "aem_single"

ssm_user = "ec2-user"
ssm_user = "root"

tags = {
Workspace = "aemc"
Expand Down
15 changes: 14 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ module github.com/wttech/terraform-provider-aem
go 1.19

require (
github.com/aws/aws-sdk-go-v2 v1.24.1
github.com/aws/aws-sdk-go-v2/config v1.26.6
github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7
github.com/hashicorp/terraform-plugin-docs v0.16.0
github.com/hashicorp/terraform-plugin-framework v1.4.2
github.com/hashicorp/terraform-plugin-go v0.19.0
Expand All @@ -21,7 +24,17 @@ require (
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/aws/aws-sdk-go v1.48.12 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
github.com/aws/smithy-go v1.19.0 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/fatih/color v1.16.0 // indirect
Expand Down
32 changes: 30 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,34 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkE
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go v1.48.12 h1:n+eGzflzzvYubu2cOjqpVll7lF+Ci0ThyCpg5kzfzbo=
github.com/aws/aws-sdk-go v1.48.12/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU=
github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
github.com/aws/aws-sdk-go-v2/config v1.26.6 h1:Z/7w9bUqlRI0FFQpetVuFYEsjzE3h7fpU6HuGmfPL/o=
github.com/aws/aws-sdk-go-v2/config v1.26.6/go.mod h1:uKU6cnDmYCvJ+pxO9S4cWDb2yWWIH5hra+32hVh1MI4=
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8=
github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 h1:n3GDfwqF2tzEkXlv5cuy4iy7LpKDtqDMcNLfZDu9rls=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino=
github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7 h1:a8HvP/+ew3tKwSXqL3BCSjiuicr+XTU2eFYeogV9GJE=
github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7/go.mod h1:Q7XIWsMo0JcMpI/6TGD6XXcXcV1DbTj6e9BKNntIMIM=
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow=
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U=
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
Expand Down Expand Up @@ -95,6 +121,7 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
Expand Down Expand Up @@ -243,6 +270,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
2 changes: 1 addition & 1 deletion internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (c Client) FileCopy(localPath string, remotePath string, override bool) err
return err
}
defer func() { _ = c.PathDelete(remoteTmpPath) }()
if err := c.connection.CopyFile(c.Sudo, localPath, remoteTmpPath); err != nil {
if err := c.connection.CopyFile(localPath, remoteTmpPath); err != nil {
return err
}
if err := c.FileMove(remoteTmpPath, remotePath); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/client/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ type Connection interface {
Connect() error
Disconnect() error
Command(cmdLine []string) ([]byte, error)
CopyFile(sudo bool, localPath string, remotePath string) error
CopyFile(localPath string, remotePath string) error
}
59 changes: 29 additions & 30 deletions internal/client/connection_aws_ssm.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package client

import (
"context"
"encoding/base64"
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/ssm"
"os"
"strings"
"time"
)

type AWSSSMConnection struct {
user string
instanceId string
region string
ssmClient *ssm.SSM
ssmClient *ssm.Client
sessionId *string
}

Expand All @@ -25,22 +27,25 @@ func (a *AWSSSMConnection) Info() string {
func (a *AWSSSMConnection) User() string {
return a.user
}

func (a *AWSSSMConnection) Connect() error {
// Create an AWS session
sess, err := session.NewSession(&aws.Config{
Region: aws.String(a.region),
})
// Specify the AWS region
cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(a.region))
if err != nil {
return err
}

// Create an SSM client
ssmClient := ssm.NewFromConfig(cfg)
if err != nil {
return fmt.Errorf("ssm: error creating AWS session: %v", err)
}

// Connect to AWS instance using SSM
ssmClient := ssm.New(sess)
startSessionInput := &ssm.StartSessionInput{
Target: aws.String(a.instanceId),
}

startSessionOutput, err := ssmClient.StartSession(startSessionInput)
startSessionOutput, err := ssmClient.StartSession(context.Background(), startSessionInput)
if err != nil {
return fmt.Errorf("ssm: error starting session: %v", err)
}
Expand All @@ -57,7 +62,7 @@ func (a *AWSSSMConnection) Disconnect() error {
SessionId: a.sessionId,
}

_, err := a.ssmClient.TerminateSession(terminateSessionInput)
_, err := a.ssmClient.TerminateSession(context.Background(), terminateSessionInput)
if err != nil {
return fmt.Errorf("ssm: error terminating session: %v", err)
}
Expand All @@ -67,56 +72,50 @@ func (a *AWSSSMConnection) Disconnect() error {

func (a *AWSSSMConnection) Command(cmdLine []string) ([]byte, error) {
// Execute command on the remote instance
command := aws.String(strings.Join(cmdLine, " "))
command := strings.Join(cmdLine, " ")
runCommandInput := &ssm.SendCommandInput{
DocumentName: aws.String("AWS-RunShellScript"),
InstanceIds: []*string{aws.String(a.instanceId)},
Parameters: map[string][]*string{
InstanceIds: []string{a.instanceId},
Parameters: map[string][]string{
"commands": {command},
},
}

runCommandOutput, err := a.ssmClient.SendCommand(runCommandInput)
runCommandOutput, err := a.ssmClient.SendCommand(context.Background(), runCommandInput)
if err != nil {
return nil, fmt.Errorf("ssm: error executing command: %v", err)
}

commandId := runCommandOutput.Command.CommandId

// Wait for command completion
err = a.ssmClient.WaitUntilCommandExecuted(&ssm.GetCommandInvocationInput{
commandInvocationInput := &ssm.GetCommandInvocationInput{
CommandId: commandId,
InstanceId: aws.String(a.instanceId),
})
}

waiter := ssm.NewCommandExecutedWaiter(a.ssmClient)
_, err = waiter.WaitForOutput(context.Background(), commandInvocationInput, time.Hour)
if err != nil {
return nil, fmt.Errorf("ssm: error executing command: %v", err)
}

getCommandOutput, err := a.ssmClient.GetCommandInvocation(&ssm.GetCommandInvocationInput{
CommandId: commandId,
InstanceId: aws.String(a.instanceId),
})
getCommandOutput, err := a.ssmClient.GetCommandInvocation(context.Background(), commandInvocationInput)
if err != nil {
return nil, fmt.Errorf("ssm: error executing command: %v", err)
}

return []byte(*getCommandOutput.StandardOutputContent), nil
}

func (a *AWSSSMConnection) CopyFile(sudo bool, localPath string, remotePath string) error {
func (a *AWSSSMConnection) CopyFile(localPath string, remotePath string) error {
fileContent, err := os.ReadFile(localPath)
if err != nil {
return fmt.Errorf("ssm: error reading local file: %v", err)
}
encodedContent := base64.StdEncoding.EncodeToString(fileContent)

cmd := fmt.Sprintf("echo -n %s | base64 -d > %s", encodedContent, remotePath)
var cmdLine []string
if sudo {
cmdLine = []string{"sudo", "sh", "-c", "\"" + cmd + "\""}
} else {
cmdLine = []string{"sh", "-c", "\"" + cmd + "\""}
}
cmdLine := []string{"sh", "-c", "\"" + cmd + "\""}
_, err = a.Command(cmdLine)
return err
}
2 changes: 1 addition & 1 deletion internal/client/connection_ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (s *SSHConnection) splitCommandLine(cmdLine []string) (string, []string) {
return name, args
}

func (s *SSHConnection) CopyFile(sudo bool, localPath string, remotePath string) error {
func (s *SSHConnection) CopyFile(localPath string, remotePath string) error {
if err := s.client.Upload(localPath, remotePath); err != nil {
return fmt.Errorf("ssh: cannot copy local file '%s' to remote path '%s' on host '%s': %w", localPath, remotePath, s.host, err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/provider/instance/systemd.conf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[Unit]
Description=AEM Instances
Requires=network.target multi-user.target
Requires=network.target
After=cloud-final.service

[Service]
Expand Down

0 comments on commit b4d8d3b

Please sign in to comment.