@@ -2,6 +2,7 @@ package aws
22
33import (
44 "context"
5+ "fmt"
56 "strings"
67 "sync"
78
@@ -128,6 +129,7 @@ func New(block schema.OptionBlock) (*Provider, error) {
128129 var sess * session.Session
129130 var err error
130131
132+ // Handle role assumption for assume_role_arn case
131133 if options .AssumeRoleArn != "" {
132134 stsSession , err := session .NewSession (config )
133135 if err != nil {
@@ -136,9 +138,18 @@ func New(block schema.OptionBlock) (*Provider, error) {
136138
137139 stsClient := sts .New (stsSession )
138140 roleInput := & sts.AssumeRoleInput {
139- RoleArn : aws .String (options .AssumeRoleArn ),
140- RoleSessionName : aws .String (options .AssumeRoleSessionName ),
141- ExternalId : aws .String (options .ExternalId ),
141+ RoleArn : aws .String (options .AssumeRoleArn ),
142+ }
143+
144+ // Only set optional fields if they are provided
145+ if options .AssumeRoleSessionName != "" {
146+ roleInput .RoleSessionName = aws .String (options .AssumeRoleSessionName )
147+ } else {
148+ roleInput .RoleSessionName = aws .String ("cloudlist-session" )
149+ }
150+
151+ if options .ExternalId != "" {
152+ roleInput .ExternalId = aws .String (options .ExternalId )
142153 }
143154
144155 assumeRoleOutput , err := stsClient .AssumeRole (roleInput )
@@ -147,7 +158,6 @@ func New(block schema.OptionBlock) (*Provider, error) {
147158 }
148159
149160 assumedCredentials := assumeRoleOutput .Credentials
150-
151161 sess , err = session .NewSession (& aws.Config {
152162 Credentials : credentials .NewStaticCredentials (
153163 * assumedCredentials .AccessKeyId ,
@@ -168,11 +178,58 @@ func New(block schema.OptionBlock) (*Provider, error) {
168178
169179 provider .session = sess
170180
181+ // Handle DescribeRegions call with fallback for assume_role_name case
182+ var regions * ec2.DescribeRegionsOutput
171183 rc := ec2 .New (sess )
172- regions , err := rc .DescribeRegions (& ec2.DescribeRegionsInput {})
173- if err != nil {
184+ regions , err = rc .DescribeRegions (& ec2.DescribeRegionsInput {})
185+
186+ if err != nil && options .AssumeRoleName != "" && len (options .AccountIds ) > 0 {
187+ // Base user doesn't have DescribeRegions permission, try with assumed role
188+ stsClient := sts .New (sess )
189+ roleArn := fmt .Sprintf ("arn:aws:iam::%s:role/%s" , options .AccountIds [0 ], options .AssumeRoleName )
190+
191+ roleInput := & sts.AssumeRoleInput {
192+ RoleArn : aws .String (roleArn ),
193+ }
194+
195+ if options .AssumeRoleSessionName != "" {
196+ roleInput .RoleSessionName = aws .String (options .AssumeRoleSessionName )
197+ } else {
198+ roleInput .RoleSessionName = aws .String ("cloudlist-session" )
199+ }
200+
201+ if options .ExternalId != "" {
202+ roleInput .ExternalId = aws .String (options .ExternalId )
203+ }
204+
205+ assumeRoleOutput , err := stsClient .AssumeRole (roleInput )
206+ if err != nil {
207+ return nil , errors .Wrap (err , "failed to assume role for DescribeRegions" )
208+ }
209+
210+ assumedCredentials := assumeRoleOutput .Credentials
211+ tempSession , err := session .NewSession (& aws.Config {
212+ Credentials : credentials .NewStaticCredentials (
213+ * assumedCredentials .AccessKeyId ,
214+ * assumedCredentials .SecretAccessKey ,
215+ * assumedCredentials .SessionToken ,
216+ ),
217+ Region : config .Region ,
218+ })
219+ if err != nil {
220+ return nil , errors .Wrap (err , "could not create assumed role session for DescribeRegions" )
221+ }
222+
223+ // Use assumed role session only for DescribeRegions
224+ tempRC := ec2 .New (tempSession )
225+ regions , err = tempRC .DescribeRegions (& ec2.DescribeRegionsInput {})
226+ if err != nil {
227+ return nil , errors .Wrap (err , "could not get list of regions even with assumed role" )
228+ }
229+ } else if err != nil {
174230 return nil , errors .Wrap (err , "could not get list of regions" )
175231 }
232+
176233 provider .regions = regions
177234
178235 services := provider .options .Services
0 commit comments