Skip to content

Commit 2991930

Browse files
authored
feat: Implementation of backend commands: bootstrap, delete (#4070)
1 parent e81ecb8 commit 2991930

File tree

132 files changed

+6847
-6003
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+6847
-6003
lines changed

awshelper/config.go

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/aws/aws-sdk-go/aws/request"
1111
"github.com/aws/aws-sdk-go/service/iam"
12+
"github.com/aws/aws-sdk-go/service/s3"
1213
"github.com/gruntwork-io/go-commons/version"
1314

1415
"github.com/aws/aws-sdk-go/aws"
@@ -46,7 +47,7 @@ var addUserAgent = request.NamedHandler{
4647

4748
// CreateAwsSessionFromConfig returns an AWS session object for the given config region (required), profile name (optional), and IAM role to assume
4849
// (optional), ensuring that the credentials are available.
49-
func CreateAwsSessionFromConfig(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) (*session.Session, error) {
50+
func CreateAwsSessionFromConfig(config *AwsSessionConfig, opts *options.TerragruntOptions) (*session.Session, error) {
5051
defaultResolver := endpoints.DefaultResolver()
5152
s3CustResolverFn := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
5253
if service == "s3" && config.CustomS3Endpoint != "" {
@@ -89,7 +90,7 @@ func CreateAwsSessionFromConfig(config *AwsSessionConfig, terragruntOptions *opt
8990
sess.Handlers.Build.PushFrontNamed(addUserAgent)
9091

9192
// Merge the config based IAMRole options into the original one, as the config has higher precedence than CLI.
92-
iamRoleOptions := terragruntOptions.IAMRoleOptions
93+
iamRoleOptions := opts.IAMRoleOptions
9394
if config.RoleArn != "" {
9495
iamRoleOptions = options.MergeIAMRoleOptions(
9596
iamRoleOptions,
@@ -113,7 +114,7 @@ func CreateAwsSessionFromConfig(config *AwsSessionConfig, terragruntOptions *opt
113114

114115
if iamRoleOptions.RoleARN != "" {
115116
sess.Config.Credentials = getSTSCredentialsFromIAMRoleOptions(sess, iamRoleOptions, credentialOptFn)
116-
} else if creds := getCredentialsFromEnvs(terragruntOptions); creds != nil {
117+
} else if creds := getCredentialsFromEnvs(opts); creds != nil {
117118
sess.Config.Credentials = creds
118119
}
119120

@@ -188,14 +189,23 @@ func getCredentialsFromEnvs(opts *options.TerragruntOptions) *credentials.Creden
188189
return credentials.NewStaticCredentials(accessKeyID, secretAccessKey, sessionToken)
189190
}
190191

192+
func CreateS3Client(config *AwsSessionConfig, opts *options.TerragruntOptions) (*s3.S3, error) {
193+
session, err := CreateAwsSession(config, opts)
194+
if err != nil {
195+
return nil, errors.New(err)
196+
}
197+
198+
return s3.New(session), nil
199+
}
200+
191201
// CreateAwsSession returns an AWS session object. The session is configured by either:
192202
// - The provided AwsSessionConfig struct, which specifies region (required), profile name (optional), and IAM role to
193203
// assume (optional).
194204
// - The provided TerragruntOptions struct, which specifies any IAM role to assume (optional).
195205
//
196206
// Note that if the AwsSessionConfig object is null, this will return default session credentials using the default
197207
// credentials chain of the AWS SDK.
198-
func CreateAwsSession(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) (*session.Session, error) {
208+
func CreateAwsSession(config *AwsSessionConfig, opts *options.TerragruntOptions) (*session.Session, error) {
199209
var (
200210
sess *session.Session
201211
err error
@@ -211,19 +221,19 @@ func CreateAwsSession(config *AwsSessionConfig, terragruntOptions *options.Terra
211221

212222
sess.Handlers.Build.PushFrontNamed(addUserAgent)
213223

214-
if terragruntOptions.IAMRoleOptions.RoleARN != "" {
215-
if terragruntOptions.IAMRoleOptions.WebIdentityToken != "" {
216-
terragruntOptions.Logger.Debugf("Assuming role %s using WebIdentity token", terragruntOptions.IAMRoleOptions.RoleARN)
217-
sess.Config.Credentials = getWebIdentityCredentialsFromIAMRoleOptions(sess, terragruntOptions.IAMRoleOptions)
224+
if opts.IAMRoleOptions.RoleARN != "" {
225+
if opts.IAMRoleOptions.WebIdentityToken != "" {
226+
opts.Logger.Debugf("Assuming role %s using WebIdentity token", opts.IAMRoleOptions.RoleARN)
227+
sess.Config.Credentials = getWebIdentityCredentialsFromIAMRoleOptions(sess, opts.IAMRoleOptions)
218228
} else {
219-
terragruntOptions.Logger.Debugf("Assuming role %s", terragruntOptions.IAMRoleOptions.RoleARN)
220-
sess.Config.Credentials = getSTSCredentialsFromIAMRoleOptions(sess, terragruntOptions.IAMRoleOptions)
229+
opts.Logger.Debugf("Assuming role %s", opts.IAMRoleOptions.RoleARN)
230+
sess.Config.Credentials = getSTSCredentialsFromIAMRoleOptions(sess, opts.IAMRoleOptions)
221231
}
222-
} else if creds := getCredentialsFromEnvs(terragruntOptions); creds != nil {
232+
} else if creds := getCredentialsFromEnvs(opts); creds != nil {
223233
sess.Config.Credentials = creds
224234
}
225235
} else {
226-
sess, err = CreateAwsSessionFromConfig(config, terragruntOptions)
236+
sess, err = CreateAwsSessionFromConfig(config, opts)
227237
if err != nil {
228238
return nil, errors.New(err)
229239
}
@@ -323,12 +333,7 @@ func AssumeIamRole(iamRoleOpts options.IAMRoleOptions) (*sts.Credentials, error)
323333
}
324334

325335
// GetAWSCallerIdentity returns the AWS caller identity associated with the current set of credentials
326-
func GetAWSCallerIdentity(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) (sts.GetCallerIdentityOutput, error) {
327-
sess, err := CreateAwsSession(config, terragruntOptions)
328-
if err != nil {
329-
return sts.GetCallerIdentityOutput{}, errors.New(err)
330-
}
331-
336+
func GetAWSCallerIdentity(sess *session.Session) (sts.GetCallerIdentityOutput, error) {
332337
identity, err := sts.New(sess).GetCallerIdentity(nil)
333338
if err != nil {
334339
return sts.GetCallerIdentityOutput{}, errors.New(err)
@@ -338,15 +343,15 @@ func GetAWSCallerIdentity(config *AwsSessionConfig, terragruntOptions *options.T
338343
}
339344

340345
// ValidateAwsSession - Validate if current AWS session is valid
341-
func ValidateAwsSession(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) error {
346+
func ValidateAwsSession(sess *session.Session) error {
342347
// read the caller identity to check if the credentials are valid
343-
_, err := GetAWSCallerIdentity(config, terragruntOptions)
348+
_, err := GetAWSCallerIdentity(sess)
344349
return err
345350
}
346351

347352
// GetAWSPartition gets the AWS Partition of the current session configuration
348-
func GetAWSPartition(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) (string, error) {
349-
identity, err := GetAWSCallerIdentity(config, terragruntOptions)
353+
func GetAWSPartition(sess *session.Session) (string, error) {
354+
identity, err := GetAWSCallerIdentity(sess)
350355
if err != nil {
351356
return "", errors.New(err)
352357
}
@@ -361,12 +366,7 @@ func GetAWSPartition(config *AwsSessionConfig, terragruntOptions *options.Terrag
361366

362367
// GetAWSAccountAlias gets the AWS account Alias of the current session configuration,
363368
// if there is no alias an empty string is return.
364-
func GetAWSAccountAlias(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) (string, error) {
365-
sess, err := CreateAwsSession(config, terragruntOptions)
366-
if err != nil {
367-
return "", errors.New(err)
368-
}
369-
369+
func GetAWSAccountAlias(sess *session.Session) (string, error) {
370370
aliases, err := iam.New(sess).ListAccountAliases(nil)
371371
if err != nil {
372372
return "", errors.New(err)
@@ -385,8 +385,8 @@ func GetAWSAccountAlias(config *AwsSessionConfig, terragruntOptions *options.Ter
385385
}
386386

387387
// GetAWSAccountID gets the AWS account ID of the current session configuration.
388-
func GetAWSAccountID(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) (string, error) {
389-
identity, err := GetAWSCallerIdentity(config, terragruntOptions)
388+
func GetAWSAccountID(sess *session.Session) (string, error) {
389+
identity, err := GetAWSCallerIdentity(sess)
390390
if err != nil {
391391
return "", errors.New(err)
392392
}
@@ -395,8 +395,8 @@ func GetAWSAccountID(config *AwsSessionConfig, terragruntOptions *options.Terrag
395395
}
396396

397397
// GetAWSIdentityArn gets the ARN of the AWS identity associated with the current set of credentials.
398-
func GetAWSIdentityArn(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) (string, error) {
399-
identity, err := GetAWSCallerIdentity(config, terragruntOptions)
398+
func GetAWSIdentityArn(sess *session.Session) (string, error) {
399+
identity, err := GetAWSCallerIdentity(sess)
400400
if err != nil {
401401
return "", errors.New(err)
402402
}
@@ -405,11 +405,23 @@ func GetAWSIdentityArn(config *AwsSessionConfig, terragruntOptions *options.Terr
405405
}
406406

407407
// GetAWSUserID gets the AWS user ID of the current session configuration.
408-
func GetAWSUserID(config *AwsSessionConfig, terragruntOptions *options.TerragruntOptions) (string, error) {
409-
identity, err := GetAWSCallerIdentity(config, terragruntOptions)
408+
func GetAWSUserID(sess *session.Session) (string, error) {
409+
identity, err := GetAWSCallerIdentity(sess)
410410
if err != nil {
411411
return "", errors.New(err)
412412
}
413413

414414
return *identity.UserId, nil
415415
}
416+
417+
func ValidatePublicAccessBlock(output *s3.GetPublicAccessBlockOutput) (bool, error) {
418+
if output.PublicAccessBlockConfiguration == nil {
419+
return false, nil
420+
}
421+
422+
if !aws.BoolValue(output.PublicAccessBlockConfiguration.BlockPublicAcls) {
423+
return false, nil
424+
}
425+
426+
return true, nil
427+
}

awshelper/config_test.go

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ package awshelper_test
55
import (
66
"testing"
77

8+
"github.com/aws/aws-sdk-go/aws"
89
"github.com/aws/aws-sdk-go/aws/request"
10+
"github.com/aws/aws-sdk-go/service/s3"
911
"github.com/aws/aws-sdk-go/service/sts"
1012
"github.com/gruntwork-io/terragrunt/awshelper"
1113
"github.com/gruntwork-io/terragrunt/options"
@@ -36,9 +38,59 @@ func TestAwsIsAddedInUserAgent(t *testing.T) {
3638
func TestAwsSessionValidationFail(t *testing.T) {
3739
t.Parallel()
3840

39-
err := awshelper.ValidateAwsSession(&awshelper.AwsSessionConfig{
41+
sess, err := awshelper.CreateAwsSession(&awshelper.AwsSessionConfig{
4042
Region: "not-existing-region",
4143
CredsFilename: "/tmp/not-existing-file",
4244
}, options.NewTerragruntOptions())
45+
require.NoError(t, err)
46+
47+
err = awshelper.ValidateAwsSession(sess)
4348
assert.Error(t, err)
4449
}
50+
51+
// Test to validate cases when is not possible to read all S3 configurations
52+
// https://github.com/gruntwork-io/terragrunt/issues/2109
53+
func TestAwsNegativePublicAccessResponse(t *testing.T) {
54+
t.Parallel()
55+
testCases := []struct {
56+
name string
57+
response *s3.GetPublicAccessBlockOutput
58+
}{
59+
{
60+
name: "nil-response",
61+
response: &s3.GetPublicAccessBlockOutput{
62+
PublicAccessBlockConfiguration: nil,
63+
},
64+
},
65+
{
66+
name: "legacy-bucket",
67+
response: &s3.GetPublicAccessBlockOutput{
68+
PublicAccessBlockConfiguration: &s3.PublicAccessBlockConfiguration{
69+
BlockPublicAcls: nil,
70+
BlockPublicPolicy: nil,
71+
IgnorePublicAcls: nil,
72+
RestrictPublicBuckets: nil,
73+
},
74+
},
75+
},
76+
{
77+
name: "false-response",
78+
response: &s3.GetPublicAccessBlockOutput{
79+
PublicAccessBlockConfiguration: &s3.PublicAccessBlockConfiguration{
80+
BlockPublicAcls: aws.Bool(false),
81+
BlockPublicPolicy: aws.Bool(false),
82+
IgnorePublicAcls: aws.Bool(false),
83+
RestrictPublicBuckets: aws.Bool(false),
84+
},
85+
},
86+
},
87+
}
88+
for _, tc := range testCases {
89+
t.Run(tc.name, func(t *testing.T) {
90+
t.Parallel()
91+
response, err := awshelper.ValidatePublicAccessBlock(tc.response)
92+
require.NoError(t, err)
93+
assert.False(t, response)
94+
})
95+
}
96+
}

0 commit comments

Comments
 (0)