

AWS SDK for Go V1 has reached end-of-support. We recommend that you migrate to [AWS SDK for Go V2](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/). For additional details and information on how to migrate, please refer to this [announcement](https://aws.amazon.com/blogs//developer/announcing-end-of-support-for-aws-sdk-for-go-v1-on-july-31-2025/).

# Amazon EC2 Examples Using the AWS SDK for Go
Amazon EC2 Examples

Amazon Elastic Compute Cloud (Amazon EC2) is a web service that provides resizable computing capacity—literally servers in Amazon’s data centers—that you use to build and host your software systems. The AWS SDK for Go examples can integrate Amazon EC2 into your Go applications. The examples assume you have already set up and configured the SDK (that is, you have imported all required packages and set your credentials and region). For more information, see [Getting Started with the AWS SDK for Go](setting-up.md) and [Configuring the AWS SDK for Go](configuring-sdk.md).

You can download complete versions of these example files from the [aws-doc-sdk-examples](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/go/example_code/s3) repository on GitHub.

**Topics**
+ [

# Creating Amazon EC2 Instances with Tags or without Block Devices
](ec2-example-create-images.md)
+ [

# Managing Amazon EC2 Instances
](ec2-example-manage-instances.md)
+ [

# Working with Amazon EC2 Key Pairs
](ec2-example-working-with-key-pairs.md)
+ [

# Using Regions and Availability Zones with Amazon EC2
](ec2-example-regions-availability-zones.md)
+ [

# Working with Security Groups in Amazon EC2
](ec2-example-security-groups.md)
+ [

# Using Elastic IP Addresses in Amazon EC2
](ec2-example-elastic-ip-addresses.md)

# Creating Amazon EC2 Instances with Tags or without Block Devices


This Go example shows you how to:
+ Create an Amazon EC2 instance with tags or set up an instance without a block device

You can download complete versions of these example files from the [aws-doc-sdk-examples](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/go/example_code/ec2) repository on GitHub.

## Scenarios


In these examples, you use a series of Go routines to create Amazon EC2 instances with tags or set up an instance without a block device.

The routines use the AWS SDK for Go to perform these tasks by using these methods of the [EC2](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2) type:
+  [BlockDeviceMapping](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#BlockDeviceMapping) 
+  [RunInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.RunInstances) 
+  [CreateTags](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.CreateTags) 

## Prerequisites

+ You have [set up](setting-up.md) and [configured](configuring-sdk.md) the AWS SDK for Go.

## Create an Instance with Tags


The Amazon EC2 service has an operation for creating instances ([RunInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.RunInstances)) and another for attaching tags to instances ([CreateTags](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.CreateTags)). To create an instance with tags, call both of these operations in succession. The following example creates an instance and then adds a `Name` tag to it. The Amazon EC2 console displays the value of the `Name` tag in its list of instances.

```
package main

import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"

    "fmt"
    "log"
)

func main() {
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-2")},
    )

    // Create EC2 service client
    svc := ec2.New(sess)

    // Specify the details of the instance that you want to create.
    runResult, err := svc.RunInstances(&ec2.RunInstancesInput{
        // An Amazon Linux AMI ID for t2.micro instances in the us-west-2 region
        ImageId:      aws.String("ami-e7527ed7"),
        InstanceType: aws.String("t2.micro"),
        MinCount:     aws.Int64(1),
        MaxCount:     aws.Int64(1),
    })

    if err != nil {
        fmt.Println("Could not create instance", err)
        return
    }

    fmt.Println("Created instance", *runResult.Instances[0].InstanceId)

    // Add tags to the created instance
    _, errtag := svc.CreateTags(&ec2.CreateTagsInput{
        Resources: []*string{runResult.Instances[0].InstanceId},
        Tags: []*ec2.Tag{
            {
                Key:   aws.String("Name"),
                Value: aws.String("MyFirstInstance"),
            },
        },
    })
    if errtag != nil {
        log.Println("Could not create tags for instance", runResult.Instances[0].InstanceId, errtag)
        return
    }

    fmt.Println("Successfully tagged instance")
}
```

You can add up to 10 tags to an instance in a single `CreateTags` operation.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/create_instance.go) on GitHub.

## Create an Image without a Block Device


Sometimes when you create an Amazon EC2 image, you might want to explicitly exclude certain block devices. To do this, you can use the `NoDevice` parameter in [BlockDeviceMapping](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#BlockDeviceMapping). When this parameter is set to an empty string `""`, the named device isn’t mapped.

The `NoDevice` parameter is compatible only with `DeviceName`, not with any other field in `BlockDeviceMapping`. The request will fail if other parameters are present.

```
package main

import (
    "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 main() {
    // Load session from shared config
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))

    // Create EC2 service client
    svc := ec2.New(sess)

    opts := &ec2.CreateImageInput{
        Description: aws.String("image description"),
        InstanceId:  aws.String("i-abcdef12"),
        Name:        aws.String("image name"),
        BlockDeviceMappings: []*ec2.BlockDeviceMapping{
            {
                DeviceName: aws.String("/dev/sda1"),
                NoDevice:    aws.String(""),
            },
            {
                DeviceName: aws.String("/dev/sdb"),
                NoDevice:    aws.String(""),
            },
            {
                DeviceName: aws.String("/dev/sdc"),
                NoDevice:    aws.String(""),
            },
        },
    }
    resp, err := svc.CreateImage(opts)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("ID: ", resp.ImageId)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/create_image_no_block_device.go) on GitHub.

# Managing Amazon EC2 Instances


These Go examples show you how to:
+ Describe Amazon EC2 instances
+ Manage Amazon EC2 instance monitoring
+ Start and stop Amazon EC2 instances
+ Reboot Amazon EC2 instances

You can download complete versions of these example files from the [aws-doc-sdk-examples](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/go/example_code/ec2) repository on GitHub.

## Scenario


In these examples, you use a series of Go routines to perform several basic instance management operations.

The routines use the AWS SDK for Go to perform the operations by using these methods of the Amazon EC2 client class:
+  [DescribeInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeInstances) 
+  [MonitorInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.MonitorInstances) 
+  [UnmonitorInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.UnmonitorInstances) 
+  [StartInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.StartInstances) 
+  [StopInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.StopInstances) 
+  [RebootInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.RebootInstances) 

## Prerequisites

+ You have [set up](setting-up.md) and [configured](configuring-sdk.md) the AWS SDK for Go.
+ You are familiar with the lifecycle of Amazon EC2 instances. To learn more, see [Instance Lifecycle](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html) in the Amazon EC2 User Guide.

## Describe Your Instances


Create a new Go file named `describing_instances.go`.

The Amazon EC2 service has an operation for describing instances, [DescribeInstances](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeInstances).

Import the required AWS SDK for Go packages.

```
package main

import (
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"

    "fmt"
)
```

Use the following code to create a session and Amazon EC2 client.

```
// Load session from shared config
sess := session.Must(session.NewSessionWithOptions(session.Options{
    SharedConfigState: session.SharedConfigEnable,
}))

// Create new EC2 client
ec2Svc := ec2.New(sess)
```

Call `DescribeInstances` to get detailed information for each instance.

```
// Call to get detailed information on each instance
result, err := ec2Svc.DescribeInstances(nil)
if err != nil {
    fmt.Println("Error", err)
} else {
    fmt.Println("Success", result)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/describing_instances.go) on GitHub.

## Manage Instance Monitoring


Create a new Go file named `monitoring_instances.go`.

Import the required AWS SDK for Go packages.

```
package main

import (
    "fmt"
    "os"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

To access Amazon EC2, create an EC2 client.

```
func main() {
    // Load session from shared config
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))

    // Create new EC2 client
    svc := ec2.New(sess)
```

Based on the value of a command-line argument (ON or OFF), call either the `MonitorInstances` method of the Amazon EC2 service object to begin detailed monitoring of the specified instances, or the `UnmonitorInstances` method. Before you try to change the monitoring of these instances, use the `DryRun` parameter to test whether you have permission to change instance monitoring.

```
    if os.Args[1] == "ON" {
        input := &ec2.MonitorInstancesInput{
            InstanceIds: []*string{
                aws.String(os.Args[2]),
            },
            DryRun: aws.Bool(true),
        }
        result, err := svc.MonitorInstances(input)
        awsErr, ok := err.(awserr.Error)

        if ok && awsErr.Code() == "DryRunOperation" {
            input.DryRun = aws.Bool(false)
            result, err = svc.MonitorInstances(input)
            if err != nil {
                fmt.Println("Error", err)
            } else {
                fmt.Println("Success", result.InstanceMonitorings)
            }
        } else {
            fmt.Println("Error", err)
        }
    } else if os.Args[1] == "OFF" { // Turn monitoring off
        input := &ec2.UnmonitorInstancesInput{
            InstanceIds: []*string{
                aws.String(os.Args[2]),
            },
            DryRun: aws.Bool(true),
        }
        result, err := svc.UnmonitorInstances(input)
        awsErr, ok := err.(awserr.Error)
        if ok && awsErr.Code() == "DryRunOperation" {
            input.DryRun = aws.Bool(false)
            result, err = svc.UnmonitorInstances(input)
            if err != nil {
                fmt.Println("Error", err)
            } else {
                fmt.Println("Success", result.InstanceMonitorings)
            }
        } else {
            fmt.Println("Error", err)
        }
    }

}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/monitoring_instances.go) on GitHub.

