Skip to content

Commit

Permalink
[exporter/awss3exporter] Add the ability to assume the role provided …
Browse files Browse the repository at this point in the history
…by s3uploader.role_arn (open-telemetry#28674)

**Description:** <Describe what has changed.>

Adding a feature - This feature allows role assumption for s3
exportation. It is especially useful on Kubernetes clusters that are
using [IAM roles for service
accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)

**Testing:**

Deployed to a Kubernetes cluster as well as an EC2 instance and verified
it would assume the correct role and publish logs to the respective s3
bucket.

**Documentation:**

README updated
  • Loading branch information
thomasbaldwin authored Oct 31, 2023
1 parent b3328a7 commit 5018ac3
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 1 deletion.
27 changes: 27 additions & 0 deletions .chloggen/update-awss3exporter-to-assume-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: exporter/awss3exporter

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: "This feature allows role assumption for s3 exportation. It is especially useful on Kubernetes clusters that are using IAM roles for service accounts"

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [28674]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: ["user", "api"]
1 change: 1 addition & 0 deletions exporter/awss3exporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The following exporter configuration parameters are supported.
| `s3_bucket` | S3 bucket | |
| `s3_prefix` | prefix for the S3 key (root directory inside bucket). | |
| `s3_partition` | time granularity of S3 key: hour or minute | "minute" |
| `role_arn` | the Role ARN to be assumed | |
| `file_prefix` | file prefix defined by user | |
| `marshaler` | marshaler used to produce output data | `otlp_json` |
| `endpoint` | overrides the endpoint used by the exporter instead of constructing it from `region` and `s3_bucket` | |
Expand Down
1 change: 1 addition & 0 deletions exporter/awss3exporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type S3UploaderConfig struct {
S3Partition string `mapstructure:"s3_partition"`
FilePrefix string `mapstructure:"file_prefix"`
Endpoint string `mapstructure:"endpoint"`
RoleArn string `mapstructure:"role_arn"`
}

type MarshalerType string
Expand Down
14 changes: 13 additions & 1 deletion exporter/awss3exporter/s3_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
)
Expand Down Expand Up @@ -59,6 +60,17 @@ func getSessionConfig(config *Config) *aws.Config {
return sessionConfig
}

func getSession(config *Config, sessionConfig *aws.Config) (*session.Session, error) {
sess, err := session.NewSession(sessionConfig)

if config.S3Uploader.RoleArn != "" {
credentials := stscreds.NewCredentials(sess, config.S3Uploader.RoleArn)
sess.Config.Credentials = credentials
}

return sess, err
}

func (s3writer *s3Writer) writeBuffer(_ context.Context, buf []byte, config *Config, metadata string, format string) error {
now := time.Now()
key := getS3Key(now,
Expand All @@ -69,7 +81,7 @@ func (s3writer *s3Writer) writeBuffer(_ context.Context, buf []byte, config *Con
reader := bytes.NewReader(buf)

sessionConfig := getSessionConfig(config)
sess, err := session.NewSession(sessionConfig)
sess, err := getSession(config, sessionConfig)

if err != nil {
return err
Expand Down
38 changes: 38 additions & 0 deletions exporter/awss3exporter/s3_writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,41 @@ func TestGetSessionConfigNoEndpoint(t *testing.T) {
assert.Empty(t, sessionConfig.Endpoint)
assert.Equal(t, sessionConfig.Region, aws.String(region))
}

func TestGetSessionConfigWithRoleArn(t *testing.T) {
const region = "region"
const roleArn = "arn:aws:iam::12345:role/s3-exportation-role"
config := &Config{
S3Uploader: S3UploaderConfig{
Region: region,
RoleArn: roleArn,
},
}

sessionConfig := getSessionConfig(config)
sess, err := getSession(config, sessionConfig)

creds, _ := sess.Config.Credentials.Get()

assert.NoError(t, err)
assert.Equal(t, sessionConfig.Region, aws.String(region))
assert.Equal(t, creds.ProviderName, "AssumeRoleProvider")
}

func TestGetSessionConfigWithoutRoleArn(t *testing.T) {
const region = "region"
config := &Config{
S3Uploader: S3UploaderConfig{
Region: region,
},
}

sessionConfig := getSessionConfig(config)
sess, err := getSession(config, sessionConfig)

creds, _ := sess.Config.Credentials.Get()

assert.NoError(t, err)
assert.Equal(t, sessionConfig.Region, aws.String(region))
assert.NotEqual(t, creds.ProviderName, "AssumeRoleProvider")
}

0 comments on commit 5018ac3

Please sign in to comment.