-
Notifications
You must be signed in to change notification settings - Fork 66
/
aws_roles.go
136 lines (122 loc) · 3.25 KB
/
aws_roles.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package cloudaccess
import (
"encoding/json"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/iam"
)
type AssumeRolePolicyDocument struct {
Version string `json:"Version"`
Statement []Statement `json:"Statement"`
}
type Statement struct {
Effect string `json:"Effect"`
Principal Principal `json:"Principal"`
Action string `json:"Action"`
Condition Condition `json:"Condition,omitempty"`
}
type Principal struct {
AWS string `json:"AWS,omitempty"`
Service string `json:"Service,omitempty"`
}
type Condition struct {
StringEquals StringEquals `json:"StringEquals,omitempty"`
}
type StringEquals struct {
StsExternalId string `json:"sts:ExternalId,omitempty"`
}
func defaultPolicy() AssumeRolePolicyDocument {
return AssumeRolePolicyDocument{
Version: "2012-10-17",
Statement: []Statement{
{
Effect: "Allow",
Principal: Principal{
Service: "ec2.amazonaws.com",
},
Action: "sts:AssumeRole",
},
},
}
}
func EC2RolePolicyString() (string, error) {
policy := defaultPolicy()
byteStr, err := json.Marshal(policy)
if err != nil {
return "", err
}
return string(byteStr), nil
}
func PolicyWithAtlasArn(atlasAWSAccountArn, atlasAssumedRoleExternalId string) (string, error) {
policy := defaultPolicy()
policy.Statement = append(policy.Statement, Statement{
Effect: "Allow",
Principal: Principal{
AWS: atlasAWSAccountArn,
},
Action: "sts:AssumeRole",
Condition: Condition{
StringEquals: StringEquals{
StsExternalId: atlasAssumedRoleExternalId,
},
},
})
byteStr, err := json.Marshal(policy)
if err != nil {
return "", err
}
return string(byteStr), nil
}
func CreateAWSIAMRole(roleName string) (string, error) {
policy, err := EC2RolePolicyString()
if err != nil {
return "", err
}
IAMClient := iam.New(session.Must(session.NewSession()))
roleInput := iam.CreateRoleInput{}
roleInput.SetRoleName(roleName)
roleInput.SetAssumeRolePolicyDocument(policy)
//roleInput.SetTags([]*iam.Tag{
// {
// Key: aws.String(config.TagForTestKey),
// Value: aws.String(config.TagForTestValue),
// },
//})
role, err := IAMClient.CreateRole(&roleInput)
if err != nil {
return "", err
}
return *role.Role.Arn, nil
}
func AddAtlasStatementToAWSIAMRole(atlasAWSAccountArn, atlasAssumedRoleExternalId, roleName string) error {
updatedPolicy, err := PolicyWithAtlasArn(atlasAWSAccountArn, atlasAssumedRoleExternalId)
if err != nil {
return err
}
IAMClient := iam.New(session.Must(session.NewSession()))
roleUpdate := iam.UpdateAssumeRolePolicyInput{}
roleUpdate.SetPolicyDocument(updatedPolicy)
roleUpdate.SetRoleName(roleName)
req, _ := IAMClient.UpdateAssumeRolePolicyRequest(&roleUpdate)
err = req.Send()
if err != nil {
return err
}
return nil
}
func NameFromArn(arn string) string {
// It's a little hacky, but it works. AWS doesn't have an API for finding role by arn
// arn format is arn:aws:iam::<account_id>:role/<role_name>
return arn[strings.LastIndex(arn, "/")+1:]
}
func DeleteAWSIAMRoleByArn(arn string) error {
IAMClient := iam.New(session.Must(session.NewSession()))
_, err := IAMClient.DeleteRole(&iam.DeleteRoleInput{
RoleName: aws.String(NameFromArn(arn)),
})
if err != nil {
return err
}
return nil
}