forked from mozilla/guardduty-multi-account-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
/
guardduty-member-account-role.yml
132 lines (130 loc) · 5.58 KB
/
guardduty-member-account-role.yml
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
AWSTemplateFormatVersion: 2010-09-09
Description: Mozilla Multi Account Manager member account roles to allow guardDuty master to accept invitations.
Metadata:
Source: https://github.com/mozilla/guardduty-multi-account-manager/tree/master/cloudformation
Mappings:
Variables:
MasterAccount:
# Make sure to set this Principal variable to the account running your
# GuardDuty master. Leaving it as the default will cause stack failure
# as this example value is an invalid reserved principal
Principal: arn:aws:iam::123456789012:root
SNSTopicForPublishingIAMRoleArn:
# Make sure to set this Account variable to the account ID running your CloudFormation Cross Account Output infrastructure
Account: 123456789012
Topic: cloudformation-stack-emissions
TheRegionYouAreDeployingIn:
# Create a record for each region in which CloudFormation Cross Account Output infrastructure is deployed
us-east-1:
WhatIsThisMapping: This constrains the regions in which you can deploy this template to only the regions listed in this mapping. This, for example, prevents deloying in ap-south-1
IsNotSupportedPleaseUseADifferentRegion: True
us-west-2:
WhatIsThisMapping: ''
IsNotSupportedPleaseUseADifferentRegion: True
Conditions:
RunningInAllowedRegion: !Equals [ !FindInMap [ TheRegionYouAreDeployingIn, !Ref 'AWS::Region', IsNotSupportedPleaseUseADifferentRegion ] , True ]
Resources:
GuardDutyInvitationAcceptorIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: !FindInMap [ Variables, MasterAccount, Principal ]
Action: sts:AssumeRole
Policies:
- PolicyName: AllowAcceptingGuardDutyInvitation
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- guardduty:ListDetectors
- guardduty:CreateDetector
- guardduty:DeleteDetector
- guardduty:AcceptInvitation
- guardduty:DeleteInvitations
- guardduty:GetDetector
- guardduty:GetInvitationsCount
- guardduty:GetMasterAccount
- guardduty:UpdateDetector
- guardduty:ListInvitations
- guardduty:DisassociateFromMasterAccount
Resource: '*'
Path: '/multi-account-guard-duty/'
PublishIAMRoleArnsToSNS:
Type: Custom::PublishIAMRoleArnsToSNS
Version: '1.0'
Properties:
ServiceToken: !Join [ ':', [ 'arn:aws:sns', !Ref 'AWS::Region', !FindInMap [ Variables, SNSTopicForPublishingIAMRoleArn, Account ], !FindInMap [ Variables, SNSTopicForPublishingIAMRoleArn, Topic ] ] ]
category: GuardDuty Multi Account Member Role
GuardDutyMemberAccountIAMRoleArn: !GetAtt GuardDutyInvitationAcceptorIAMRole.Arn
GuardDutyMemberAccountIAMRoleName: !Ref GuardDutyInvitationAcceptorIAMRole
CloudFormationLambdaIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: AllowLambdaLoggingAndCreateServiceLinkedRole
PolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Action:
- logs:*
- iam:CreateServiceLinkedRole
Resource: '*'
CreateGuardDutyServiceLinkedRoleFunction:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
import cfnresponse
import boto3, secrets, string
def handler(event, context):
client = boto3.client('iam')
created = False
try:
if event['RequestType'] in ['Create', 'Update']:
client.create_service_linked_role(
AWSServiceName='guardduty.amazonaws.com',
Description='A service-linked role required for Amazon '
'GuardDuty to access your resources.'
)
created = True
elif event['RequestType'] == 'Delete':
pass # Leave the role in place when stack is deleted
except client.exceptions.InvalidInputException:
pass # Role already exists
physical_id = ''.join(
secrets.choice(string.ascii_uppercase + string.digits) for _ in
range(13))
cfnresponse.send(
event, context, cfnresponse.SUCCESS, {'RoleCreated': created},
"CreateGuardDutyServiceLinkedRole-%s" % physical_id)
Handler: index.handler
Runtime: python3.6
Role: !GetAtt CloudFormationLambdaIAMRole.Arn
Timeout: 20
CreateGuardDutyServiceLinkedRole:
Type: AWS::CloudFormation::CustomResource
Properties:
ServiceToken: !GetAtt CreateGuardDutyServiceLinkedRoleFunction.Arn
Outputs:
GuardDutyInvitationAcceptorRoleName:
Description: IAM Role name of the Guard Duty Invitation Acceptor
Value: !Ref GuardDutyInvitationAcceptorIAMRole
GuardDutyInvitationAcceptorRoleArn:
Description: ARN of the Guard Duty Invitation Acceptor IAM Role
Value: !GetAtt GuardDutyInvitationAcceptorIAMRole.Arn