Set Event Value for Cloudtrail - all S3 buckets - aws-cloudformation

I'm trying to get a cloudtrail for all S3 bucket Data but it keeps throwing an error. The template looks like:
DataTrail:
Type: AWS::CloudTrail::Trail
Properties:
CloudWatchLogsLogGroupArn:
Fn::ImportValue:
!Sub ${EnvironmentName}-CloudtrailLogGroupARN
CloudWatchLogsRoleArn:
Fn::ImportValue:
!Sub ${EnvironmentName}-CloudTrailLogsRoleARN
EnableLogFileValidation: true
EventSelectors:
- DataResources:
- Type: AWS::S3::Object
Values:
- 'arn:aws:s3:::*'
- IncludeManagementEvents: false
- ReadWriteType: All
IncludeGlobalServiceEvents: true
IsLogging: true
IsMultiRegionTrail: true
KMSKeyId:
Fn::ImportValue:
!Sub ${EnvironmentName}-InvoicegenKey-CMK-Arn
S3BucketName:
Fn::ImportValue:
!Sub ${EnvironmentName}-CloudTrailBucket-Name
the AWS Doku says it must be a list of string, so I did:
Values:
- 'arn:aws:s3:::*'
But it keeps failing...
Merci in Advance
A

In the end it was pretty easy; I just created a trail via Console and then used aws cloudtrail get-event-selectors --trail-name <name> to get the result. then transferred it to my template like this:
DataResources:
- Type: AWS::S3::Object
Values:
- arn:aws:s3

yeah, pretty close though but correct indent should be
cloudtrail:
Type: AWS::CloudTrail::Trail
Properties:
EnableLogFileValidation: Yes
EventSelectors:
- DataResources:
- Type: AWS::S3::Object
Values:
- arn:aws:s3:::s3-event-step-bucket/
IncludeManagementEvents: Yes
ReadWriteType: All
IncludeGlobalServiceEvents: Yes
IsLogging: Yes
IsMultiRegionTrail: Yes
S3BucketName: s3-event-step-bucket-storage
TrailName: xyz

Related

how to pass bucket/key name to fargate job via a cloudwatch event trigger on s3 object creation event?

