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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

"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.

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.

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.

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