Set up your Environment

Make sure you have go installed.

Next, create a folder and open it with your chosen editor. Run:

go mod init personal.test.com/aws-sdk

to create your go.mod file for managing dependencies.

Next, we’ll need to install the AWS SDK dependencies we’ll be using for this simple example.

go get github.com/aws/aws-sdk-go-v2/config github.com/aws/aws-sdk-go-v2/service/ssm

Lastly, set-up your directory to look something like this

├── go.mod
├── go.sum
├── internal
│   └── get-parameters.go
└── main.go

The Code

Luckily, this simple example isn’t too verbose. I will first show the entire project before I explain how it all works.

main.go

package main

import (
	"personal.test.com/aws-sdk/internal"
)

func main(){
	result := internal.GetParameterFromName("myParameterName")
}

internal/get-parameters.go

package internal

import (
	"context"

	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/ssm"
)

func GetParameterFromName(name string) (*string, error) {
	cfg, err := config.LoadDefaultCig(context.TODO())

	if err != nil {
		return nil, err
	}

	client := ssm.NewFromConfig(cfg)

	input := &ssm.GetParameterInput{
		Name: &name,
		WithDecryption: true,
	}

	results, err := client.GetParameter(context.TODO(), input)

	if err != nil {
		return nil, err
	}

	return *results.Parameter.Value, nil
}

The Config struct and context

cfg, err := config.LoadDefaultConfig(context.TODO())

This first line is going to use the AWS SDK config package to “construct an aws.Config using the AWS shared configuration sources. This includes configuring a credential provider, configuring the AWS Region, and loading service specific configuration.”. This explanation comes directly from the AWS documentation here.

In other words, the config.LoadDefaultConfig method is going to handle finding our credentials and other metadata automatically.

The context.TODO() method is interesting. Per the context package documentation, “Code should use context.TODO when it’s unclear which Context to use or it is not yet available (because the surrounding function has not yet been extended to accept a Context parameter).”. The AWS documentation uses this regularly, implying that the AWS SDK for Go can use more advanced context behaviors, such as passing down a context from a top-level function, but that it isn’t required to use it this way. For the sake of simplicity, we will keep it as this default context.

Creating an SSM client

client := ssm.NewFromConfig(cfg)

After checking for errors from the configuration loading step, we will now use the cfg struct that contains our metadata to create a client with which we can interact with SSM. This should look familiar to anyone who has used boto3, the Python 3 SDK for AWS.

Setting up our request parameters

input := &ssm.GetParameterInput{
	Name: &name,
	WithDecryption: true, // In the case that you parameter is a 'Secure String' type.
}

Next, we are going to create and reference a new struct that contains the request details specific to ssm:GetParameter. In this case, all we need to give it is the name of the parameter, and to let it know to decrypt.

Retrieving and Returning

results, err := client.GetParameter(context.TODO(), input)

if err != nil {
	return nil, err
}

return *results.Parameter.Value, nil

Lastly, we will use our input and another default background context to make the API call. If it fails for whatever reason, we will return the error and no value. Otherwise, we will get the Parameter.Value string and return it.

From main.go, we just need to make sure we’ve imported the internal module and call the function with the name of our parameter.

result := internal.GetParameterFromName("myParameterName")

And that is it! Hopefully this clears up some of the more confusing basics of getting started with the AWS SDK for Go. The deeper you go, the more interesting quirks you’ll find. Lastly, be sure to watch out for examples where the SDK for Go V1 is being used. Both V1 and V2 are supported, but V2 will be the version getting more features over time, so its better to use this one if you’re first starting out. If you’ve got old code using V1, it probably isn’t worth panicking, but I’d check in to confirm the support lifecycle to ensure that it won’t be deprecated at the time of reading this.