Skip to content

Commit 2cad960

Browse files
add cross account support
1 parent 9b96bd5 commit 2cad960

File tree

1 file changed

+267
-13
lines changed

1 file changed

+267
-13
lines changed

modules/log_ingestion.s3.cft.yaml

Lines changed: 267 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
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.
5+
Supports single-account, organizational same-account, and organizational cross-account deployments.
66
77
Metadata:
88
AWS::CloudFormation::Interface:
@@ -14,9 +14,13 @@ Metadata:
1414
- ExternalID
1515
- TrustedIdentity
1616
- BucketARN
17+
- KMSKeyARN
18+
- BucketAccountId
19+
- OrganizationalUnitIds
1720
- CreateTopic
1821
- TopicARN
1922
- Endpoint
23+
- Partition
2024

2125
ParameterLabels:
2226
NameSuffix:
@@ -27,12 +31,20 @@ Metadata:
2731
default: Trusted Identity
2832
BucketARN:
2933
default: Bucket ARN
34+
KMSKeyARN:
35+
default: KMS Key ARN
36+
BucketAccountId:
37+
default: Bucket Account ID
38+
OrganizationalUnitIds:
39+
default: Organizational Unit IDs
3040
CreateTopic:
3141
default: Create SNS Topic
3242
TopicARN:
3343
default: SNS Topic ARN
3444
Endpoint:
3545
default: Sysdig Secure endpoint
46+
Partition:
47+
default: AWS Partition
3648

3749
Parameters:
3850
NameSuffix:
@@ -50,6 +62,19 @@ Parameters:
5062
BucketARN:
5163
Type: String
5264
Description: The ARN of your S3 bucket associated with your CloudTrail trail logs.
65+
AllowedPattern: 'arn:(aws|aws-us-gov):s3:::.*'
66+
KMSKeyARN:
67+
Type: String
68+
Description: The ARN of the KMS key used to encrypt the S3 bucket.
69+
Default: ""
70+
BucketAccountId:
71+
Type: String
72+
Description: The AWS Account ID that owns the S3 bucket, if different from the current account.
73+
Default: ""
74+
OrganizationalUnitIds:
75+
Type: String
76+
Description: Comma-separated list of AWS Organizations organizational unit (OU) IDs for cross-account deployments.
77+
Default: "root"
5378
CreateTopic:
5479
Type: String
5580
AllowedValues:
@@ -63,12 +88,32 @@ Parameters:
6388
Endpoint:
6489
Type: String
6590
Description: Sysdig Secure endpoint to receive CloudTrail notifications.
91+
Partition:
92+
Type: String
93+
Description: AWS Partition of your account or organization to create resources in
94+
Default: 'aws'
95+
96+
Conditions:
97+
CreateSNSTopic: !Equals [ !Ref CreateTopic, "true" ]
98+
HasKMSKey: !Not [ !Equals [ !Ref KMSKeyARN, "" ] ]
99+
# Matches Terraform's: is_cross_account = var.bucket_account_id != null && var.bucket_account_id != data.aws_caller_identity.current.account_id
100+
IsCrossAccount: !And [
101+
!Not [ !Equals [ !Ref BucketAccountId, "" ] ],
102+
!Not [ !Equals [ !Ref BucketAccountId, !Ref "AWS::AccountId" ] ]
103+
]
104+
NotIsCrossAccount: !Not [IsCrossAccount]
105+
HasKMSAndNotCrossAccount: !And [HasKMSKey, NotIsCrossAccount]
106+
HasKMSAndIsCrossAccount: !And [HasKMSKey, IsCrossAccount]
107+
IsTopicAccount: !Equals [ !Select [4, !Split [":", !Ref TopicARN]], !Ref "AWS::AccountId" ]
108+
IsBucketAccount: !Equals [ !Ref BucketAccountId, !Ref "AWS::AccountId" ]
66109