I have create a fargate task and trying to trigger it via s3 object creation event ( see sample below) via cloudformation.as it cannot trigger it directly, i have created a cloudwatchevent. I am trying to pass the bucket and obj name to my fargate task code . doing some research, i came across -> InputTransformer, but i'm not sure how to pass the value of my bucket and key name and how to read it in my python code. any help will be appreciated.
AWSTemplateFormatVersion: 2010-09-09
Description: An example CloudFormation template for Fargate.
Parameters:
VPC:
Type: AWS::EC2::VPC::Id
SubnetA:
Type: AWS::EC2::Subnet::Id
SubnetB:
Type: AWS::EC2::Subnet::Id
Image:
Type: String
Default: 123456789012.dkr.ecr.region.amazonaws.com/image:tag
Resources:
mybucket:
Properties:
BucketName: 'mytestbucket-us'
cloudwatchEvent:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.s3
detail:
eventSource:
- s3.amazonaws.com
eventName:
- PutObject
- CompleteMultipartUpload
requestParameters:
bucketName:
- !Ref mybucket
Targets:
- Id: my-fargate-task
Arn: myclusterArn
RoleArn: myinvocationrolearn
Input:
'Fn::Sub':
- >-
{"containerOverrides": [{"name":"somecontainer"]}
EcsParameters:
TaskDefinition:
LaunchType: 'FARGATE'
...
NetworkConfiguration:
...
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Join ['', [!Ref ServiceName, Cluster]]
TaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn: LogGroup
Properties:
Family: !Join ['', [!Ref ServiceName, TaskDefinition]]
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: 256
Memory: 2GB
ExecutionRoleArn: !Ref ExecutionRole
TaskRoleArn: !Ref TaskRole
ContainerDefinitions:
- Name: !Ref ServiceName
Image: !Ref Image
# A role needed by ECS
ExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join ['', [!Ref ServiceName, ExecutionRole]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
# A role for the containers
TaskRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join ['', [!Ref ServiceName, TaskRole]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
You would use a CloudWatch Event Input Transformer to extract the data you need from the event, and pass that data to the ECS task as environment variable(s) in the target's ContainerOverrides. I don't use CloudFormation, but here's an example using Terraform.
You can't. CloudWatch events do not pass data to ECS jobs. You need to develop your own mechanism for that. For example, trigger lambda first, store event in S3 Parameter Store or DynamoDB, and then invoke your ECS job which will get stored data.

Export and ImportValue in another stack under sub

I am trying to get a value from one stack to another using the below syntax.
stack one-
Outputs:
CompRestAPI:
Description: Rest Api Id
Value: !Ref CompRestAPI
Export:
Name: 'CompRestAPI'
Stack two -
CompRestApiWaf:
Type: AWS::WAFv2::WebACLAssociation
DependsOn: CompApiGatewayStage
Properties:
RestApiId: !ImportValue 'CompRestAPI'
ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/${RestApiId}/${STAGENAME}-apistage'
WebACLArn: !Ref WafId
I am able to get the values for other resources using 1st syntax, but I am not able to get the value for RestApiId under !Sub
RestApiId: !ImportValue 'CompRestAPI'
ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/${RestApiId}/apistage'
So is there any way to use !ImportValue under !Sub condition?
I tried it using below code, validation is pass but still showing me an error
Error reason: The ARN isn't valid. A valid ARN begins with arn: and includes other information separated by colons or slashes., field: RESOURCE_ARN, parameter:
CompRestApiWaf:
Type: AWS::WAFv2::WebACLAssociation
DependsOn: CompApiGatewayStage
Properties:
ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/{!ImportValue CompRestAPI}/stages/apistage'
WebACLArn: !Ref WafId
I am done with it using Fn::join:
SourceArn:
Fn::Join:
- ""
- - 'arn:aws:execute-api:'
- !Ref AWS::Region
- ':'
- !Ref AWS::AccountId
- ':'
- !Ref ApiGatewayRestApiResource
- '/*'
this should work
ResourceArn: !Sub
- 'arn:aws:apigateway:${REGION}:/${CompRestAPI}/stages/apistage'
- CompRestAPI: !ImportValue CompRestAPI
you can expand the second parameter to have multiple keys for multiple imports like so
SecretString: !Sub
- 'postgres://${username}:${password}#${dbhost}:${dbport}/${dbname}'
- username: !Ref 'DBUser'
password: !Ref 'DBPassword'
dbhost: !Ref DbMasterDnsEntry
dbport: !GetAtt AuroraPgCluster.Endpoint.Port
dbname: !Ref 'DBName'

How to combine list from Fn::FindInMap with additional items?

I have next CloudFormation file:
Mappings:
MyMap:
us-east-1:
Roles:
- "roleA"
- "roleB"
...
Resources:
MyPolicy:
Type: "AWS::IAM::Policy"
PolicyDocument:
Statement:
- Effect: "Allow"
Action:
- "sts:AssumeRole"
Resource:
Fn::FindInMap: ["MyMap", !Ref AWS::Region, "Roles"]
Everything works fine, however now I need to add an extra role that would be defined for all regions, however simply adding additional role to Resource: section doesn't work, since it fails with template syntax error.
Is there a way to combine list of results from FindInMap and another item? Something like:
Resource:
Fn::FindInMap: ["MyMap", !Ref AWS::Region, "Roles"]
- "roleC"
Yes, you can, but it won't be pretty:
Resource:
Fn::Split:
- ','
- Fn::Join:
- ','
- - !Join [',', !FindInMap ["MyMap", !Ref "AWS::Region", "Roles"]]
- 'roleC'
Basically, first you join the MyMap list into a string, then you add roleC to the string, and then split it into List of Strings.

CloudFormation Combine Sub - Import - Sub

I am trying to create a parameter and would like to combine !Sub and !Import several times.
Parameters:
Environment:
Description: Stackname of Environment
Type: String
Resources:
IAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: '*'
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: S3Files
PolicyDocument:
Statement:
- Sid: 'S3Files'
Effect: Allow
Action:
- 's3:DeleteObjectTagging'
- 's3:GetObjectRetention'
- 's3:ListMultipartUploadParts'
- 's3:PutObject'
- 's3:GetObjectAcl'
- 's3:GetObject'
- 's3:AbortMultipartUpload'
- 's3:PutObjectRetention'
- 's3:GetObjectVersionAcl'
- 's3:GetObjectTagging'
- 's3:PutObjectTagging'
- 's3:DeleteObject'
- 's3:PutObjectAcl'
- 's3:GetObjectVersion'
Resource: !Sub
- '${ARN}/*'
- ARN:
Fn::ImportValue: !Sub ${Environment}:S3:Arn
According to the documentation it should be possible, but unfortunately I always get an error message
Template contains errors.: [/Resources/IAMRole/Type/Policies/0/PolicyDocument/Statement/0/Resource/Fn::Sub/1/ARN] 'null' values are not allowed in templates
How could the UseCase work?
There is a space issue in the Resource section.
Resource: !Sub
- '${ARN}/*'
- ARN:
Fn::ImportValue: !Sub ${Environment}:S3:Arn
It should be
Resource: !Sub
- '${ARN}/*'
- ARN:
Fn::ImportValue: !Sub ${Environment}:S3:Arn
Note: Fn starts under N of ARN instead of A.
Explanation: With the first indentation the line with Fn::ImportValue is considered as an input for !Sub, with the second indentation it becomes the value for ARN: defined the line above it.
Side note: Use 2 spaces or 4 spaces or tabs uniformly throughout the template.

Encountered unsupported property AutoScalingReplacingUpdate

Encountered unsupported property AutoScalingReplacingUpdate error appears when trying to launch a stack that contains the following AWS::AutoScaling::AutoScalingGroup:
myAutoScalingGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
CreationPolicy:
AutoScalingReplacingUpdate:
WillReplace: true
Properties:
HealthCheckType: ELB
HealthCheckGracePeriod: 300
AvailabilityZones:
- eu-west-1a
- eu-west-1b
- eu-west-1c
VPCZoneIdentifier:
- 'Fn::ImportValue': !Sub '${vpcId1}'
- 'Fn::ImportValue': !Sub '${vpcId2}'
- 'Fn::ImportValue': !Sub '${vpcId3}'
MetricsCollection:
- Granularity: 1Minute
Metrics:
- GroupMinSize
- GroupMaxSize
- GroupInServiceInstances
- GroupPendingInstances
- GroupTerminatingInstances
MinSize: !Ref AutoScalingGroupWSMinSize
MaxSize: !Ref AutoScalingGroupWSMaxSize
LaunchConfigurationName: !Ref myLaunchConfig
TargetGroupARNs:
- !Ref myTargetGroup
I have found a (undesired) workaround for this but i really don't want to rely on it. The work around is the following:
comment out
CreationPolicy:
AutoScalingReplacingUpdate:
WillReplace: true
launch the template
update the successfully launched stack by uncommenting the above
lines
This is bad and i don't want to do it, since my goal is to automate my infrastructure.
The atribute CreationPolicy do not have the AutoScalingReplacingUpdate property
CreationPolicy:
AutoScalingCreationPolicy:
MinSuccessfulInstancesPercent: Integer
ResourceSignal:
Count: Integer
Timeout: String
The attribute UpdatePolicy is the one that does have the property AutoScalingReplacingUpdate:
UpdatePolicy:
AutoScalingReplacingUpdate:
WillReplace: Boolean