## Start and Stop Instances


Create a new Go file named `start_stop_instances.go`.

Import the required AWS SDK for Go packages.

```
package main

import (
    "fmt"
    "os"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

To access Amazon EC2, create an EC2 client. The user will pass in a state value of START or STOP and the instance ID.

```
func main() {
    // Load session from shared config
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))

    // Create new EC2 client
    svc := ec2.New(sess)
```

Based on the value of a command-line argument (START or STOP), call either the `StartInstances` method of the Amazon EC2 service object to start the specified instances, or the `StopInstances` method to stop them. Before you try to start or stop the selected instances, use the `DryRun` parameter to test whether you have permission to start or stop them.

```
    if os.Args[1] == "START" {
        input := &ec2.StartInstancesInput{
            InstanceIds: []*string{
                aws.String(os.Args[2]),
            },
            DryRun: aws.Bool(true),
        }
        result, err := svc.StartInstances(input)
        awsErr, ok := err.(awserr.Error)

        if ok && awsErr.Code() == "DryRunOperation" {
            // Let's now set dry run to be false. This will allow us to start the instances
            input.DryRun = aws.Bool(false)
            result, err = svc.StartInstances(input)
            if err != nil {
                fmt.Println("Error", err)
            } else {
                fmt.Println("Success", result.StartingInstances)
            }
        } else { // This could be due to a lack of permissions
            fmt.Println("Error", err)
        }
    } else if os.Args[1] == "STOP" { // Turn instances off
        input := &ec2.StopInstancesInput{
            InstanceIds: []*string{
                aws.String(os.Args[2]),
            },
            DryRun: aws.Bool(true),
        }
        result, err := svc.StopInstances(input)
        awsErr, ok := err.(awserr.Error)
        if ok && awsErr.Code() == "DryRunOperation" {
            input.DryRun = aws.Bool(false)
            result, err = svc.StopInstances(input)
            if err != nil {
                fmt.Println("Error", err)
            } else {
                fmt.Println("Success", result.StoppingInstances)
            }
        } else {
            fmt.Println("Error", err)
        }
    }
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/start_stop_instances.go) on GitHub.

