We announced
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
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
-
You have set up, and configured the AWS SDK for Go.
-
You are familiar with Amazon S3 bucket polices. To learn more, see Using Bucket Policies and User Policies in the Amazon S3 Developer Guide.
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" )
Create 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")}, ) 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())
See the complete example
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.
func main() { 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.
sess, err := session.NewSession(&aws.Config{ Region: aws.String("us-west-2")}, ) svc := s3.New(sess)
Create a policy using the map interface, filling in the bucket as the resource.
readOnlyAnonUserPolicy := map[string]interface{}{ "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.
policy, err := json.Marshal(readOnlyAnonUserPolicy)
Call the S3 client’s PutBucketPolicy to PUT the policy for the bucket and print the results.
_, err = svc.PutBucketPolicy(&s3.PutBucketPolicyInput{ Bucket: aws.String(bucket), Policy: aws.String(string(policy)), }) fmt.Printf("Successfully set bucket %q's policy\n", bucket)
The exitError
function is used to deal with printing any errors.
func exitErrorf(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg+"\n", args...) os.Exit(1) }
See the complete example