Menu
AWS SDK for Go
Developer Guide

Working with Amazon S3 Bucket Policies

This AWS SDK for Go example shows you how to retrieve, display, and set Amazon S3 bucket polices. You can download complete versions of these example files from the aws-doc-sdk-examples repository on GitHub.

Scenario

In this example, you use a series of Go routines to retrieve or set a bucket policy on an Amazon S3 bucket. The routines use the AWS SDK for Go to configure policy for a selected Amazon S3 bucket using these methods of the Amazon S3 client class:

For more information about bucket policies for Amazon S3 buckets, see Using Bucket Policies and User Policies in the Amazon S3 Developer Guide.

Prerequisites

Retrieve and Display a Bucket Policy

Create a new Go file named s3_get_bucket_policy.go. You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

Copy
import ( "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/s3" "bytes" "encoding/json" "fmt" "os" "path/filepath" )

Creat the exitError function to deal with errors.

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

This routine prints the policy for a bucket. If the bucket doesn't exist, or there was an error, an error message is printed instead. It requires the bucket name as input.

Copy
if len(os.Args) != 2 { exitErrorf("bucket name required\nUsage: %s bucket_name", filepath.Base(os.Args[0])) } bucket := 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 S3 service client.

Copy
sess, err := session.NewSession(&aws.Config{ Region: aws.String("us-west-2")}, ) // Create S3 service client svc := s3.New(sess)

Call GetBucketPolicy to fetch the policy, then display any errors.

Copy
result, err := svc.GetBucketPolicy(&s3.GetBucketPolicyInput{ Bucket: aws.String(bucket), }) if err != nil { // Special error handling for the when the bucket doesn't // exists so we can give a more direct error message from the CLI. if aerr, ok := err.(awserr.Error); ok { switch aerr.Code() { case s3.ErrCodeNoSuchBucket: exitErrorf("Bucket %q does not exist.", bucket) case "NoSuchBucketPolicy": exitErrorf("Bucket %q does not have a policy.", bucket) } } exitErrorf("Unable to get bucket %q policy, %v.", bucket, err) }

Use Go's JSON package to print the Policy JSON returned by the call.

Copy
out := bytes.Buffer{} policyStr := aws.StringValue(result.Policy) if err := json.Indent(&out, []byte(policyStr), "", " "); err != nil { exitErrorf("Failed to pretty print bucket policy, %v.", err) } fmt.Printf("%q's Bucket Policy:\n", bucket) fmt.Println(out.String())

Set Bucket Policy

This routine sets the policy for a bucket. If the bucket doesn't exist, or there was an error, an error message will be printed instead. It requires the bucket name as input. It also requires the same Go and AWS SDK for Go packages as the previous example, except for the bytes Go package.

Copy
import ( "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/s3" "encoding/json" "fmt" "os" "path/filepath" )

Add the main function and parse the arguments to get the bucket name.

Copy
if len(os.Args) != 2 { exitErrorf("bucket name required\nUsage: %s bucket_name", filepath.Base(os.Args[0])) } bucket := os.Args[1]

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

Copy
Region: aws.String("us-west-2")}, ) // Create S3 service client svc := s3.New(sess)

Create a policy using the map interface, filling in the bucket as the resource.

Copy
"Version": "2012-10-17", "Statement": []map[string]interface{}{ { "Sid": "AddPerm", "Effect": "Allow", "Principal": "*", "Action": []string{ "s3:GetObject", }, "Resource": []string{ fmt.Sprintf("arn:aws:s3:::%s/*", bucket), }, }, }, }

Use Go's JSON package to marshal the policy into a JSON value so that it can be sent to S3.

Copy
if err != nil { exitErrorf("Failed to marshal policy, %v", err) }

Call the S3 client's PutBucketPolicy to PUT the policy for the bucket and print the results.

Copy
Bucket: aws.String(bucket), Policy: aws.String(string(policy)), }) if err != nil { if aerr, ok := err.(awserr.Error); ok && aerr.Code() == s3.ErrCodeNoSuchBucket { // Special error handling for the when the bucket doesn't // exists so we can give a more direct error message from the CLI. exitErrorf("Bucket %q does not exist", bucket) } exitErrorf("Unable to set bucket %q policy, %v", bucket, err) } fmt.Printf("Successfully set bucket %q's policy\n", bucket) }

The exitError function is used to deal with printing any errors.

Copy
fmt.Fprintf(os.Stderr, msg+"\n", args...) os.Exit(1) }