## Reboot Instances


Create a new Go file named `reboot_instances.go`.

Import the required AWS SDK for Go packages.

```
package main

import (
    "fmt"
    "os"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

To access Amazon EC2, create an EC2 client. The user will pass in a state value of START or STOP and the instance ID.

```
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))

    // Create new EC2 client
    svc := ec2.New(sess)
```

Based on the value of a command-line argument (START or STOP), call either the `StartInstances` method of the Amazon EC2 service object to start the specified instances, or the `StopInstances` method to stop them. Before you try to reboot the selected instances, use the `DryRun` parameter to test whether the instance exists and that you have permission to reboot it.

```
    input := &ec2.RebootInstancesInput{
        InstanceIds: []*string{
            aws.String(os.Args[1]),
        },
        DryRun: aws.Bool(true),
    }
    result, err := svc.RebootInstances(input)
    awsErr, ok := err.(awserr.Error)
```

If the error code is `DryRunOperation`, it means that you do have the permissions you need to reboot the instance.

```
    if ok && awsErr.Code() == "DryRunOperation" {
        input.DryRun = aws.Bool(false)
        result, err = svc.RebootInstances(input)
        if err != nil {
            fmt.Println("Error", err)
        } else {
            fmt.Println("Success", result)
        }
    } else { // This could be due to a lack of permissions
        fmt.Println("Error", err)
    }
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/reboot_instances.go) on GitHub.

# Working with Amazon EC2 Key Pairs


