diff --git a/README.md b/README.md index 377f53c..96a22ab 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ web-path | path to static web files (for development or custom front end) | | WE proxy-path | path prefix when service is run behind a proxy | | PROXY_PATH | proxy-port | port of the proxy when the service is run behind a proxy | | PROXY_PORT | ga-key | google analytics key for the front end | | GA_KEY | -provider | which storage provider to use | (s3, storj, gdrive or local) | +provider | which storage provider to use | (s3, s3-ec2role, storj, gdrive or local) | uservoice-key | user voice key for the front end | | USERVOICE_KEY | aws-access-key | aws access key | | AWS_ACCESS_KEY | aws-secret-key | aws access key | | AWS_SECRET_KEY | @@ -155,6 +155,17 @@ For the usage with a AWS S3 Bucket, you just need to specify the following optio If you specify the s3-region, you don't need to set the endpoint URL since the correct endpoint will used automatically. +### S3 Usage with an AWS IAM Role + +With the `s3-ec2role` provider you can use S3 without static credentials: aws-access-key and aws-secret-key. + +You just need to specify the following options: + - provider + - bucket + - s3-region + +How it works, [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html). + ### Custom S3 providers To use a custom non-AWS S3 provider, you need to specify the endpoint as defined from your cloud provider. diff --git a/cmd/cmd.go b/cmd/cmd.go index cb8892e..baf6e0a 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -112,7 +112,7 @@ var globalFlags = []cli.Flag{ }, cli.StringFlag{ Name: "provider", - Usage: "s3|gdrive|local", + Usage: "s3|s3-ec2role|gdrive|local", Value: "", EnvVar: "PROVIDER", }, @@ -445,6 +445,14 @@ func New() *Cmd { } else { options = append(options, server.UseStorage(storage)) } + case "s3-ec2role": // using AWS IAM Role and EC2 Profile + if bucket := c.String("bucket"); bucket == "" { + panic("bucket not set.") + } else if storage, err := server.NewS3Storage("", "", bucket, purgeDays, c.String("s3-region"), c.String("s3-endpoint"), c.Bool("s3-no-multipart"), c.Bool("s3-path-style"), logger); err != nil { + panic(err) + } else { + options = append(options, server.UseStorage(storage)) + } case "gdrive": chunkSize := c.Int("gdrive-chunk-size") diff --git a/server/utils.go b/server/utils.go index e97ff1a..8e85123 100644 --- a/server/utils.go +++ b/server/utils.go @@ -41,6 +41,21 @@ import ( ) func getAwsSession(accessKey, secretKey, region, endpoint string, forcePathStyle bool) *session.Session { + + if accessKey+secretKey == "" { + return session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + Config: aws.Config{ + // this config will be used only for backward compatibility to work with S3 client and s3manager; + // a not for getting session credentials; + // will be better to refactor NewS3Storage() function with s3.New(sess, &aws.Config{...}) + Region: aws.String(region), + Endpoint: aws.String(endpoint), + S3ForcePathStyle: aws.Bool(forcePathStyle), + }, + })) + } + return session.Must(session.NewSession(&aws.Config{ Region: aws.String(region), Endpoint: aws.String(endpoint),