AWS Go SDK and EC2: Complete Guide with examples
In this tutorial, we will look at how we can use the AWS Go SDK to perform various operations on AWS EC2.
Table of contents
- Prerequisites
- How to create an EC2 key pair?
- How to create a new EC2 instance using AWS Go SDK?
- How to list all running EC2 instances?
- How to stop an EC2 instance?
- How to terminate an EC2 instance?
Prerequisites
- Install AWS Go SDK: Run
go get -u github.com/aws/aws-sdk-go/...
to install the SDK - AWS Credentials: If you haven’t setup AWS credentials before, this resource from AWS is helpful.
How to create an EC2 key pair?
A key pair consists of a private key and a public key. A Key Pair is required to securely access an EC2 instance. We will be storing the generated private key on our computer where Amazon stores the public key.
package main
import (
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"fmt"
)
func CreateKeyPair(client *ec2.EC2, keyName string) (*ec2.CreateKeyPairOutput, error) {
result, err := client.CreateKeyPair(&ec2.CreateKeyPairInput{
KeyName: aws.String(keyName),
})
if err != nil {
return nil, err
}
return result, nil
}
func WriteKey(fileName string, fileData *string) error {
err := os.WriteFile(fileName, []byte(*fileData), 0400)
return err
}
func main() {
sess, err := session.NewSessionWithOptions(session.Options{
Profile: "default",
Config: aws.Config{
Region: aws.String("us-west-2"),
},
})
if err != nil {
fmt.Printf("Failed to initialize new session: %v", err)
return
}
ec2Client := ec2.New(sess)
keyName := "ec2-go-tutorial-key-name"
createRes, err := CreateKeyPair(ec2Client, keyName)
if err != nil {
fmt.Printf("Couldn't create key pair: %v", err)
return
}
err = WriteKey("/tmp/aws_ec2_key.pem", createRes.KeyMaterial)
if err != nil {
fmt.Printf("Couldn't write key pair to file: %v", err)
return
}
fmt.Println("Created key pair: ", *createRes.KeyName)
}
The function above creates an EC2 key pair with the name ec2-go-tutorial-key-name
and then stores that locally at /tmp/ec2-go-tutorial-key-name.pem
with the 400
permissions that will be needed when we use the private key to access the EC2 instance.
How to list all existing KeyPairs?
We will be using the DescribeKeyPairs method from the SDK to list all of the existing Key Pairs in the AWS account.
package main
import (
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"fmt"
)
func DescribeKeyPairs(client *ec2.EC2) (*ec2.DescribeKeyPairsOutput, error) {
result, err := client.DescribeKeyPairs(nil)
if err != nil {
return nil, err
}
return result, err
}
func main() {
sess, err := session.NewSessionWithOptions(session.Options{
Profile: "default",
Config: aws.Config{
Region: aws.String("us-west-2"),
},
})
if err != nil {
fmt.Printf("Failed to initialize new session: %v", err)
return
}
ec2Client := ec2.New(sess)
keyPairRes, err := DescribeKeyPairs(ec2Client)
if err != nil {
fmt.Printf("Couldn't fetch key pairs: %v", err)
return
}
fmt.Println("Key Pairs: ")
for _, pair := range keyPairRes.KeyPairs {
fmt.Printf("%s \n", *pair.KeyName)
}
}
How to create a new EC2 instance using AWS Go SDK?
Requirements for creating an EC2 instance
- ImageId: An Amazon Machine Image (AMI) is required to launch an EC2 instance. You can either use one of the freely available AMIs provided by Amazon or create your own. For this tutorial, we will use the
Amazon Linux 2 AMI
inus-west-2
. - MinCount: Minimum number of EC2 instances to create
- MaxCount: Maximum number of EC2 instances to create
Recommended
- InstanceType: The instance type for the EC2 instance. Information about all the instance types is available here.
- KeyName: The name of the key pair that will be used to access the EC2 instance. If no
KeyName
is specified, we won’t be able to SSH into the EC2 instance. - SecurityGroupIds: Security groups allow you to control access into and out of your EC2 instance.
- IamInstanceProfile: The name of the IAM profile that will be attached to the EC2 instance.
Information on all available parameters is available in the SDK docs.
package main
import (
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"fmt"
)
func CreateInstance(client *ec2.EC2, imageId string, minCount int, maxCount int, instanceType string, keyName string) (*ec2.Reservation, error) {
res, err := client.RunInstances(&ec2.RunInstancesInput{
ImageId: aws.String(imageId),
MinCount: aws.Int64(int64(minCount)),
MaxCount: aws.Int64(int64(maxCount)),
InstanceType: aws.String(instanceType),
KeyName: aws.String(keyName),
})
if err != nil {
return nil, err
}
return res, nil
}
func main() {
sess, err := session.NewSessionWithOptions(session.Options{
Profile: "default",
Config: aws.Config{
Region: aws.String("us-west-2"),
},
})
if err != nil {
fmt.Printf("Failed to initialize new session: %v", err)
return
}
ec2Client := ec2.New(sess)
keyName := "ec2-go-tutorial-key-name"
instanceType := "t4g.nano"
minCount := 1
maxCount := 1
imageId := "ami-0b0154d3d8011b0cd"
newInstance, err := CreateInstance(ec2Client, imageId, minCount, maxCount, instanceType, keyName)
if err != nil {
fmt.Printf("Couldn't create new instance: %v", err)
return
}
fmt.Printf("Created new instance: %v\n", newInstance.Instances)
}
In this example, we create an EC2 instance using the t4g.nano
instance type and the key pair we created earlier.
Created new instance: [{
AmiLaunchIndex: 0,
Architecture: "arm64",
CapacityReservationSpecification: {
CapacityReservationPreference: "open"
},
ClientToken: "A9A3CDC5-BF00-461B-BACA-EA0F34D2B174",
CpuOptions: {
CoreCount: 2,
ThreadsPerCore: 1
},
EbsOptimized: false,
EnaSupport: true,
EnclaveOptions: {
Enabled: false
},
Hypervisor: "xen",
ImageId: "ami-0b0154d3d8011b0cd",
InstanceId: "i-083af8ae3eb0ea1dc",
....
How to list all running EC2 instances?
We will use the DescribeInstances method to get a list of all running instances. We will use the Filters
arguments to only return instances that are in the Running
state.
package main
import (
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"fmt"
)
func GetRunningInstances(client *ec2.EC2) (*ec2.DescribeInstancesOutput, error) {
result, err := client.DescribeInstances(&ec2.DescribeInstancesInput{
Filters: []*ec2.Filter{
{
Name: aws.String("instance-state-name"),
Values: []*string{
aws.String("running"),
},
},
},
})
if err != nil {
return nil, err
}
return result, err
}
func main() {
sess, err := session.NewSessionWithOptions(session.Options{
Profile: "default",
Config: aws.Config{
Region: aws.String("us-west-2"),
},
})
if err != nil {
fmt.Printf("Failed to initialize new session: %v", err)
return
}
ec2Client := ec2.New(sess)
runningInstances, err := GetRunningInstances(ec2Client)
if err != nil {
fmt.Printf("Couldn't retrieve running instances: %v", err)
return
}
for _, reservation := range runningInstances.Reservations {
for _, instance := range reservation.Instances {
fmt.Printf("Found running instance: %s\n", *instance.InstanceId)
}
}
}
Output:
Found running instance: i-01f702b40bba89a19
How to stop an EC2 instance?
An EC2 instance can be shut down using the StopInstances method. AWS doesn’t charge for stopped EC2 instances (except for any EBS volumes).
package main
import (
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"fmt"
)
func StopInstance(client *ec2.EC2, instanceId string) error {
_, err := client.StopInstances(&ec2.StopInstancesInput{
InstanceIds: []*string{&instanceId},
})
return err
}
func main() {
sess, err := session.NewSessionWithOptions(session.Options{
Profile: "default",
Config: aws.Config{
Region: aws.String("us-west-2"),
},
})
if err != nil {
fmt.Printf("Failed to initialize new session: %v", err)
return
}
ec2Client := ec2.New(sess)
instanceId := "i-01f702b40bba89a19"
err = StopInstance(ec2Client, instanceId)
if err != nil {
fmt.Printf("Couldn't stop instance: %v", err)
}
fmt.Println("Stopped instance with id: ", instanceId)
}
Stopped instance with id: i-01f702b40bba89a19
How to terminate an EC2 instance?
We will use the TerminateInstances method to terminate and remove EC2 instances.
package main
import (
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"fmt"
)
func TerminateInstance(client *ec2.EC2, instanceId string) error {
_, err := client.TerminateInstances(&ec2.TerminateInstancesInput{
InstanceIds: []*string{&instanceId},
})
return err
}
func main() {
sess, err := session.NewSessionWithOptions(session.Options{
Profile: "default",
Config: aws.Config{
Region: aws.String("us-west-2"),
},
})
if err != nil {
fmt.Printf("Failed to initialize new session: %v", err)
return
}
ec2Client := ec2.New(sess)
instanceId := "i-01f702b40bba89a19"
err = TerminateInstance(ec2Client, instanceId)
if err != nil {
fmt.Printf("Couldn't terimate instance: %v", err)
}
fmt.Println("Terminated instance with id: ", instanceId)
}
Terminated instance with id: i-01f702b40bba89a19