These Go examples show you how to:
+ Describe an Amazon EC2 key pair
+ Create an Amazon EC2 key pair
+ Delete an Amazon EC2 key pair

You can download complete versions of these example files from the [aws-doc-sdk-examples](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/go/example_code/ec2) repository on GitHub.

## Scenario


Amazon EC2 uses public–key cryptography to encrypt and decrypt login information. Public–key cryptography uses a public key to encrypt data, then the recipient uses the private key to decrypt the data. The public and private keys are known as a key pair.

The routines use the AWS SDK for Go to perform these tasks by using these methods of the [EC2](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2) type:
+  [CreateKeyPair](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.CreateKeyPair) 
+  [DeleteKeyPair](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DeleteKeyPair) 
+  [DescribeKeyPairs](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeKeyPairs) 

## Prerequisites

+ You have [set up](setting-up.md) and [configured](configuring-sdk.md) the SDK.
+ You are familiar with Amazon EC2 key pairs. To learn more, see [Amazon EC2 Key Pairs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) in the Amazon EC2 User Guide.

## Describe Your Key Pairs


Create a new Go file named `ec2_describe_keypairs.go`.

Import the required AWS SDK for Go packages.

```
package main

import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"

    "fmt"
    "os"
)
```

Use the following code to create a session and Amazon EC2 client.

```
//    go run ec2_describe_keypairs.go
    // credentials from the shared credentials file ~/.aws/credentials.
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-2")},
    )

    // Create an EC2 service client.
```

Call `DescribeKeyPairs` to get a list of key pairs and print them out.

```
    //  Returns a list of key pairs
    result, err := svc.DescribeKeyPairs(nil)
    if err != nil {
        exitErrorf("Unable to get key pairs, %v", err)
    }

    fmt.Println("Key Pairs:")
    for _, pair := range result.KeyPairs {
        fmt.Printf("%s: %s\n", *pair.KeyName, *pair.KeyFingerprint)
    }
```

The routine uses the following utility function.

```
func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_describe_keypairs.go) on GitHub.

## Create a Key Pair


Create a new Go file named `ec2_create_keypair.go`.

Import the required AWS SDK for Go packages.

```
package main

