Repository: chanzuckerberg/fogg
Pull request #494 (2020-09-08 20:30:51)

[feature] configure bless providers with a role
Allow configuring bless providers with a role_arn, in addition to a profile.

Support was
[previously](https://github.com/chanzuckerberg/terraform-provider-bless/pull/33)
added to the provider.

### Test Plan
* unit tests

### References
* https://github.com/chanzuckerberg/terraform-provider-bless/pull/33

codecov-commenter: # [Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/494?src=pr&el=h1) Report
> Merging [#494](https://codecov.io/gh/chanzuckerberg/fogg/pull/494?src=pr&el=desc) into [master](https://codecov.io/gh/chanzuckerberg/fogg/commit/22cc7744e789d98a055010b1987e602bce3373b7?el=desc) will **increase** coverage by `0.44%`.
> The diff coverage is `83.33%`.

[![Impacted file tree graph](https://codecov.io/gh/chanzuckerberg/fogg/pull/494/graphs/tree.svg?width=650&height=150&src=pr&token=57DhtZ7g2A)](https://codecov.io/gh/chanzuckerberg/fogg/pull/494?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #494      +/-   ##
==========================================
+ Coverage   59.27%   59.72%   +0.44%     
==========================================
  Files          19       19              
  Lines        1994     2001       +7     
==========================================
+ Hits         1182     1195      +13     
+ Misses        654      649       -5     
+ Partials      158      157       -1     
```


| [Impacted Files](https://codecov.io/gh/chanzuckerberg/fogg/pull/494?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [config/v2/config.go](https://codecov.io/gh/chanzuckerberg/fogg/pull/494/diff?src=pr&el=tree#diff-Y29uZmlnL3YyL2NvbmZpZy5nbw==) | `8.60% <ø> (ø)` | |
| [config/v2/validation.go](https://codecov.io/gh/chanzuckerberg/fogg/pull/494/diff?src=pr&el=tree#diff-Y29uZmlnL3YyL3ZhbGlkYXRpb24uZ28=) | `78.85% <0.00%> (ø)` | |
| [config/v2/resolvers.go](https://codecov.io/gh/chanzuckerberg/fogg/pull/494/diff?src=pr&el=tree#diff-Y29uZmlnL3YyL3Jlc29sdmVycy5nbw==) | `50.00% <100.00%> (+0.77%)` | :arrow_up: |
| [plan/plan.go](https://codecov.io/gh/chanzuckerberg/fogg/pull/494/diff?src=pr&el=tree#diff-cGxhbi9wbGFuLmdv) | `85.94% <100.00%> (+1.96%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/494?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/494?src=pr&el=footer). Last update [22cc774...40a7768](https://codecov.io/gh/chanzuckerberg/fogg/pull/494?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/config/v2/config.go b/config/v2/config.go
index 0ce8f8bd..c2625636 100644
--- a/config/v2/config.go
+++ b/config/v2/config.go
@@ -132,6 +132,7 @@ type BlessProvider struct {
 	AdditionalRegions []string `yaml:"additional_regions,omitempty"`
 	AWSProfile        *string  `yaml:"aws_profile,omitempty"`
 	AWSRegion         *string  `yaml:"aws_region,omitempty"`
+	RoleArn           *string  `yaml:"role_arn,omitempty"`
 	Version           *string  `yaml:"version,omitempty"`
 }
 
diff --git a/config/v2/resolvers.go b/config/v2/resolvers.go
index 4f7e4f39..5bba0551 100644
--- a/config/v2/resolvers.go
+++ b/config/v2/resolvers.go
@@ -253,16 +253,18 @@ func ResolveOktaProvider(commons ...Common) *OktaProvider {
 
 func ResolveBlessProvider(commons ...Common) *BlessProvider {
 	profile := lastNonNil(BlessProviderProfileGetter, commons...)
+	roleArn := lastNonNil(BlessProviderRoleArnGetter, commons...)
 	region := lastNonNil(BlessProviderRegionGetter, commons...)
 
 	// required fields
-	if profile == nil || region == nil {
+	if (profile == nil && roleArn == nil) || region == nil {
 		return nil
 	}
 
 	return &BlessProvider{
 		AWSProfile: profile,
 		AWSRegion:  region,
+		RoleArn:    roleArn,
 
 		Version:           lastNonNil(BlessProviderVersionGetter, commons...),
 		AdditionalRegions: ResolveOptionalStringSlice(BlessProviderAdditionalRegionsGetter, commons...),
@@ -596,6 +598,14 @@ func BlessProviderProfileGetter(comm Common) *string {
 	}
 	return comm.Providers.Bless.AWSProfile
 }
+
+func BlessProviderRoleArnGetter(comm Common) *string {
+	if comm.Providers == nil || comm.Providers.Bless == nil {
+		return nil
+	}
+	return comm.Providers.Bless.RoleArn
+}
+
 func BlessProviderRegionGetter(comm Common) *string {
 	if comm.Providers == nil || comm.Providers.Bless == nil {
 		return nil
diff --git a/config/v2/validation.go b/config/v2/validation.go
index 3c3d308d..a37d2f5a 100644
--- a/config/v2/validation.go
+++ b/config/v2/validation.go
@@ -174,8 +174,9 @@ func (p *BlessProvider) Validate(component string) error {
 	if p == nil {
 		return nil // nothing to do
 	}
-	if p.AWSProfile == nil {
-		errs = multierror.Append(errs, fmt.Errorf("bless provider aws_profile required in %s", component))
+
+	if p.AWSProfile == nil && p.RoleArn == nil {
+		errs = multierror.Append(errs, fmt.Errorf("bless provider requires aws_profile or role_arn in %s", component))
 	}
 	if p.AWSRegion == nil {
 		errs = multierror.Append(errs, fmt.Errorf("bless provider aws_region required in %s", component))
diff --git a/plan/plan.go b/plan/plan.go
index 2bdf72b7..310aeaf3 100644
--- a/plan/plan.go
+++ b/plan/plan.go
@@ -159,8 +159,9 @@ type OktaProvider struct {
 //BlessProvider represents Bless ssh provider configuration
 type BlessProvider struct {
 	AdditionalRegions []string `yaml:"additional_regions,omitempty"`
-	AWSProfile        string   `yaml:"aws_profile,omitempty"`
+	AWSProfile        *string  `yaml:"aws_profile,omitempty"`
 	AWSRegion         string   `yaml:"aws_region,omitempty"`
+	RoleArn           *string  `yaml:"role_arn,omitempty"`
 	Version           *string  `yaml:"version,omitempty"`
 }
 
@@ -509,11 +510,12 @@ func resolveComponentCommon(commons ...v2.Common) ComponentCommon {
 
 	var blessPlan *BlessProvider
 	blessConfig := v2.ResolveBlessProvider(commons...)
-	if blessConfig != nil && blessConfig.AWSProfile != nil && blessConfig.AWSRegion != nil {
+	if blessConfig != nil && (blessConfig.AWSProfile != nil || blessConfig.RoleArn != nil) && blessConfig.AWSRegion != nil {
 		blessPlan = &BlessProvider{
-			AWSProfile:        *blessConfig.AWSProfile,
+			AWSProfile:        blessConfig.AWSProfile,
 			AWSRegion:         *blessConfig.AWSRegion,
 			AdditionalRegions: blessConfig.AdditionalRegions,
+			RoleArn:           blessConfig.RoleArn,
 			Version:           blessConfig.Version,
 		}
 	}
diff --git a/templates/common/bless_provider.tmpl b/templates/common/bless_provider.tmpl
index 8887fb8d..4fc7ce07 100644
--- a/templates/common/bless_provider.tmpl
+++ b/templates/common/bless_provider.tmpl
@@ -5,7 +5,12 @@ provider bless {
   version = "~>{{ .Version }}"
   {{ end -}}
   region  = "{{ .AWSRegion }}"
+  {{ if .AWSProfile -}}
   profile = "{{ .AWSProfile }}"
+  {{ end -}}
+  {{ if .RoleArn -}}
+  role_arn = "{{ .RoleArn }}"
+  {{ end -}}
 }
 
 {{ $outer := . -}}
@@ -15,8 +20,13 @@ provider bless {
   {{ if $outer.Version -}}
   version = "~>{{ $outer.Version }}"
   {{ end -}}
-  region = "{{ $region }}"
+  region  = "{{ $region }}"
+  {{ if $outer.AWSProfile}}
   profile = "{{ $outer.AWSProfile }}"
+  {{ end -}}
+  {{ if $outer.RoleArn}}
+  role_arn = "{{ $outer.RoleArn }}"
+  {{ end -}}
 }
 {{ end }}
 {{ end }}


Test patch:
diff --git a/testdata/bless_provider_yaml/terraform/accounts/foo/fogg.tf b/testdata/bless_provider_yaml/terraform/accounts/foo/fogg.tf
index ef020a8b..78f940a5 100644
--- a/testdata/bless_provider_yaml/terraform/accounts/foo/fogg.tf
+++ b/testdata/bless_provider_yaml/terraform/accounts/foo/fogg.tf
@@ -10,12 +10,14 @@ provider bless {
   alias   = "a"
   version = "~>0.0.0"
   region  = "a"
+
   profile = "foofoofoo"
 }
 provider bless {
   alias   = "b"
   version = "~>0.0.0"
   region  = "b"
+
   profile = "foofoofoo"
 }
 terraform {
diff --git a/testdata/bless_provider_yaml/terraform/envs/bar/bam/fogg.tf b/testdata/bless_provider_yaml/terraform/envs/bar/bam/fogg.tf
index d39a1396..6a5bed5e 100644
--- a/testdata/bless_provider_yaml/terraform/envs/bar/bam/fogg.tf
+++ b/testdata/bless_provider_yaml/terraform/envs/bar/bam/fogg.tf
@@ -10,12 +10,14 @@ provider bless {
   alias   = "a"
   version = "~>0.0.0"
   region  = "a"
+
   profile = "foofoofoo"
 }
 provider bless {
   alias   = "b"
   version = "~>0.0.0"
   region  = "b"
+
   profile = "foofoofoo"
 }
 terraform {
diff --git a/testdata/bless_provider_yaml/terraform/global/fogg.tf b/testdata/bless_provider_yaml/terraform/global/fogg.tf
index df6ec224..50cc28b3 100644
--- a/testdata/bless_provider_yaml/terraform/global/fogg.tf
+++ b/testdata/bless_provider_yaml/terraform/global/fogg.tf
@@ -10,12 +10,14 @@ provider bless {
   alias   = "a"
   version = "~>0.0.0"
   region  = "a"
+
   profile = "foofoofoo"
 }
 provider bless {
   alias   = "b"
   version = "~>0.0.0"
   region  = "b"
+
   profile = "foofoofoo"
 }
 terraform {
diff --git a/testdata/v2_full_yaml/fogg.yml b/testdata/v2_full_yaml/fogg.yml
index 76a61171..ff1723e6 100644
--- a/testdata/v2_full_yaml/fogg.yml
+++ b/testdata/v2_full_yaml/fogg.yml
@@ -7,11 +7,19 @@ accounts:
           - us-east-1
           - us-east-2
         role: foo
+      bless:
+        role_arn: arn:aws:iam::1234567890:role/roll
+        version: 0.4.2
+        aws_region: us-west-2
   foo:
     providers:
       aws:
         account_id: 123
         role: roll
+      bless:
+        aws_profile: prof
+        version: 0.4.2
+        aws_region: us-west-2
 defaults:
   backend:
     bucket: buck
diff --git a/testdata/v2_full_yaml/terraform/accounts/bar/fogg.tf b/testdata/v2_full_yaml/terraform/accounts/bar/fogg.tf
index c07536ad..2944c5f8 100644
--- a/testdata/v2_full_yaml/terraform/accounts/bar/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/accounts/bar/fogg.tf
@@ -42,6 +42,12 @@ provider aws {
   allowed_account_ids = [456]
 }
 
+
+provider bless {
+  version  = "~>0.4.2"
+  region   = "us-west-2"
+  role_arn = "arn:aws:iam::1234567890:role/roll"
+}
 terraform {
   required_version = "=0.100.0"
   backend s3 {
diff --git a/testdata/v2_full_yaml/terraform/accounts/foo/fogg.tf b/testdata/v2_full_yaml/terraform/accounts/foo/fogg.tf
index c76c6d76..69743ffa 100644
--- a/testdata/v2_full_yaml/terraform/accounts/foo/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/accounts/foo/fogg.tf
@@ -14,6 +14,12 @@ provider aws {
 }
 # Aliased Providers (for doing things in every region).
 
+
+provider bless {
+  version = "~>0.4.2"
+  region  = "us-west-2"
+  profile = "prof"
+}
 terraform {
   required_version = "=0.100.0"
   backend s3 {