67110
Resources:
111+
# Role and resources for same-account deployments
68112
CloudLogsRole:
69113
Type: "AWS::IAM::Role"
114+
Condition: NotIsCrossAccount
70115
Properties:
71-
RoleName: !Sub sysdig-secure-cloudlogs-${NameSuffix}
116+
RoleName: !Sub sysdig-secure-cloudlogs-${NameSuffix}
72117
AssumeRolePolicyDocument:
73118
Version: "2012-10-17"
74119
Statement:
@@ -85,20 +130,29 @@ Resources:
85130
PolicyDocument:
86131
Version: "2012-10-17"
87132
Statement:
88-
- Sid: "CloudlogsS3AccessGet"
133+
- Sid: "CloudlogsS3Access"
89134
Effect: "Allow"
90135
Action:
91136
- "s3:Get*"
92-
Resource:
93-
- !Sub '${BucketARN}'
94-
- !Sub '${BucketARN}/*'
95-
- Sid: "CloudlogsS3AccessList"
96-
Effect: "Allow"
97-
Action:
98137
- "s3:List*"
99138
Resource:
100139
- !Sub '${BucketARN}'
101140
- !Sub '${BucketARN}/*'
141+
- !If
142+
- HasKMSKey
143+
- Sid: "CloudlogsKMSDecrypt"
144+
Effect: "Allow"
145+
Action:
146+
- "kms:Decrypt"
147+
Resource: !Ref KMSKeyARN
148+
- !Ref "AWS::NoValue"
149+
Tags:
150+
- Key: "Name"
151+
Value: "Sysdig Secure CloudTrail Logs Access Role"
152+
- Key: "Purpose"
153+
Value: "Allow Sysdig to access S3 bucket for CloudTrail logs"
154+
- Key: "product"
155+
Value: "sysdig-secure-for-cloud"
102156

103157
CloudTrailNotificationsTopic:
104158
Condition: CreateSNSTopic
@@ -129,10 +183,210 @@ Resources:
129183
Action: "SNS:Publish"
130184
Resource: !Ref CloudTrailNotificationsTopic
131185