import (
    "fmt"
    "os"
    "path/filepath"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

Get the key pair name passed in to the code and, to access Amazon EC2, create an EC2 client.

```
func main() {
    if len(os.Args) != 2 {
        exitErrorf("pair name required\nUsage: %s key_pair_name",
            filepath.Base(os.Args[0]))
    }
    pairName := os.Args[1]
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-2")},
    )

    // Create an EC2 service client.
    svc := ec2.New(sess)
```

Create a new key pair with the provided name.

```
    result, err := svc.CreateKeyPair(&ec2.CreateKeyPairInput{
        KeyName: aws.String(pairName),
    })
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "InvalidKeyPair.Duplicate" {
            exitErrorf("Keypair %q already exists.", pairName)
        }
        exitErrorf("Unable to create key pair: %s, %v.", pairName, err)
    }

    fmt.Printf("Created key pair %q %s\n%s\n",
        *result.KeyName, *result.KeyFingerprint,
        *result.KeyMaterial)
}
```

The routine uses the following utility function.

```
func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_create_keypair.go) on GitHub.

## Delete a Key Pair


Create a new Go file named `ec2_delete_keypair.go`.

Import the required AWS SDK for Go packages.

```
package main

import (
    "fmt"
    "os"
    "path/filepath"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

Get the key pair name passed in to the code and, to access Amazon EC2, create an EC2 client.

```
func main() {
    if len(os.Args) != 2 {
        exitErrorf("pair name required\nUsage: %s key_pair_name",
            filepath.Base(os.Args[0]))
    }
    pairName := os.Args[1]

    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-2")},
    )

    // Create an EC2 service client.
    svc := ec2.New(sess)
```

Delete the key pair with the provided name.

```
    _, err = svc.DeleteKeyPair(&ec2.DeleteKeyPairInput{
        KeyName: aws.String(pairName),
    })
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "InvalidKeyPair.Duplicate" {
            exitErrorf("Key pair %q does not exist.", pairName)
        }
        exitErrorf("Unable to delete key pair: %s, %v.", pairName, err)
    }

    fmt.Printf("Successfully deleted %q key pair\n", pairName)
}
```

The routine uses the following utility function.

```
func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_delete_keypair.go) on GitHub.

# Using Regions and Availability Zones with Amazon EC2


These Go examples show you how to retrieve details about AWS Regions and Availability Zones.

The code in this example uses the AWS SDK for Go to perform these tasks by using these methods of the Amazon EC2 client class:
+  [DescribeRegions](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeRegions) 
+  [DescribeAvailabilityZones](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeAvailabilityZones) 

You can download complete versions of these example files from the [aws-doc-sdk-examples](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/go/example_code/ec2) repository on GitHub.

## Scenario


Amazon EC2 is hosted in multiple locations worldwide. These locations are composed of AWS Regions and Availability Zones. Each region is a separate geographic area with multiple, isolated locations known as Availability Zones. Amazon EC2 provides the ability to place instances and data in these multiple locations.

In this example, you use Go code to retrieve details about regions and Availability Zones. The code uses the AWS SDK for Go tomanage instances by using the following methods of the Amazon EC2 client class:
+  [DescribeAvailabilityZones](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeAvailabilityZones) 
+  [DescribeRegions](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeRegions) 

## Prerequisites

+ You have [set up](setting-up.md) and [configured](configuring-sdk.md) the AWS SDK for Go.
+ You are familiar with AWS Regions and Availability Zones. To learn more, see [Regions and Availability Zones](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) in the Amazon EC2 User Guide or [Regions and Availability Zones](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/resources.html) in the Amazon EC2 User Guide.

## List the Regions


This example lists the regions in which Amazon EC2 is available.

To get started, create a new Go file named `regions_and_availability.go`.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

```
package main

import (
    "fmt"

    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

In the `main` function, create a session with credentials from the shared credentials file, `~/.aws/credentials`, and create a new EC2 client.

```
func main() {
    // Load session from shared config
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))

    // Create new EC2 client
    svc := ec2.New(sess)
```

Print out the list of regions that work with Amazon EC2 that are returned by calling `DescribeRegions`.

```
    resultRegions, err := svc.DescribeRegions(nil)
    if err != nil {
        fmt.Println("Error", err)
        return
    }
```

Add a call that retrieves Availability Zones only for the region of the EC2 service object.

```
    resultAvalZones, err := svc.DescribeAvailabilityZones(nil)
    if err != nil {
        fmt.Println("Error", err)
        return
    }

    fmt.Println("Success", resultAvalZones.AvailabilityZones)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/regions_and_availability.go) on GitHub.

# Working with Security Groups in Amazon EC2


These Go examples show you how to:
+ Retrieve information about your security groups
+ Create a security group to access an Amazon EC2 instance
+ Delete an existing security group

You can download complete versions of these example files from the [aws-doc-sdk-examples](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/go/example_code/ec2) repository on GitHub.

## Scenario


An Amazon EC2 security group acts as a virtual firewall that controls the traffic for one or more instances. You add rules to each security group to allow traffic to or from its associated instances. You can modify the rules for a security group at any time; the new rules are automatically applied to all instances that are associated with the security group.

The code in this example uses the AWS SDK for Go to perform these tasks by using these methods of the Amazon EC2 client class:
+  [DescribeSecurityGroups](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeSecurityGroups) 
+  [AuthorizeSecurityGroupIngress](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.AuthorizeSecurityGroupIngress) 
+  [CreateSecurityGroup](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.CreateSecurityGroup) 
+  [DescribeVpcs](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeVpcs) 
+  [DeleteSecurityGroup](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DeleteSecurityGroup) 

## Prerequisites

+ You have [set up](setting-up.md) and [configured](configuring-sdk.md) the AWS SDK for Go.
+ You are familiar with Amazon EC2 security groups. To learn more, see [Amazon EC2 Amazon Security Groups for Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html) in the Amazon EC2 User Guide or [Amazon EC2 Amazon Security Groups for Windows Instances](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/using-network-security.html) in the Amazon EC2 User Guide.

## Describing Your Security Groups


This example describes the security groups by IDs that are passed into the routine. It takes a space separated list of group IDs as input.

To get started, create a new Go file named `ec2_describe_security_groups.go`.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

```
import (
    "fmt"
    "os"
    "path/filepath"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

In the `main` function, get the security group ID that is passed in.

```
if len(os.Args) < 2 {
    exitErrorf("Security Group ID required\nUsage: %s group_id ...",
        filepath.Base(os.Args[0]))
}
groupIds := os.Args[1:]
```

Initialize a session and create an EC2 service client.

```
sess, err := session.NewSession(&aws.Config{
    Region: aws.String("us-west-2")},
)

// Create an EC2 service client.
svc := ec2.New(sess)
```

Obtain and print out the security group descriptions. You will explicitly check for errors caused by an invalid group ID.

```
result, err := svc.DescribeSecurityGroups(&ec2.DescribeSecurityGroupsInput{
    GroupIds: aws.StringSlice(groupIds),
})
if err != nil {
    if aerr, ok := err.(awserr.Error); ok {
        switch aerr.Code() {
        case "InvalidGroupId.Malformed":
            fallthrough
        case "InvalidGroup.NotFound":
            exitErrorf("%s.", aerr.Message())
        }
    }
    exitErrorf("Unable to get descriptions for security groups, %v", err)
}

fmt.Println("Security Group:")
for _, group := range result.SecurityGroups {
    fmt.Println(group)
}
```

The following utility function is used by this example to display errors.

```
func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_describe_security_groups.go) on GitHub.

## Creating a Security Group


You can create new Amazon EC2 security groups. To do this, you use the [CreateSecurityGroup](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.CreateSecurityGroup) method.

This example creates a new security group with the given name and description for access to open ports 80 and 22. If a VPC ID is not provided, it associates the security group with the first VPC in the account.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

```
import (
    "flag"
    "fmt"
    "os"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

Get the parameters (name, description, and optional ID of the VPC) that are passed in to the routine.

```
namePtr := flag.String("n", "", "Group Name")
descPtr := flag.String("d", "", "Group Description")
vpcIDPtr := flag.String("vpc", "", "(Optional) VPC ID to associate security group with")

flag.Parse()

if *namePtr == "" || *descPtr == "" {
    flag.PrintDefaults()
    exitErrorf("Group name and description require")
}
```

Create a session and Amazon EC2 client.

```
sess := session.Must(session.NewSessionWithOptions(session.Options{
    SharedConfigState: session.SharedConfigEnable,
}))

svc := ec2.New(sess)
```

Create an Amazon EC2 client. If the VPC ID was not provided, retrieve the first one in the account.

```
if *vpcIDPtr == "" {
    // Get a list of VPCs so we can associate the group with the first VPC.
    result, err := svc.DescribeVpcs(nil)
    if err != nil {
        exitErrorf("Unable to describe VPCs, %v", err)
    }
    if len(result.Vpcs) == 0 {
        exitErrorf("No VPCs found to associate security group with.")
    }

    *vpcIDPtr = aws.StringValue(result.Vpcs[0].VpcId)
}
```

Create the security group with the VPC ID, name, and description.

```
createRes, err := svc.CreateSecurityGroup(&ec2.CreateSecurityGroupInput{
    GroupName:   aws.String(*namePtr),
    Description: aws.String(*descPtr),
    VpcId:       aws.String(*vpcIDPtr),
})
if err != nil {
    if aerr, ok := err.(awserr.Error); ok {
        switch aerr.Code() {
        case "InvalidVpcID.NotFound":
            exitErrorf("Unable to find VPC with ID %q.", *vpcIDPtr)
        case "InvalidGroup.Duplicate":
            exitErrorf("Security group %q already exists.", *namePtr)
        }
    }
    exitErrorf("Unable to create security group %q, %v", *namePtr, err)
}

fmt.Printf("Created security group %s with VPC %s.\n",
    aws.StringValue(createRes.GroupId), *vpcIDPtr)
```

Add permissions to the security group.

```
_, err = svc.AuthorizeSecurityGroupIngress(&ec2.AuthorizeSecurityGroupIngressInput{
    GroupName: aws.String(*namePtr),
    IpPermissions: []*ec2.IpPermission{
        // Can use setters to simplify seting multiple values without the
        // needing to use aws.String or associated helper utilities.
        (&ec2.IpPermission{}).
            SetIpProtocol("tcp").
            SetFromPort(80).
            SetToPort(80).
            SetIpRanges([]*ec2.IpRange{
                {CidrIp: aws.String("0.0.0.0/0")},
            }),
        (&ec2.IpPermission{}).
            SetIpProtocol("tcp").
            SetFromPort(22).
            SetToPort(22).
            SetIpRanges([]*ec2.IpRange{
                (&ec2.IpRange{}).
                    SetCidrIp("0.0.0.0/0"),
            }),
    },
})
if err != nil {
    exitErrorf("Unable to set security group %q ingress, %v", *namePtr, err)
}

fmt.Println("Successfully set security group ingress")
```

The following utility function is used by this example.

```
func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_create_security_group.go) on GitHub.

## Deleting a Security Group


You can delete an Amazon EC2 security group in code. To do this, you use the [DeleteSecurityGroup](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DeleteSecurityGroup) method.

This example deletes a security group with the given group ID.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

```
import (
    "fmt"
    "os"
    "path/filepath"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

Get the group ID that is passed in to the routine.

```
if len(os.Args) != 2 {
    exitErrorf("Security Group ID required\nUsage: %s group_id",
        filepath.Base(os.Args[0]))
}
groupID := os.Args[1]
```

Create a session.

```
sess, err := session.NewSession(&aws.Config{
    Region: aws.String("us-west-2")},
)

// Create an EC2 service client.
svc := ec2.New(sess)
```

Then delete the security group with the group ID that is passed in.

```
_, err = svc.DeleteSecurityGroup(&ec2.DeleteSecurityGroupInput{
    GroupId: aws.String(groupID),
})
if err != nil {
    if aerr, ok := err.(awserr.Error); ok {
        switch aerr.Code() {
        case "InvalidGroupId.Malformed":
            fallthrough
        case "InvalidGroup.NotFound":
            exitErrorf("%s.", aerr.Message())
        }
    }
    exitErrorf("Unable to get descriptions for security groups, %v.", err)
}

fmt.Printf("Successfully delete security group %q.\n", groupID)
```

This example uses the following utility function.

```
func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_delete_security_group.go) on GitHub.

# Using Elastic IP Addresses in Amazon EC2


These Go examples show you how to:
+ Describe Amazon EC2 instance IP addresses
+ Allocate addresses to Amazon EC2 instances
+ Release Amazon EC2 instance IP addresses

You can download complete versions of these example files from the [aws-doc-sdk-examples](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/go/example_code/ec2) repository on GitHub.

## Scenario


An Elastic IP address is a static IP address designed for dynamic cloud computing that is associated with your AWS account. It is a public IP address, reachable from the Internet. If your instance doesn’t have a public IP address, you can associate an Elastic IP address with the instance to enable communication with the Internet.

In this example, you use a series of Go routines to perform several Amazon EC2 operations involving Elastic IP addresses. The routines use the AWS SDK for Go to manage Elastic IP addresses by using these methods of the Amazon EC2 client class:
+  [DescribeAddresses](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeAddresses) 
+  [AllocateAddress](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.AllocateAddress) 
+  [AssociateAddress](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.AssociateAddress) 
+  [ReleaseAddress](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.ReleaseAddress) 

## Prerequisites

+ You have [set up](setting-up.md) and [configured](configuring-sdk.md) the AWS SDK for Go.
+ You are familiar with Elastic IP addresses in Amazon EC2. To learn more, see [Elastic IP Addresses](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) in the Amazon EC2 User Guide or [Elastic IP Addresses](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/elastic-ip-addresses-eip.html) in the Amazon EC2 User Guide.

## Describe Instance IP Addresses


Create a new Go file named `ec2_describe_addresses.go`.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

```
package main

import (
    "fmt"
    "os"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

### Get the Address Descriptions


This routine prints out the Elastic IP Addresses for the account’s VPC. Initialize a session that the SDK will use to load credentials from the shared credentials file, `~/.aws/credentials`, and create a new EC2 service client.

```
func main() {
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-2")},
    )

    // Create an EC2 service client.
    svc := ec2.New(sess)
```

Make the API request to EC2 filtering for the addresses in the account’s VPC.

```
    result, err := svc.DescribeAddresses(&ec2.DescribeAddressesInput{
        Filters: []*ec2.Filter{
            {
                Name:   aws.String("domain"),
                Values: aws.StringSlice([]string{"vpc"}),
            },
        },
    })
    if err != nil {
        exitErrorf("Unable to elastic IP address, %v", err)
    }

    // Printout the IP addresses if there are any.
    if len(result.Addresses) == 0 {
        fmt.Printf("No elastic IPs for %s region\n", *svc.Config.Region)
    } else {
        fmt.Println("Elastic IPs")
        for _, addr := range result.Addresses {
            fmt.Println("*", fmtAddress(addr))
        }
    }
}
```

The `fmtAddress` and `exitErrorf` functions are utility functions used in the example.

```
func fmtAddress(addr *ec2.Address) string {
    out := fmt.Sprintf("IP: %s,  allocation id: %s",
        aws.StringValue(addr.PublicIp), aws.StringValue(addr.AllocationId))
    if addr.InstanceId != nil {
        out += fmt.Sprintf(", instance-id: %s", *addr.InstanceId)
    }
    return out
}

func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_describe_addresses.go) on GitHub.

## Allocate Addresses to Instances


Create a new Go file named `ec2_allocate_address.go`.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

```
package main

import (
    "fmt"
    "os"
    "path/filepath"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

This routine attempts to allocate a VPC Elastic IP address for the current region. The IP address requires and will be associated with the instance ID that is passed in.

```
func main() {
    if len(os.Args) != 2 {
        exitErrorf("instance ID required\nUsage: %s instance_id",
            filepath.Base(os.Args[0]))
    }
    instanceID := os.Args[1]
```

You will need to initialize a session that the SDK will use to load credentials from the shared credentials file, `~/.aws/credentials`, and create a new Amazon EC2 service client.

```
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-2")},
    )

    // Create an EC2 service client.
    svc := ec2.New(sess)
```

Call [AllocateAddress](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.AllocateAddress), passing in “vpc” as the Domain value.

```
    allocRes, err := svc.AllocateAddress(&ec2.AllocateAddressInput{
        Domain: aws.String("vpc"),
    })
    if err != nil {
        exitErrorf("Unable to allocate IP address, %v", err)
    }
```

Call [AssociateAddress](https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.AssociateAddress) to associate the new Elastic IP address with an existing Amazon EC2 instance, and print out the results.

```
    assocRes, err := svc.AssociateAddress(&ec2.AssociateAddressInput{
        AllocationId: allocRes.AllocationId,
        InstanceId:   aws.String(instanceID),
    })
    if err != nil {
        exitErrorf("Unable to associate IP address with %s, %v",
            instanceID, err)
    }

    fmt.Printf("Successfully allocated %s with instance %s.\n\tallocation id: %s, association id: %s\n",
        *allocRes.PublicIp, instanceID, *allocRes.AllocationId, *assocRes.AssociationId)
}
```

This example also uses the `exitErrorf` utility function.

```
func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_allocate_address.go) on GitHub.

## Release Instance IP Addresses


This routine releases an Elastic IP address allocation ID. If the address is associated with an Amazon EC2 instance, the association is removed.

Create a new Go file named `ec2_release_address.go`.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

```
package main

import (
    "fmt"
    "os"
    "path/filepath"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
)
```

The routine requires that the user pass in the allocation ID of the Elastic IP address.

```
func main() {
    if len(os.Args) != 2 {
        exitErrorf("allocation ID required\nUsage: %s allocation_id",
            filepath.Base(os.Args[0]))
    }
    allocationID := os.Args[1]
```

Initialize a session that the SDK will use to load credentials from the shared credentials file, `~/.aws/credentials`, and create a new EC2 service client.

```
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-2")},
    )

    // Create an EC2 service client.
    svc := ec2.New(sess)
```

Attempt to release the Elastic IP address by using the allocation ID.

```
    _, err = svc.ReleaseAddress(&ec2.ReleaseAddressInput{
        AllocationId: aws.String(allocationID),
    })
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "InvalidAllocationID.NotFound" {
            exitErrorf("Allocation ID %s does not exist", allocationID)
        }
        exitErrorf("Unable to release IP address for allocation %s, %v",
            allocationID, err)
    }

    fmt.Printf("Successfully released allocation ID %s\n", allocationID)
}
```

This example uses the `fmtAddress` and `exitErrorf` utility functions.

```
func fmtAddress(addr *ec2.Address) string {
    out := fmt.Sprintf("IP: %s,  allocation id: %s",
        aws.StringValue(addr.PublicIp), aws.StringValue(addr.AllocationId))
    if addr.InstanceId != nil {
        out += fmt.Sprintf(", instance-id: %s", *addr.InstanceId)
    }
    return out
}

func exitErrorf(msg string, args ...interface{}) {
    fmt.Fprintf(os.Stderr, msg+"\n", args...)
    os.Exit(1)
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/example_code/ec2/ec2_describe_addresses.go) on GitHub.