I have a requirement to select all the rules in AWS Config while deploying the resources in newly created account through Cloudformation. But I don't know how to select all the AWS Managed rules as in Console through Cloudformation. Any help would be very helpful.
AWSTemplateFormatVersion: 2010-09-09
Description: Enable AWS Config
Parameters:
AllSupported:
Type: String
Default: True
Description: Indicates whether to record all supported resource types.
AllowedValues:
- True
- False
IncludeGlobalResourceTypes:
Type: String
Default: True
Description: Indicates whether AWS Config records all supported global resource types.
AllowedValues:
- True
- False
ResourceTypes:
Type: List<String>
Description: A list of valid AWS resource types to include in this recording group, such as AWS::EC2::Instance or AWS::CloudTrail::Trail.
Default: <All>
DeliveryChannelName:
Type: String
Default: <Generated>
Description: The name of the delivery channel.
Frequency:
Type: String
Default: 24hours
Description: The frequency with which AWS Config delivers configuration snapshots.
AllowedValues:
- 1hour
- 3hours
- 6hours
- 12hours
- 24hours
Conditions:
IsAllSupported: !Equals
- !Ref AllSupported
- True
IsGeneratedDeliveryChannelName: !Equals
- !Ref DeliveryChannelName
- <Generated>
Mappings:
Settings:
FrequencyMap:
1hour : One_Hour
3hours : Three_Hours
6hours : Six_Hours
12hours : Twelve_Hours
24hours : TwentyFour_Hours
Resources:
ConfigBucket:
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
ConfigBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref ConfigBucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: AWSConfigBucketPermissionsCheck
Effect: Allow
Principal:
Service:
- config.amazonaws.com
Action: s3:GetBucketAcl
Resource:
- !Sub "arn:${AWS::Partition}:s3:::${ConfigBucket}"
- Sid: AWSConfigBucketDelivery
Effect: Allow
Principal:
Service:
- config.amazonaws.com
Action: s3:PutObject
Resource:
- !Sub "arn:${AWS::Partition}:s3:::${ConfigBucket}/AWSLogs/${AWS::AccountId}/*"
- Sid: AWSConfigBucketSecureTransport
Action:
- s3:*
Effect: Deny
Resource:
- !Sub "arn:${AWS::Partition}:s3:::${ConfigBucket}"
- !Sub "arn:${AWS::Partition}:s3:::${ConfigBucket}/*"
Principal: "*"
Condition:
Bool:
aws:SecureTransport:
false
ConfigRecorderRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- config.amazonaws.com
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AWS_ConfigRole"
ConfigRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn:
- ConfigBucketPolicy
Properties:
RoleARN: !GetAtt ConfigRecorderRole.Arn
RecordingGroup:
AllSupported: !Ref AllSupported
IncludeGlobalResourceTypes: !Ref IncludeGlobalResourceTypes
ResourceTypes: !If
- IsAllSupported
- !Ref AWS::NoValue
- !Ref ResourceTypes
ConfigDeliveryChannel:
Type: AWS::Config::DeliveryChannel
DependsOn:
- ConfigBucketPolicy
Properties:
Name: !If
- IsGeneratedDeliveryChannelName
- !Ref AWS::NoValue
- !Ref DeliveryChannelName
ConfigSnapshotDeliveryProperties:
DeliveryFrequency: !FindInMap
- Settings
- FrequencyMap
- !Ref Frequency
S3BucketName: !Ref ConfigBucket
ConfigRuleForVolumeTags:
DependsOn: ConfigRecorder
Type: AWS::Config::ConfigRule
Properties:
InputParameters:
tag1Key: CostCenter
Scope:
ComplianceResourceTypes:
- "AWS::EC2::Volume"
Source:
Owner: AWS
SourceIdentifier: "REQUIRED_TAGS"
# Like this I need all the AWS Managed rules
You can't do this. There are no loops in cloudformation. But you could create a macro if you want such a functionality.
Related
I'm trying to write a template that configures the whole ecs fargate server and its code pipeline.
There is no problem in all other configurations, but the image is empty because it is right after creating the ecr in cloudformation, and the create ecs service refers to the empty image and the process does not end.
So I want to push the server image to ecr with code build and then ecs service create to work, but I don't know how.
Could it be possible to trigger code build or code pipeline inside cloudformation?
If not, is there any way to do docker build & push?
Yes it can be done, I used it before to perform jobs like a database restore as part of stack creation (don't ask). What you need:
A custom resource lambda which kicks off the codebuild job. It will receive the codebuild project to start via a property passed to it in the cloudformation resource definition (assuming that the codebuild is determined at deploy time; else feel free to make the lambda know about which codebuild to run in whatever way makes the most sense to you).
The endpoint to call when the custom resource is complete. A custom resource will stay in CREATE_IN_PROGRESS state until the endpoint is called. It's been a while since I've used custom resources so don't remember where it comes from but I think it's found in the event that the custom resource lambda is invoked with.
Your codebuild job needs that endpoint and needs to be able to send a (GET or POST?) request to it, on both success and failure cases (you pass different params signifying success or failure).
So the overall sequence of steps is:
Define/reference the custom resource in your template, passing in whatever properties the lambda needs.
Deploy stack, custom resource lambda is invoked.
The custom resource status goes into CREATE_IN_PROGRESS
Lambda kicks off codebuild, passing in custom resource endpoint as a param or env var, and returns.
Codebuild starts doing its work.
Until the endpoint is invoked, the custom resource will remain as CREATE_IN_PROGRESS, and the stack create/update process will wait for it, even if it takes hours.
When codebuild has finished its work, it uses curl or similar to invoke that endpoint to signal it's complete.
Custom resource status goes to CREATE_COMPLETE (assuming you've invoked the endpoint with params saying it was successful).
Stack creation completes (or moves on to any resources that were dependent on the custom resource).
Yes, it is possible to trigger the Fargate deployment after pushing the image rather than when the CloudFormation template is run.
The trick is to set the DesiredCount property of AWS::ECS::Service to zero:
Service:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DesiredCount: 0
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
SecurityGroups:
- !Ref SecG
Subnets: !Ref Subs
ServiceName: !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
TaskDefinition: !Ref TaskDefinition
That said, you can also choose to create a repo with an initial commit that will trigger the build as soon as the template is done executing. This requires you to upload the zipped source code to an S3 bucket and configure the CodeCommit repository like so:
Repo:
Type: AWS::CodeCommit::Repository
Properties:
Code:
BranchName: main
S3:
Bucket: some-bucket
Key: code.zip
RepositoryName: !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
RepositoryDescription: Repository
Triggers:
- Name: Trigger
CustomData: The Code Repository
DestinationArn: !Ref Topic
Branches:
- main
Events: [all]
Note that the some-bucket S3 bucket needs to contain the zipped .Dockerfile and any source code without any .git directory included.
You can see my implementation of this system and the rest of the stack below:
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation Stack to Trigger CodeBuild via CodePipeline
Parameters:
SecG:
Description: Single security group
Type: AWS::EC2::SecurityGroup::Id
Subs:
Description: Comma separated subnet IDs
Type: List<AWS::EC2::Subnet::Id>
ImagesFile:
Type: String
Default: images.json
Resources:
ArtifactBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
Tags:
- Key: UseWithCodeDeploy
Value: true
CodeBuildServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: !Sub 'ssm-${AWS::Region}-${AWS::StackName}'
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action:
- ssm:GetParameters
- secretsmanager:GetSecretValue
Resource: '*'
- PolicyName: !Sub 'logs-${AWS::Region}-${AWS::StackName}'
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
- PolicyName: !Sub 'ecr-${AWS::Region}-${AWS::StackName}'
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Action:
- ecr:BatchCheckLayerAvailability
- ecr:CompleteLayerUpload
- ecr:GetAuthorizationToken
- ecr:InitiateLayerUpload
- ecr:PutImage
- ecr:UploadLayerPart
- lightsail:*
Resource: '*'
- PolicyName: !Sub bkt-${ArtifactBucket}-${AWS::Region}
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action:
- s3:ListBucket
- s3:GetBucketLocation
- s3:ListBucketVersions
- s3:GetBucketVersioning
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}
- arn:aws:s3:::some-bucket
- PolicyName: !Sub obj-${ArtifactBucket}-${AWS::Region}
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:GetObjectAcl
- s3:PutObjectAcl
- s3:GetObjectTagging
- s3:PutObjectTagging
- s3:GetObjectVersion
- s3:GetObjectVersionAcl
- s3:PutObjectVersionAcl
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
- arn:aws:s3:::some-bucket/*
CodeDeployServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Sid: '1'
Effect: Allow
Principal:
Service:
- codedeploy.us-east-1.amazonaws.com
- codedeploy.eu-west-1.amazonaws.com
Action: sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS
- arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole
- arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda
CodeDeployRolePolicies:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub 'CDPolicy-${AWS::Region}-${AWS::StackName}'
PolicyDocument:
Statement:
- Effect: Allow
Resource:
- '*'
Action:
- ec2:Describe*
- Effect: Allow
Resource:
- '*'
Action:
- autoscaling:CompleteLifecycleAction
- autoscaling:DeleteLifecycleHook
- autoscaling:DescribeLifecycleHooks
- autoscaling:DescribeAutoScalingGroups
- autoscaling:PutLifecycleHook
- autoscaling:RecordLifecycleActionHeartbeat
Roles:
- !Ref CodeDeployServiceRole
CodePipelineServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: !Sub 'root-${AWS::Region}-${AWS::StackName}'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Resource:
- !Sub 'arn:aws:s3:::${ArtifactBucket}/*'
- !Sub 'arn:aws:s3:::${ArtifactBucket}'
Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketAcl
- s3:GetBucketLocation
- Resource: "*"
Effect: Allow
Action:
- ecs:*
- Resource: "*"
Effect: Allow
Action:
- iam:PassRole
Condition:
StringLike:
iam:PassedToService:
- ecs-tasks.amazonaws.com
- Resource: !GetAtt Build.Arn
Effect: Allow
Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- codebuild:BatchGetBuildBatches
- codebuild:StartBuildBatch
- Resource: !GetAtt Repo.Arn
Effect: Allow
Action:
- codecommit:CancelUploadArchive
- codecommit:GetBranch
- codecommit:GetCommit
- codecommit:GetRepository
- codecommit:GetUploadArchiveStatus
- codecommit:UploadArchive
AmazonCloudWatchEventRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Principal:
Service:
- events.amazonaws.com
Action: sts:AssumeRole
Path: /
Policies:
-
PolicyName: cwe-pipeline-execution
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action: codepipeline:StartPipelineExecution
Resource: !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${Pipeline}
AmazonCloudWatchEventRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.codecommit
detail-type:
- CodeCommit Repository State Change
resources:
- !GetAtt Repo.Arn
detail:
event:
- referenceCreated
- referenceUpdated
referenceType:
- branch
referenceName:
- main
Targets:
-
Arn: !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${Pipeline}
RoleArn: !GetAtt AmazonCloudWatchEventRole.Arn
Id: codepipeline-Pipeline
Topic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: user#example.com
Protocol: email
TopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Sid: AllowPublish
Effect: Allow
Principal:
Service:
- 'codestar-notifications.amazonaws.com'
Action:
- 'SNS:Publish'
Resource:
- !Ref Topic
Topics:
- !Ref Topic
Repo:
Type: AWS::CodeCommit::Repository
Properties:
Code:
BranchName: main
S3:
Bucket: some-bucket
Key: code.zip
RepositoryName: !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
RepositoryDescription: Repository
Triggers:
- Name: Trigger
CustomData: The Code Repository
DestinationArn: !Ref Topic
Branches:
- main
Events: [all]
RepoUser:
Type: AWS::IAM::User
Properties:
Path: '/'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSCodeCommitPowerUser
RepoUserKey:
Type: AWS::IAM::AccessKey
Properties:
UserName:
!Ref RepoUser
Registry:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
RepositoryPolicyText:
Version: '2012-10-17'
Statement:
- Sid: AllowPushPull
Effect: Allow
Principal:
AWS:
- !GetAtt CodeDeployServiceRole.Arn
Action:
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:BatchCheckLayerAvailability
- ecr:PutImage
- ecr:InitiateLayerUpload
- ecr:UploadLayerPart
- ecr:CompleteLayerUpload
Build:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Source:
Type: CODEPIPELINE
BuildSpec: !Sub |
version: 0.2
phases:
pre_build:
commands:
- echo "[`date`] PRE_BUILD"
- echo "Logging in to Amazon ECR..."
- aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT.dkr.ecr.$REGION.amazonaws.com
- IMAGE_URI="$ACCOUNT.dkr.ecr.$REGION.amazonaws.com/$REPO:$TAG"
build:
commands:
- echo "[`date`] BUILD"
- echo "Building Docker Image..."
- docker build -t $REPO:$TAG .
- docker tag $REPO:$TAG $IMAGE_URI
post_build:
commands:
- echo "[`date`] POST_BUILD"
- echo "Pushing Docker Image..."
- docker push $IMAGE_URI
- echo Writing image definitions file...
- printf '[{"name":"svc","imageUri":"%s"}]' $IMAGE_URI > $FILE
artifacts:
files: $FILE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/standard:6.0
Type: LINUX_CONTAINER
EnvironmentVariables:
- Name: REGION
Type: PLAINTEXT
Value: !Ref AWS::Region
- Name: ACCOUNT
Type: PLAINTEXT
Value: !Ref AWS::AccountId
- Name: TAG
Type: PLAINTEXT
Value: latest
- Name: REPO
Type: PLAINTEXT
Value: !Ref Registry
- Name: FILE
Type: PLAINTEXT
Value: !Ref ImagesFile
PrivilegedMode: true
Name: !Ref AWS::StackName
ServiceRole: !GetAtt CodeBuildServiceRole.Arn
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
- Name: Source
Actions:
- Name: Site
ActionTypeId:
Category: Source
Owner: AWS
Version: '1'
Provider: CodeCommit
Configuration:
RepositoryName: !GetAtt Repo.Name
BranchName: main
PollForSourceChanges: 'false'
InputArtifacts: []
OutputArtifacts:
- Name: SourceArtifact
RunOrder: 1
- Name: Build
Actions:
- Name: Docker
ActionTypeId:
Category: Build
Owner: AWS
Version: '1'
Provider: CodeBuild
Configuration:
ProjectName: !Ref Build
InputArtifacts:
- Name: SourceArtifact
OutputArtifacts:
- Name: BuildArtifact
RunOrder: 1
- Name: Deploy
Actions:
- Name: Fargate
ActionTypeId:
Category: Deploy
Owner: AWS
Version: '1'
Provider: ECS
Configuration:
ClusterName: !Ref Cluster
FileName: !Ref ImagesFile
ServiceName: !GetAtt Service.Name
InputArtifacts:
- Name: BuildArtifact
RunOrder: 1
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
FargateTaskExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ecs-tasks.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
TaskRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ecs-tasks.amazonaws.com
Action:
- sts:AssumeRole
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
-
Name: svc
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${Registry}:latest
PortMappings:
- ContainerPort: 8080
Cpu: 256
ExecutionRoleArn: !Ref FargateTaskExecutionRole
Memory: 512
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
RuntimePlatform:
CpuArchitecture: ARM64
OperatingSystemFamily: LINUX
TaskRoleArn: !Ref TaskRole
Service:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DesiredCount: 0
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
SecurityGroups:
- !Ref SecG
Subnets: !Ref Subs
ServiceName: !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
TaskDefinition: !Ref TaskDefinition
Outputs:
ArtifactBucketName:
Description: ArtifactBucket S3 Bucket Name
Value: !Ref ArtifactBucket
ArtifactBucketSecureUrl:
Description: ArtifactBucket S3 Bucket Domain Name
Value: !Sub 'https://${ArtifactBucket.DomainName}'
ClusterName:
Value: !Ref Cluster
ServiceName:
Value: !GetAtt Service.Name
RepoUserAccessKey:
Description: S3 User Access Key
Value: !Ref RepoUserKey
RepoUserSecretKey:
Description: S3 User Secret Key
Value: !GetAtt RepoUserKey.SecretAccessKey
BuildArn:
Description: CodeBuild URL
Value: !GetAtt Build.Arn
RepoArn:
Description: CodeCommit Repository ARN
Value: !GetAtt Repo.Arn
RepoName:
Description: CodeCommit Repository NAme
Value: !GetAtt Repo.Name
RepoCloneUrlHttp:
Description: CodeCommit HTTP Clone URL
Value: !GetAtt Repo.CloneUrlHttp
RepoCloneUrlSsh:
Description: CodeCommit SSH Clone URL
Value: !GetAtt Repo.CloneUrlSsh
PipelineUrl:
Description: CodePipeline URL
Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline}
RegistryUri:
Description: ECR Repository URI
Value: !GetAtt Registry.RepositoryUri
TopicArn:
Description: CodeCommit Notification SNS Topic ARN
Value: !Ref Topic
Hope this helps!
Everything works perfectly in the code below if run without the 4 lines starting NotificationConfiguration . I thought this might be because of needing the topic policy before setting notification on the bucket. So have tried to do the initial create without the NotificationConfiguration lines and then add these in and update the stack.
But get the error Unable to validate the following destination configurations (Service: Amazon S3; Status Code: 400; Error Code: InvalidArgument; . I've tried things like putting the actual topic arn not using !Ref but no joy. Thanks!
Resources:
DeletionSNSTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName:
!Join [" ",[Data has been deleted from,!Sub '${ServiceName}-${Stage}-${AWS::AccountId}']
]
Subscription:
- Endpoint: !Sub '${DeleteNotifyEmail}'
Protocol: email
TopicName: !Sub 'delete-from-${ServiceName}-bucket'
DataBucket:
Type: AWS::S3::Bucket
DependsOn: DeletionSNSTopic
Description: Create Amazon S3 bucket from CloudFormation
Properties:
BucketName: !Sub '${ServiceName}-${Stage}-${AWS::AccountId}'
AccessControl: Private
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
NotificationConfiguration:
TopicConfigurations:
- Topic: !Ref DeletionSNSTopic
Event: 's3:ObjectRemoved:*'
BucketToSNSPermission:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Id: 'deletionTopicPolicy'
Version: '2012-10-17'
Statement:
- Sid: 'deletionTopic-statement-id'
Effect: Allow
Principal:
Service: s3.amazonaws.com
Action: sns:Publish
Resource: !Ref DeletionSNSTopic
Condition:
StringEquals:
aws:SourceAccount: !Sub '${AWS::AccountId}'
ArnLike:
aws:SourceArn: !Ref DataBucket
Topics:
- !Ref DeletionSNSTopic
You have circular dependency in your code. You create bucket with notifications, before topic policy is applied. Obviously the policy can't be created before the bucket because the bucket must already exist due to !Ref DataBucket.
To solve that the bucket name must be known first, which in your case is possible:
Resources:
DeletionSNSTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName:
!Join [" ",[Data has been deleted from,!Sub '${ServiceName}-${Stage}-${AWS::AccountId}']
]
Subscription:
- Endpoint: !Sub '${DeleteNotifyEmail}'
Protocol: email
TopicName: !Sub 'delete-from-${ServiceName}-bucket'
DataBucket:
Type: AWS::S3::Bucket
DependsOn: BucketToSNSPermission
Description: Create Amazon S3 bucket from CloudFormation
Properties:
BucketName: !Sub '${ServiceName}-${Stage}-${AWS::AccountId}'
AccessControl: Private
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
NotificationConfiguration:
TopicConfigurations:
- Topic: !Ref DeletionSNSTopic
Event: 's3:ObjectRemoved:*'
BucketToSNSPermission:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Id: 'deletionTopicPolicy'
Version: '2012-10-17'
Statement:
- Sid: 'deletionTopic-statement-id'
Effect: Allow
Principal:
Service: s3.amazonaws.com
Action: SNS:Publish
Resource: !Ref DeletionSNSTopic
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
ArnLike:
aws:SourceArn: !Sub "arn:aws:s3:::${ServiceName}-${Stage}-${AWS::AccountId}"
Topics:
- !Ref DeletionSNSTopic
For general case check in:
How do I avoid the "Unable to validate the following destination configurations" error in AWS CloudFormation?
I'm trying to create a new role and a policy using cloudformation.
When deploying it I'm getting the following error :
Syntax errors in policy. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: 848a408e-b0f1-11e8-90b6-cf2a19d18ad2)
AWSTemplateFormatVersion: 2010-09-09
Description: >
AWS CloudFormation Template
Parameters:
StackName:
Type: String
Description: stack test
Default: stackTest
DclEnvironment:
Type: String
Description: Env
AllowedValues :
- test
- dev
- stage
- prod
Default: dev
Domain:
Type: String
Description: Private Domain name
Default: int.mydomain.com
VpcId:
Type: AWS::EC2::VPC::Id
Default: xxxx
AppAmiId:
Type: AWS::EC2::Image::Id
Description: Ec2 AMI ID
Default: ami-XXXX
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Key Name
Default: xxxx
SecurityGroupIds:
Type: CommaDelimitedList
Description: Comma-separated list of existing security group IDs in your VPC
Default: sg-xxxx
SubnetA:
Description: Subnet from AZ a
Type: String
Default: subnet-xxxxx
SubnetB:
Description: Subnet from AZ b
Type: String
Default: subnet-xxxx
SubnetC:
Description: Subnet from AZ c
Type: String
Default: subnet-xxxx
DbSubnetGroupA:
Type: String
Description: Subnet from AZ A
Default: subnet-xxxx
DbSubnetGroupB:
Type: String
Description: Subnet from AZ B
Default: subnet-xxxxx
DbSubnetGroupC:
Type: String
Description: Subnet from AZ C
Default: subnet-xxxxx
Resources:
monitoringRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join
- "-"
- - !Ref DclEnvironment
- "iam-01"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ec2.amazonaws.com
Path: "/"
policyEC2Monitoring:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Join
- "-"
- - !Ref DclEnvironment
- "policy-01"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:Describe*
Ressource: "*"
- Effect: Allow
Action:
- elasticloadbalancing:Describe*
Ressource: "*"
- Effect: Allow
Action:
- cloudwatch:ListMetrics*
- cloudwatch:GetMetricStatistics
- cloudwatch:Describe*
Ressource: "*"
- Effect: Allow
Action:
- autoscaling:Describe*
Ressource: "*"
Roles:
- !Ref monitoringRole
instanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: !Join
- "-"
- - !Ref DclEnvironment
- "inp-01"
Path: "/"
Roles:
- !Ref monitoringRole
Thanks by advance,
Fas3r.
EDIT
resource should be surrounded by [ "*" ] if more than 1 action;
If one action, it's not necessary to add a new line, it can be :
Action : actionName
br.
As the error suggests, your yaml has invalid syntax.
You can use web tools like http://www.yamllint.com/ to troubleshoot the syntax issues.
Here's the correct syntax yaml file:
AWSTemplateFormatVersion: 2010-09-09
Description: >
AWS CloudFormation Template
Parameters:
StackName:
Type: String
Description: stack test
Default: stackTest
DclEnvironment:
Type: String
Description: Env
AllowedValues :
- test
- dev
- stage
- sbox
- prod
Default: dev
DclPod:
Type: String
Description: Pod Name
Default: enel
DclService:
Type: String
Description: Pod Name
Default: monitoring
Domain:
Type: String
Description: Private Domain name
Default: int.mydomain.com
VpcId:
Type: AWS::EC2::VPC::Id
Default: vpc-4ac3bb21
AppAmiId:
Type: AWS::EC2::Image::Id
Description: Ec2 AMI ID
Default: ami-XXXX
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Key Name
Default: c3-kp-01
SecurityGroupIds:
Type: CommaDelimitedList
Description: Comma-separated list of existing security group IDs in your VPC
Default: sg-07f5186b
SubnetA:
Description: Subnet from AZ a
Type: String
Default: subnet-7d576316
SubnetB:
Description: Subnet from AZ b
Type: String
Default: subnet-496a0834
SubnetC:
Description: Subnet from AZ c
Type: String
Default: subnet-7d576316
DbSubnetGroupA:
Type: String
Description: Subnet from AZ A
Default: subnet-1154607a
DbSubnetGroupB:
Type: String
Description: Subnet from AZ B
Default: subnet-3d650740
DbSubnetGroupC:
Type: String
Description: Subnet from AZ C
Default: subnet-4d027e00
Resources:
monitoringRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join
- "-"
- - !Ref DclEnvironment
- !Ref DclPod
- !Ref DclService
- "iam-01"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ec2.amazonaws.com
Path: "/"
policyEC2Monitoring:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Join
- "-"
- - !Ref DclEnvironment
- !Ref DclPod
- !Ref DclService
- "policy-01"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:Describe*
Ressource: "*"
- Effect: Allow
Action:
- elasticloadbalancing:Describe*
Ressource: "*"
- Effect: Allow
Action:
- cloudwatch:ListMetrics*
- cloudwatch:GetMetricStatistics
- cloudwatch:Describe*
Ressource: "*"
- Effect: Allow
Action:
- autoscaling:Describe*
Ressource: "*"
Roles:
- !Ref monitoringRole
instanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: !Join
- "-"
- - !Ref DclEnvironment
- !Ref DclPod
- !Ref DclService
- "inp-01"
Path: "/"
Roles:
- !Ref monitoringRole
Hope it helps.
I have A template that creates IAM roles In cloud Formation YAML. I need service Anr in next template, But I am getting this error.
Template contains errors.: Invalid template resource property 'Fn::ImportValue'
IAMStack
Resources:
CodeDeployTrustRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Sid: '1'
Effect: Allow
Principal:
Service:
- codedeploy.us-east-1.amazonaws.com
- codedeploy.us-west-2.amazonaws.com
Action: sts:AssumeRole
Path: "/"
CodeDeployRolePolicies:
Type: AWS::IAM::Policy
Properties:
PolicyName: CodeDeployPolicy
PolicyDocument:
Statement:
- Effect: Allow
Resource:
- "*"
Action:
- ec2:Describe*
- Effect: Allow
Resource:
- "*"
Action:
- autoscaling:CompleteLifecycleAction
- autoscaling:DeleteLifecycleHook
- autoscaling:DescribeLifecycleHooks
- autoscaling:DescribeAutoScalingGroups
- autoscaling:PutLifecycleHook
- autoscaling:RecordLifecycleActionHeartbeat
Roles:
- Ref: CodeDeployTrustRole
InstanceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
InstanceRolePolicies:
Type: AWS::IAM::Policy
Properties:
PolicyName: InstanceRole
PolicyDocument:
Statement:
- Effect: Allow
Action:
- autoscaling:Describe*
- autoscaling:EnterStandby
- autoscaling:ExitStandby
- cloudformation:Describe*
- cloudformation:GetTemplate
- s3:Get*
Resource: "*"
Roles:
- Ref: InstanceRole
InstanceRoleInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- Ref: InstanceRole
Outputs:
CodeDeployServiceRoleARN:
Value:
Fn::GetAtt:
- CodeDeployTrustRole
- Arn
==================================================================================
CodeDeploystack
---
AWSTemplateFormatVersion: '2010-09-09'
Description: This template will create an s3bucket
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: PublicRead
BucketName: CodeDeploy
CodeDeployApplication:
Type: 'AWS::CodeDeploy::Application'
Properties:
ComputePlatform: ec2
DeploymentGroup:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
ApplicationName:
!Ref CodeDeployApplication
Deployment:
Description: First time
IgnoreApplicationStopFailures: true
Revision:
RevisionType: S3
S3Location:
Bucket:
Ref: S3Bucket
ServiceRoleArn:
'Fn::ImportValue': !Sub '${IAMStack}-CodeDeployServiceRoleARN'
Outputs:
S3BucketName:
Value:
Ref: S3Bucket
Description: Name of S3 bucket
I tried rewriting your second template with the import function. Can you try something like this:
AWSTemplateFormatVersion: '2010-09-09'
Description: This template will create an s3bucket
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: PublicRead
BucketName: CodeDeploy
CodeDeployApplication:
Type: "AWS::CodeDeploy::Application"
Properties:
ComputePlatform: ec2
DeploymentGroup:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
ApplicationName: !Ref CodeDeployApplication
Deployment:
Description: First time
IgnoreApplicationStopFailures: true
Revision:
RevisionType: S3
S3Location: !Ref S3Bucket
ServiceRoleArn:
Fn::ImportValue:
Fn::Sub "${IAMStack}-CodeDeployServiceRoleARN"
Outputs:
S3BucketName:
Value: !Ref S3Bucket
Description: Name of S3 bucket
I think some quotes may be off in your version.
Issue fixed, I just change the region
I have turned my original cloudformation stack template into multiple child templates which I then call from a master template. One of the child templates possesses the following snippet, for which I'm getting the error:
An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: Unresolved resource dependencies [GeneralPurposeContainerRole] in the Resources block of the template
BatchResourcesStack (child stack):
---
AWSTemplateFormatVersion: '2010-09-09'
Description: batch resources stack.
Parameters:
GPCEName:
Type: String
GPCEMaxVcpus:
Type: Number
Description: Max number of VCPUs for entire cluster, there are caveats to this
GPCEMinVcpus:
Type: Number
Description: Min number of VCPUs for entire cluster, there are caveats to this
GPCEDesiredVcpus:
Type: Number
Description: Desired number of VCPUs for entire cluster, there are caveats to this
GPCEVpcId:
Type: String
GPCESubnetAZ1:
Type: String
GPCEAmi:
Type: String
GPCEInstanceTypes:
Type: CommaDelimitedList
GPCESSHKeyPair:
Type: String
StackUID:
Type: String
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Subnet:
Type: AWS::EC2::Subnet
Resources:
BatchServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: batch.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole
IamInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref 'EcsInstanceRole'
EcsInstanceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2008-10-17'
Statement:
- Sid: ''
Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
GeneralPurposeContainerRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ecs-tasks.amazonaws.com
Action:
- sts:AssumeRole
Path: '/'
Policies:
- PolicyName: ContainerS3Access
PolicyDocument:
Statement:
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:DeleteObject
- s3:List*
Resource:
# TODO: Make these non psychcore-specific
- arn:aws:s3:::pipeline-validation/*
- arn:aws:s3:::wgs-pipeline-vqsr-test/*
- arn:aws:s3:::test-references/*
- arn:aws:s3:::psychcore-pipelines/output/*
- arn:aws:s3:::psychcore-pipelines/validation/samples/*
- arn:aws:s3:::psychcore-data/reference_indexs/*
- arn:aws:s3:::psychcore-pipelines
- arn:aws:s3:::psychcore-pipelines
- arn:aws:s3:::psychcore-data
- arn:aws:s3:::*
- Effect: Allow
Action:
- s3:List*
- s3:ListMultipartUploadParts
- s3:AbortMultipartUpload
- s3:ListBucketMultipartUploads
Resource:
- arn:aws:s3:::pipeline-validation
- arn:aws:s3:::wgs-pipeline-vqsr-test
- arn:aws:s3:::test-references
- arn:aws:s3:::psychcore-pipelines/output/
- arn:aws:s3:::psychcore-pipelines/validation/samples/
- arn:aws:s3:::psychcore-data/reference_indexs/
- arn:aws:s3:::psychcore-pipelines
- arn:aws:s3:::psychcore-pipelines
- arn:aws:s3:::psychcore-data
- arn:aws:s3:::*
GeneralPurposeComputeEnvironment:
Type: "AWS::Batch::ComputeEnvironment"
Properties:
Type: MANAGED
ComputeEnvironmentName: !Join
- '-'
- - !Ref GPCEName
- !Ref StackUID
ComputeResources:
MinvCpus:
Ref: GPCEMinVcpus
MaxvCpus:
Ref: GPCEMaxVcpus
DesiredvCpus:
Ref: GPCEDesiredVcpus
SecurityGroupIds:
- Ref: SecurityGroup
Subnets:
- Ref: Subnet
Type: 'EC2'
ImageId:
Ref: GPCEAmi
InstanceRole:
Ref: IamInstanceProfile
InstanceTypes:
Ref: GPCEInstanceTypes
Ec2KeyPair:
Ref: GPCESSHKeyPair
Tags:
Key: Name
Value: "VariantCallingBatchComputeEnvironment"
ServiceRole:
Ref: BatchServiceRole
State: ENABLED
DependsOn:
- SecurityGroup
- Subnet
- IamInstanceProfile
- BatchServiceRole
GeneralPurposeQueue:
Type: "AWS::Batch::JobQueue"
Properties:
ComputeEnvironmentOrder:
- Order: 1
ComputeEnvironment: !Ref GeneralPurposeComputeEnvironment
Priority: 1
State: ENABLED
JobQueueName: !Join
- '-'
- - "GeneralPurposeQueue"
- !Ref StackUID
DependsOn:
- GeneralPurposeComputeEnvironment
- BatchServiceRole
Parent.yaml (contains parts relevant to above child stack):
---
AWSTemplateFormatVersion: "2010-09-09"
Description: "Master template for wgs-pipeline. Calls to other stack templates."
Parameters:
GPCEName:
Default: 'GeneralPurposeVariantCallingCE'
Type: String
GPCEMaxVcpus:
Default: 128
Type: Number
Description: Max number of VCPUs for entire cluster, there are caveats to this
GPCEMinVcpus:
Default: 0
Type: Number
Description: Min number of VCPUs for entire cluster, there are caveats to this
GPCEDesiredVcpus:
Default: 0
Type: Number
Description: Desired number of VCPUs for entire cluster, there are caveats to this
GPCEVpcId:
Type: String
GPCESubnetAZ1:
Default: 'us-east-1a'
Type: String
GPCEAmi:
Default: "ami-ce6cdfb4"
Type: String
GPCEInstanceTypes:
Default: "i3.xlarge, i3.2xlarge, i3.4xlarge, i3.8xlarge, i3.16xlarge"
Type: CommaDelimitedList
GPCESSHKeyPair:
Type: String
StackUID:
Default: "1234"
Type: String
Resources:
Subnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: 10.0.0.0/24
VpcId: !Ref 'VPC'
AvailabilityZone: !Ref GPCESubnetAZ1
MapPublicIpOnLaunch: 'True'
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: EC2 Security Group for instances launched in the VPC by Batch
VpcId: !Ref 'VPC'
BatchResourcesStack:
Type: AWS::CloudFormation::Stack
Properties:
Parameters:
GPCEName:
Ref: GPCEName
GPCEMaxVcpus:
Ref: GPCEMaxVcpus
GPCEMinVcpus:
Ref: GPCEMinVcpus
GPCEDesiredVcpus:
Ref: GPCEDesiredVcpus
GPCEVpcId:
Ref: GPCEVpcId
GPCESubnetAZ1:
Ref: GPCESubnetAZ1
GPCEAmi:
Ref: GPCEAmi
GPCEInstanceTypes:
Ref: GPCEInstanceTypes
GPCESSHKeyPair:
Ref: GPCESSHKeyPair
StackUID:
Ref: StackUID
SecurityGroup:
Ref: SecurityGroup
Subnet:
Ref: Subnet
TemplateURL: https://s3.amazonaws.com/CFNTemplate/batch_resources.stack.yaml
Timeout: "100"
I don't understand what the error is specifically pointing to. I put the entire Batch-child.yaml file through a YAML validator and it passed, so it shouldn't be from a formatting/indention error per se. Also, the GeneralPurposeContainerRole resource does not get referenced to anywhere else in the template, nor even in the parent stack template.