diff --git a/README.md b/README.md index 001fb35..66096c4 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,22 @@ You can also optionally specify the duration the sts assume role call should use This is useful if you have long running jobs on concourse. The duration should be specified in seconds, and between 1 hour and 12 hours. +If you need your created secrets to have certain tags applied you can add these as well: + +```json +{ + "name": "example-team", + "accounts": [{ + "name": "divx-lab", + "roleArn": "arn:aws:iam::123456789999:role/machine-user-example" + }], + "secretTags": { + "Team": "example", + "Environment": "Production" + } +} +``` + When the function is triggered with this input it will assume the `roleArn`, and write the credentials to (by default): diff --git a/handler.go b/handler.go index b0308ee..450c24b 100644 --- a/handler.go +++ b/handler.go @@ -32,7 +32,7 @@ func New(manager *Manager, secretTemplate string, logger *logrus.Logger) func(Co log.Warnf("failed to assume role: %s", err) continue } - if err := manager.WriteCredentials(creds, path); err != nil { + if err := manager.WriteCredentials(creds, path, team.SecretTags); err != nil { log.Warnf("failed to write credentials: %s", err) continue } diff --git a/handler_test.go b/handler_test.go index f6d1050..2534606 100644 --- a/handler_test.go +++ b/handler_test.go @@ -30,7 +30,10 @@ func TestHandler(t *testing.T) { "accounts": [{ "name": "test-account", "roleArn": "test-account-arn" - }] + }], + "secretTags": { + "Team": "test-team" + } } `) diff --git a/manager.go b/manager.go index 39e31c1..f37b821 100644 --- a/manager.go +++ b/manager.go @@ -94,7 +94,7 @@ func (m *Manager) AssumeRole(arn, team string, duration int64) (*sts.Credentials } // WriteCredentials handles writing a set of Credentials to the parameter store. -func (m *Manager) WriteCredentials(creds *sts.Credentials, path string) error { +func (m *Manager) WriteCredentials(creds *sts.Credentials, path string, secretTags map[string]string) error { values := map[string]string{ path + "-access-key": aws.StringValue(creds.AccessKeyId), path + "-secret-key": aws.StringValue(creds.SecretAccessKey), @@ -102,7 +102,7 @@ func (m *Manager) WriteCredentials(creds *sts.Credentials, path string) error { } for name, value := range values { - err := m.writeSecret(name, value) + err := m.writeSecret(name, value, secretTags) if err != nil { return err } @@ -110,12 +110,21 @@ func (m *Manager) WriteCredentials(creds *sts.Credentials, path string) error { return nil } -func (m *Manager) writeSecret(name, secret string) error { +func (m *Manager) writeSecret(name, secret string, secretTags map[string]string) error { + var tags []*secretsmanager.Tag + for k, v := range secretTags { + tags = append(tags, &secretsmanager.Tag{ + Key: aws.String(k), + Value: aws.String(v), + }) + } + var err error // Fewer API calls to naively try to create it and handle the error. _, err = m.secretsClient.CreateSecret(&secretsmanager.CreateSecretInput{ Name: aws.String(name), Description: aws.String("STS Credentials for Concourse."), + Tags: tags, }) if err != nil { e, ok := err.(awserr.Error) diff --git a/models.go b/models.go index 4346d44..a81c481 100644 --- a/models.go +++ b/models.go @@ -13,8 +13,9 @@ type Configuration struct { // Team represents the configuration for a single team. type Team struct { - Name string `json:"name"` - Accounts []*Account `json:"accounts"` + Name string `json:"name"` + Accounts []*Account `json:"accounts"` + SecretTags map[string]string `json:"secretTags"` } // Account represents the configuration for an assumable role. diff --git a/models_test.go b/models_test.go index 043f665..1b54bb1 100644 --- a/models_test.go +++ b/models_test.go @@ -28,7 +28,10 @@ func TestConfig(t *testing.T) { "name": "account2", "roleArn": "role2", "duration": 4000 - }] + }], + "secretTags": { + "Team": "team" + } } `), expected: handler.Team{ @@ -45,6 +48,9 @@ func TestConfig(t *testing.T) { Duration: 4000, }, }, + SecretTags: map[string]string{ + "Team": "team", + }, }, }, }