Skip to content

Commit d5733e5

Browse files
feat(cloudlogs): add cross account support (#150)
1 parent 1b82efe commit d5733e5

File tree

1 file changed

+253
-16
lines changed

1 file changed

+253
-16
lines changed

modules/log_ingestion.s3.cft.yaml

Lines changed: 253 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
AWSTemplateFormatVersion: "2010-09-09"
22
Description: >
3-
CloudFormation organizational template for provisioning the necessary resources
4-
for the `cloud-logs` component and the read-only role required to interact with
5-
the target organizational environment.
3+
CloudFormation template for provisioning the necessary resources
4+
for the `cloud-logs` component, allowing Sysdig to access CloudTrail logs in S3 buckets.
65
76
Metadata:
87
AWS::CloudFormation::Interface:
@@ -14,9 +13,15 @@ Metadata:
1413
- ExternalID
1514
- TrustedIdentity
1615
- BucketARN
16+
- KMSKeyARN
17+
- KMSAccountId
18+
- BucketAccountId
19+
- TopicAccountId
20+
- OrganizationalUnitIds
1721
- CreateTopic
1822
- TopicARN
1923
- Endpoint
24+
- TopicRegion
2025

2126
ParameterLabels:
2227
NameSuffix:
@@ -27,12 +32,24 @@ Metadata:
2732
default: Trusted Identity
2833
BucketARN:
2934
default: Bucket ARN
35+
KMSKeyARN:
36+
default: KMS Key ARN
37+
KMSAccountId:
38+
default: KMS Account ID
39+
BucketAccountId:
40+
default: Bucket Account ID
41+
TopicAccountId:
42+
default: SNS Topic Account ID
43+
OrganizationalUnitIds:
44+
default: Organizational Unit IDs
3045
CreateTopic:
3146
default: Create SNS Topic
3247
TopicARN:
3348
default: SNS Topic ARN
3449
Endpoint:
3550
default: Sysdig Secure endpoint
51+
TopicRegion:
52+
default: The AWS region where the SNS topic is located
3653

3754
Parameters:
3855
NameSuffix:
@@ -50,6 +67,28 @@ Parameters:
5067
BucketARN:
5168
Type: String
5269
Description: The ARN of your S3 bucket associated with your CloudTrail trail logs.
70+
AllowedPattern: 'arn:(aws|aws-us-gov):s3:::.*'
71+
KMSKeyARN:
72+
Type: String
73+
Description: The ARN of the KMS key used to encrypt the S3 bucket.
74+
Default: ""
75+
KMSAccountId:
76+
Type: String
77+
Description: The AWS Account ID that owns the KMS key.
78+
AllowedPattern: '^[0-9]{12}$'
79+
BucketAccountId:
80+
Type: String
81+
Description: The AWS Account ID that owns the S3 bucket, if different from the current account.
82+
AllowedPattern: '^[0-9]{12}$'
83+
TopicAccountId:
84+
Type: String
85+
Description: The AWS Account ID that owns the SNS topic.
86+
AllowedPattern: '^[0-9]{12}$'
87+
OrganizationalUnitIds:
88+
Type: String
89+
Description: Comma-separated list of AWS Organizations organizational unit (OU) IDs for cross-account deployments.
90+
Default: "r-root"
91+
AllowedPattern: '^(ou-[a-z0-9]{4,32}-[a-z0-9]{8,32}|r-[a-z0-9]{4,32})(,\s*(ou-[a-z0-9]{4,32}-[a-z0-9]{8,32}|r-[a-z0-9]{4,32}))*$'
5392
CreateTopic:
5493
Type: String
5594
AllowedValues:
@@ -63,12 +102,37 @@ Parameters:
63102
Endpoint:
64103
Type: String
65104
Description: Sysdig Secure endpoint to receive CloudTrail notifications.
105+
TopicRegion:
106+
Type: String
107+
Description: The AWS region where the SNS topic is located
108+
AllowedPattern: '^[a-zA-Z0-9-]{1,128}$'
109+
110+
Conditions:
111+
CreateSNSTopic: !Equals [ !Ref CreateTopic, "true" ]
112+
HasKMSKey: !Not [ !Equals [ !Ref KMSKeyARN, "" ] ]
113+
DeployStackSet: !Or [
114+
!Not [ !Equals [ !Ref BucketAccountId, !Ref "AWS::AccountId" ] ],
115+
!Not [ !Equals [ !Ref TopicAccountId, !Ref "AWS::AccountId" ] ]
116+
]
117+
118+
DeployRole: !And [
119+
!Equals [ !Ref BucketAccountId, !Ref "AWS::AccountId" ] ,
120+
!Equals [ DeployStackSet, "false" ]
121+
]
122+
123+
NeedKMSPolicy: !And [
124+
!Not [ !Equals [ !Ref KMSKeyARN, "" ] ],
125+
!Not [ !Equals [ !Ref KMSAccountId, !Ref BucketAccountId ] ]
126+
]
127+
IsTopicAccount: !Equals [ !Ref TopicAccountId, !Ref "AWS::AccountId" ]
66128

67129
Resources:
130+
# Role and resources for same-account deployments
68131
CloudLogsRole:
69132
Type: "AWS::IAM::Role"
133+
Condition: DeployRole
70134
Properties:
71-
RoleName: !Sub sysdig-secure-cloudlogs-${NameSuffix}
135+
RoleName: !Sub sysdig-secure-cloudlogs-${NameSuffix}
72136
AssumeRolePolicyDocument:
73137
Version: "2012-10-17"
74138
Statement:
@@ -85,20 +149,29 @@ Resources:
85149
PolicyDocument:
86150
Version: "2012-10-17"
87151
Statement:
88-
- Sid: "CloudlogsS3AccessGet"
152+
- Sid: "CloudlogsS3Access"
89153
Effect: "Allow"
90154
Action:
91155
- "s3:Get*"
92-
Resource:
93-
- !Sub '${BucketARN}'
94-
- !Sub '${BucketARN}/*'
95-
- Sid: "CloudlogsS3AccessList"
96-
Effect: "Allow"
97-
Action:
98156
- "s3:List*"
99157
Resource:
100158
- !Sub '${BucketARN}'
101159
- !Sub '${BucketARN}/*'
160+
- !If
161+
- HasKMSKey
162+
- Sid: "CloudlogsKMSDecrypt"
163+
Effect: "Allow"
164+
Action:
165+
- "kms:Decrypt"
166+
Resource: !Ref KMSKeyARN
167+
- !Ref "AWS::NoValue"
168+
Tags:
169+
- Key: "Name"
170+
Value: "Sysdig Secure CloudTrail Logs Access Role"
171+
- Key: "Purpose"
172+
Value: "Allow Sysdig to access S3 bucket for CloudTrail logs"
173+
- Key: "product"
174+
Value: "sysdig-secure-for-cloud"
102175

103176
CloudTrailNotificationsTopic:
104177
Condition: CreateSNSTopic
@@ -107,6 +180,7 @@ Resources:
107180
TopicName: !Select [ 5, !Split [ ":", !Ref TopicARN ] ]
108181

109182
CloudTrailNotificationsSubscription:
183+
Condition: IsTopicAccount
110184
Type: "AWS::SNS::Subscription"
111185
Properties:
112186
TopicArn: !If [ CreateSNSTopic, !Ref CloudTrailNotificationsTopic, !Ref TopicARN ]
@@ -129,10 +203,173 @@ Resources:
129203
Action: "SNS:Publish"
130204
Resource: !Ref CloudTrailNotificationsTopic
131205

132-
Conditions:
133-
CreateSNSTopic: !Equals [ !Ref CreateTopic, "true" ]
206+
# StackSet for cross-account bucket access
207+
BucketAccessStackSet:
208+
Type: AWS::CloudFormation::StackSet
209+
Condition: DeployStackSet
210+
Properties:
211+
StackSetName: !Sub sysdig-secure-cloudlogs-bucket-access-${NameSuffix}
212+
Description: StackSet to configure S3 bucket and KMS permissions for Sysdig Cloud Logs integration
213+
PermissionModel: SERVICE_MANAGED
214+
AutoDeployment:
215+
Enabled: false
216+
ManagedExecution:
217+
Active: true
218+
Capabilities:
219+
- "CAPABILITY_NAMED_IAM"
220+
OperationPreferences:
221+
MaxConcurrentPercentage: 100
222+
FailureTolerancePercentage: 90
223+
ConcurrencyMode: SOFT_FAILURE_TOLERANCE
224+
Parameters:
225+
- ParameterKey: NameSuffix
226+
ParameterValue: !Ref NameSuffix
227+
- ParameterKey: RoleName
228+
ParameterValue: !Sub sysdig-secure-cloudlogs-${NameSuffix}
229+
- ParameterKey: TrustedIdentity
230+
ParameterValue: !Ref TrustedIdentity
231+
- ParameterKey: ExternalID
232+
ParameterValue: !Ref ExternalID
233+
- ParameterKey: BucketARN
234+
ParameterValue: !Ref BucketARN
235+
- ParameterKey: KMSKeyARN
236+
ParameterValue: !Ref KMSKeyARN
237+
- ParameterKey: BucketAccountId
238+
ParameterValue: !Ref BucketAccountId
239+
- ParameterKey: TopicARN
240+
ParameterValue: !Ref TopicARN
241+
- ParameterKey: TopicAccountId
242+
ParameterValue: !Ref TopicAccountId
243+
- ParameterKey: Endpoint
244+
ParameterValue: !Ref Endpoint
245+
- ParameterKey: TopicRegion
246+
ParameterValue: !Ref TopicRegion
247+
StackInstancesGroup:
248+
- DeploymentTargets:
249+
OrganizationalUnitIds: !Split [",", !Ref OrganizationalUnitIds]
250+
Accounts: [!Ref BucketAccountId]
251+
AccountFilterType: INTERSECTION
252+
Regions: [!Ref "AWS::Region"]
253+
- DeploymentTargets:
254+
OrganizationalUnitIds: !Split [",", !Ref OrganizationalUnitIds]
255+
Accounts: [!Ref TopicAccountId]
256+
AccountFilterType: INTERSECTION
257+
Regions: [!Ref TopicRegion]
258+
TemplateBody: |
259+
AWSTemplateFormatVersion: "2010-09-09"
260+
Description: IAM Role for S3 bucket and KMS access for Sysdig Cloud Logs integration
261+
Parameters:
262+
NameSuffix:
263+
Type: String
264+
Description: Suffix to append to the resource name identifiers
265+
RoleName:
266+
Type: String
267+
Description: Name of the role to be created in the bucket account
268+
TrustedIdentity:
269+
Type: String
270+
Description: ARN of the Sysdig service that needs to assume the role
271+
ExternalID:
272+
Type: String
273+
Description: External ID for secure role assumption by Sysdig
274+
BucketARN:
275+
Type: String
276+
Description: ARN of the S3 bucket containing CloudTrail logs
277+
KMSKeyARN:
278+
Type: String
279+
Description: ARN of the KMS key used for encryption
280+
Default: ""
281+
BucketAccountId:
282+
Type: String
283+
Description: AWS Account ID that owns the S3 bucket
284+
TopicARN:
285+
Type: String
286+
Description: ARN of the SNS topic
287+
TopicAccountId:
288+
Type: String
289+
Description: AWS Account ID that owns the SNS topic
290+
Endpoint:
291+
Type: String
292+
Description: Sysdig Secure endpoint to receive CloudTrail notifications
293+
TopicRegion:
294+
Type: String
295+
Description: The AWS region where the SNS topic is located
296+
Conditions:
297+
IsBucketAccount: !Equals [ !Ref BucketAccountId, !Ref "AWS::AccountId" ]
298+
IsTopicAccount: !Equals [ !Ref TopicAccountId, !Ref "AWS::AccountId" ]
299+
HasKMSKey: !Not [ !Equals [ !Ref KMSKeyARN, "" ] ]
300+
Resources:
301+
S3AccessRole:
302+
Type: AWS::IAM::Role
303+
Condition: IsBucketAccount
304+
Properties:
305+
RoleName: !Ref RoleName
306+
AssumeRolePolicyDocument:
307+
Version: "2012-10-17"
308+
Statement:
309+
- Effect: "Allow"
310+
Principal:
311+
AWS: !Ref TrustedIdentity
312+
Action: "sts:AssumeRole"
313+
Condition:
314+
StringEquals:
315+
"sts:ExternalId": !Ref ExternalID
316+
Policies:
317+
- PolicyName: !Sub "sysdig-secure-cloudlogs-policy-${AWS::AccountId}-${NameSuffix}"
318+
PolicyDocument:
319+
Version: "2012-10-17"
320+
Statement:
321+
- Sid: "S3BucketListAccess"
322+
Effect: "Allow"
323+
Action:
324+
- "s3:ListBucket"
325+
- "s3:GetBucketLocation"
326+
Resource:
327+
- !Ref BucketARN
328+
- Sid: "S3ObjectAccess"
329+
Effect: "Allow"
330+
Action:
331+
- "s3:GetObject"
332+
Resource:
333+
- !Sub "${BucketARN}/*"
334+
- !If
335+
- HasKMSKey
336+
- Sid: "KMSDecryptAccess"
337+
Effect: "Allow"
338+
Action: "kms:Decrypt"
339+
Resource: !Ref KMSKeyARN
340+
- !Ref "AWS::NoValue"
341+
Tags:
342+
- Key: "Name"
343+
Value: "Sysdig Secure CloudTrail Logs Access Role"
344+
- Key: "Purpose"
345+
Value: "Allow Sysdig to access S3 bucket for CloudTrail logs"
346+
- Key: "product"
347+
Value: "sysdig-secure-for-cloud"
134348
349+
CloudTrailSNSSubscription:
350+
Type: AWS::SNS::Subscription
351+
Condition: IsTopicAccount
352+
Properties:
353+
TopicArn: !Ref TopicARN
354+
Protocol: "https"
355+
Endpoint: !Ref Endpoint
135356
Outputs:
136-
TopicARN:
137-
Description: "The ARN of the SNS Topic created for CloudTrail notifications."
138-
Value: !If [ CreateSNSTopic, !Ref CloudTrailNotificationsTopic, !Ref TopicARN ]
357+
KMSPolicyInstructions:
358+
Description: "Instructions for updating KMS key policy when KMS encryption is enabled"
359+
Condition: NeedKMSPolicy
360+
Value: !Sub |
361+
IMPORTANT: MANUAL ACTION REQUIRED
362+
363+
Please add the following statement to your KMS key policy to allow Sysdig to decrypt logs.
364+
This is necessary when KMS encryption is enabled for your S3 bucket and the KMS key is in a different account.
365+
Without this policy addition, Sysdig may not be able to read your encrypted logs.
366+
367+
{
368+
"Sid": "Sysdig-Decrypt",
369+
"Effect": "Allow",
370+
"Principal": {
371+
"AWS": "sysdig-secure-cloudlogs-${NameSuffix}"
372+
},
373+
"Action": "kms:Decrypt",
374+
"Resource": "*"
375+
}

0 commit comments

Comments
 (0)