132-
Conditions:
133-
CreateSNSTopic: !Equals [ !Ref CreateTopic, "true" ]
186+
# StackSet for cross-account bucket access
187+
BucketAccessStackSet:
188+
Type: AWS::CloudFormation::StackSet
189+
Condition: IsCrossAccount
190+
Properties:
191+
StackSetName: !Sub sysdig-secure-cloudlogs-bucket-access-${NameSuffix}
192+
Description: IAM Role for S3 bucket and KMS access for Sysdig Cloud Logs integration
193+
PermissionModel: SERVICE_MANAGED
194+
AutoDeployment:
195+
Enabled: false
196+
ManagedExecution:
197+
Active: true
198+
Capabilities:
199+
- "CAPABILITY_NAMED_IAM"
200+
OperationPreferences:
201+
MaxConcurrentPercentage: 100
202+
FailureTolerancePercentage: 90
203+
ConcurrencyMode: SOFT_FAILURE_TOLERANCE
204+
Parameters:
205+
- ParameterKey: RoleName
206+
ParameterValue: !Sub sysdig-secure-cloudlogs-${AWS::AccountId}-${NameSuffix}
207+
- ParameterKey: TrustedIdentity
208+
ParameterValue: !Ref TrustedIdentity
209+
- ParameterKey: ExternalID
210+
ParameterValue: !Ref ExternalID
211+
- ParameterKey: BucketARN
212+
ParameterValue: !Ref BucketARN
213+
- ParameterKey: KMSKeyARN
214+
ParameterValue: !Ref KMSKeyARN
215+
- ParameterKey: BucketAccountId
216+
ParameterValue: !Ref BucketAccountId
217+
- ParameterKey: TopicARN
218+
ParameterValue: !Ref TopicARN
219+
- ParameterKey: Endpoint
220+
ParameterValue: !Ref Endpoint
221+
StackInstancesGroup:
222+
- DeploymentTargets:
223+
OrganizationalUnitIds: !Split [",", !Ref OrganizationalUnitIds]
224+
Accounts: [!Ref BucketAccountId]
225+
Regions: [!Ref "AWS::Region"]
226+
- DeploymentTargets:
227+
OrganizationalUnitIds: !Split [",", !Ref OrganizationalUnitIds]
228+
Accounts: [!Select [4, !Split [":", !Ref TopicARN]]] # Extract account ID from topic ARN
229+
Regions: [!Select [3, !Split [":", !Ref TopicARN]]] # Extract region from topic ARN
230+
TemplateBody: |
231+
AWSTemplateFormatVersion: "2010-09-09"
232+
Description: IAM Role for S3 bucket and KMS access for Sysdig Cloud Logs integration
233+
Parameters:
234+
RoleName:
235+
Type: String
236+
Description: Name of the role to be created in the bucket account
237+
TrustedIdentity:
238+
Type: String
239+
Description: ARN of the Sysdig service that needs to assume the role
240+
ExternalID:
241+
Type: String
242+
Description: External ID for secure role assumption by Sysdig
243+
BucketARN:
244+
Type: String
245+
Description: ARN of the S3 bucket containing CloudTrail logs
246+
KMSKeyARN:
247+
Type: String
248+
Description: ARN of the KMS key used for encryption
249+
Default: ""
250+
BucketAccountId:
251+
Type: String
252+
Description: AWS Account ID that owns the S3 bucket
253+
TopicARN:
254+
Type: String
255+
Description: ARN of the SNS topic
256+
Endpoint:
257+
Type: String
258+
Description: Sysdig Secure endpoint to receive CloudTrail notifications
259+
Conditions:
260+
IsBucketAccount: !Equals [ !Ref BucketAccountId, !Ref "AWS::AccountId" ]
261+
IsTopicAccount: !Equals [ !Ref TopicAccountId, !Ref "AWS::AccountId" ]
262+
HasKMSKey: !Not [ !Equals [ !Ref KMSKeyARN, "" ] ]
263+
Resources:
264+
S3AccessRole:
265+
Type: AWS::IAM::Role
266+
Condition: IsBucketAccount
267+
Properties:
268+
RoleName: !Ref RoleName
269+
AssumeRolePolicyDocument:
270+
Version: "2012-10-17"
271+
Statement:
272+
- Effect: "Allow"
273+
Principal:
274+
AWS: !Ref TrustedIdentity
275+
Action: "sts:AssumeRole"
276+
Condition:
277+
StringEquals:
278+
"sts:ExternalId": !Ref ExternalID
279+
Policies:
280+
- PolicyName: "cloudlogs_s3_access_policy"
281+
PolicyDocument:
282+
Version: "2012-10-17"
283+
Statement:
284+
- Sid: "S3BucketListAccess"
285+
Effect: "Allow"
286+
Action:
287+
- "s3:ListBucket"
288+
- "s3:GetBucketLocation"
289+
Resource:
290+
- !Ref BucketARN
291+
- Sid: "S3ObjectAccess"
292+
Effect: "Allow"
293+
Action:
294+
- "s3:GetObject"
295+
Resource:
296+
- !Sub "${BucketARN}/*"
297+
- !If
298+
- HasKMSKey
299+
- Sid: "KMSDecryptAccess"
300+
Effect: "Allow"
301+
Action: "kms:Decrypt"
302+
Resource: !Ref KMSKeyARN
303+
- !Ref "AWS::NoValue"
304+
Tags:
305+
- Key: "Name"
306+
Value: "Sysdig Secure CloudTrail Logs Access Role"
307+
- Key: "Purpose"
308+
Value: "Allow Sysdig to access S3 bucket for CloudTrail logs"
309+
- Key: "product"
310+
Value: "sysdig-secure-for-cloud"
311+
312+
CloudTrailSNSSubscription:
313+
Type: AWS::SNS::Subscription
314+
Condition: IsTopicAccount
315+
Properties:
316+
TopicArn: !Ref TopicARN
317+
Protocol: "https"
318+
Endpoint: !Ref Endpoint
319+
Outputs:
320+
S3AccessRoleArn:
321+
Description: ARN of the IAM role created in the bucket account for S3 access
322+
Value: !GetAtt S3AccessRole.Arn
323+
KMSPolicyInstructions:
324+
Description: Instructions for updating KMS key policy when KMS encryption is enabled
325+
Condition: HasKMSKey
326+
Value: !Sub |
327+
IMPORTANT: MANUAL ACTION REQUIRED
328+
329+
Please add the following statement to your KMS key policy to allow Sysdig to decrypt logs.
330+
This is necessary when KMS encryption is enabled for your S3 bucket.
331+
Without this policy addition, Sysdig may not be able to read your encrypted logs.
332+
333+
{
334+
"Sid": "Sysdig-Decrypt",
335+
"Effect": "Allow",
336+
"Principal": {
337+
"AWS": "${S3AccessRole.Arn}"
338+
},
339+
"Action": "kms:Decrypt",
340+
"Resource": "*"
341+
}
134342
135343
Outputs:
136344
TopicARN:
137345
Description: "The ARN of the SNS Topic created for CloudTrail notifications."
138346
Value: !If [ CreateSNSTopic, !Ref CloudTrailNotificationsTopic, !Ref TopicARN ]
347+
RoleARN:
348+
Description: "The ARN of the IAM Role created for CloudTrail logs access."
349+
Condition: NotIsCrossAccount
350+
Value: !GetAtt CloudLogsRole.Arn
351+
CrossAccountRoleARN:
352+
Description: "ARN of the Cross-Account IAM Role for accessing the S3 bucket."
353+
Condition: IsCrossAccount
354+
Value: !Sub "arn:${Partition}:iam::${BucketAccountId}:role/sysdig-secure-cloudlogs-${AWS::AccountId}-${NameSuffix}"
355+
KMSPolicyInstructionsSameAccount:
356+
Description: "Instructions for updating KMS key policy when KMS encryption is enabled"
357+
Condition: HasKMSAndNotCrossAccount
358+
Value: !Sub |
359+
IMPORTANT: MANUAL ACTION REQUIRED
360+
361+
Please add the following statement to your KMS key policy to allow Sysdig to decrypt logs.
362+
This is necessary when KMS encryption is enabled for your S3 bucket.
363+
Without this policy addition, Sysdig may not be able to read your encrypted logs.
364+
365+
{
366+
"Sid": "Sysdig-Decrypt",
367+
"Effect": "Allow",
368+
"Principal": {
369+
"AWS": "${CloudLogsRole.Arn}"
370+
},
371+
"Action": "kms:Decrypt",
372+
"Resource": "*"
373+
}
374+
KMSPolicyInstructionsCrossAccount:
375+
Description: "Instructions for updating KMS key policy when KMS encryption is enabled (Cross-Account)"
376+
Condition: HasKMSAndIsCrossAccount
377+
Value: !Sub |
378+
IMPORTANT: MANUAL ACTION REQUIRED
379+
380+
Please add the following statement to your KMS key policy to allow Sysdig to decrypt logs.
381+
This is necessary when KMS encryption is enabled for your S3 bucket.
382+
Without this policy addition, Sysdig may not be able to read your encrypted logs.
383+
384+
{
385+
"Sid": "Sysdig-Decrypt",
386+
"Effect": "Allow",
387+
"Principal": {
388+
"AWS": "arn:${Partition}:iam::${BucketAccountId}:role/sysdig-secure-cloudlogs-${AWS::AccountId}-${NameSuffix}"
389+
},
390+
"Action": "kms:Decrypt",
391+
"Resource": "*"
392+
}

0 commit comments

Comments
 (0)