Cloudformation fails with 'failed validation constraint for keyword [pattern]' - amazon-web-services

I am trying to create a Workflow object using AWS CloudFormation. This workflow will be used with AWS File Transfer Family so that files get copied to S3 upon uploading.
AWSTemplateFormatVersion: "2010-09-09"
Resources:
SftpToS3Workflow:
Type: AWS::Transfer::Workflow
Properties:
Description: 'Workflow used by AWS File Transfer Family. Copies the files to S3'
Steps:
- Type: COPY
CopyStepDetails:
Name: copt-to-s3-wf-step
DestinationFileLocation:
S3FileLocation:
Bucket: !ImportValue GenesysS3BucketName
Key: "genesys/"
OverwriteExisting: 'TRUE'
Outputs:
SftpToS3WorkflowId:
Description: 'Id of the Workflow'
Value: !GetAtt SftpToS3Workflow.WorkflowId
Export:
Name: SftpToS3WorkflowId
Unfortunately, this script fails with the below error. The error does not say what property is failing validation. Can someone help, please? I could not find even one single example on GitHub.
Properties validation failed for resource SftpToS3Workflow with message: #/Description: failed validation constraint for keyword [pattern]
I have used this CloudFormation schema to write the code:
https://github.com/APIs-guru/openapi-directory/blob/0380216a44c364b4517b31a93295089a6f4f23b9/APIs/amazonaws.com/transfer/2018-11-05/openapi.yaml

The Description can only be
^[\w- ]*$
So it should be:
Description: 'Workflow used by AWS File Transfer Family - Copies the files to S3'

Related

AWS Cloudformation Codecommit S3 400 Exception

I have created a cloudformation template which creates a new repo in codecommit,Also it need to pull the source.zip from S3 and copy it to the repo. but while running the template i see 400 bad request.
CF template:
AWSTemplateFormatVersion: 2010-09-09
Description: my First code commit CF template
Parameters:
DemoBucket:
Type: String
Description: Bucket in which you have code
Default: jaivijaycccf
DemoKey:
Type: String
Description: key of zipped code
Default: demo.zip
Resources:
HelloWorld:
Type: AWS::CodeCommit::Repository
Properties:
RepositoryName: HelloWorldApp
RepositoryDescription: This is a repository for my project with code from MySourceCodeBucket
Code:
BranchName: development
S3:
Bucket: !Ref DemoBucket
Key: !Ref DemoKey
ObjectVersion: 1
If the S3 bucket that is storing the source code does not use Object Versioning then providing the ObjectVersion paramater to the Cloudformation template will cause it to fail.
Removing the unnecessary parameter will fix the problem.
I'm adding this as an answer after you've confirmed that you aren't using object versioning.

Expose SNSTopic TopicArn in AWS CloudFormation Template: How might I expose my TopicArn in my CloudFormation script for my SNS Topic?

I'd like to expose the TopicArn Value (referenced in the outputs section at the bottom of my code snippet) of my SNStopic via Cloudformation template in the outputs tab of my stack in a similar manner to the way it's exposed in the resources when I create an SNStopic through the service catalog. I tried to access it by referencing it in the outputs section of my yaml script using dot notation but have been unsuccessful thus far. How might I be able to do so? I'm looking to do this so others using my script in the future won't have to go searching for the TopicArn in another place in order to subscribe to it.
Another important thing to note is that the provisioned product id below, under the properties section of the resources code block generates an SNSTopic.
Resources:
LabTrainingSnsTopic:
Type: "AWS::ServiceCatalog::CloudFormationProvisionedProduct"
Properties:
ProductId: prod-4iafsjovqrsrm # Sns Topic
ProvisioningArtifactName: "v1.1" # Must be an actual version number.
ProvisionedProductName: !Ref ProvisionedProductName
...
Outputs:
AccountID:
Description: The account in which this was built.
Value: !Ref 'AWS::AccountId'
TopicArn:
Description: Arn of the topic we created
Value: !GetAtt LabTrainingHigSnsTopic.ProvisionedProductName.Resources.SNSTopic
service catalog screenshot
cloudformation screenshot

Can AWS CloudFormation resources call !GetAtt on themselves?

I am trying to set up the Inventory configuration for an S3 bucket with CloudFormation. I want to get daily inventories of data in one subfolder, and have the inventories written to a different subfolder in the same bucket. I have defined the bucket as follows:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
# ...other properties...
InventoryConfigurations:
- Id: runs
Enabled: true
Destination:
BucketAccountId: !Ref AWS::AccountId
BucketArn: !GetAtt S3Bucket.Arn
Format: CSV
Prefix: inventory/runs/
IncludedObjectVersions: Current
OptionalFields: [ETag, Size, BucketKeyStatus]
Prefix: runs/
ScheduleFrequency: Daily
Unfortunately, the !GetAtt S3Bucket.Arn line seems to be failing, causing an error message like "Error: Failed to create changeset for the stack: , ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state: For expression "Status" we matched expected path: "FAILED" Status: FAILED. Reason: Circular dependency between resource". If I use the actual ARN of the bucket in place of !GetAtt S3Bucket.Arn (it already exists from a previous version of the stack), then the deploy succeeds, so I know buckets can write Inventories to themselves.
So I guess my question is, is there a way to let Cfn resources call !GetAtt on themselves, so I don't have to hard-code the bucket ARN in InventoryConfigurations? Thanks in advance!
Can AWS CloudFormation resources call !GetAtt on themselves?
Unfortunately no, as the !GetAtt is used to reference other resources in the stack as you've experienced (other as in concrete resources that have already been created).
However, in your case, considering you know the bucket name, you could just construct the bucket ARN yourself directly.
Format:
arn:aws:s3:::bucket_name
e.g. if the name is test, you can use arn:aws:s3:::test
Destination:
BucketAccountId: !Ref AWS::AccountId
BucketArn: 'arn:aws:s3:::test'

How to get the ssm parameter to a yaml file?

I have a yaml cloud formation file which requires a variable stored in ssm parameter. The yaml file is a CFT template. Below is the sample code,
AWSTemplateFormatVersion: 2010-09-09
Description: 'Fully Automated OT Archival Data Migration'
Parameters:
Environment:
Description: 'Stage type (for Tags)'
Type: String
Default: dev
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: '{{resolve:ssm:/opentext/config/automated-ot-archival-data-migration/migration.bucket.name:1}}-${Environment}'
When I upload the code to cloudformation in AWS console, I results with an error. I'm wondering whether the ssm param reference is correct or not.
Please let me know if you find any issues here.
Thanks
You are missing the !Sub function for your {Environment} variable.
BucketName: !Sub '{{resolve:ssm:/opentext/config/automated-ot-archival-data-migration/migration.bucket.name:1}}-${Environment}'

Serverless: Deplyment error S3 Bucket already exists in stack

I am trying to deploy a serverless project which has s3 bucket creation cloudformation in the serverless.yml file, but the problem is when I tried to deploy, it says the s3 bucket already exists and failing the deployment.
I know s3 bucket name should be globally unique, and I am damn sure it is a unique name that I am using, even if changed to something else, it still says the same.
the cloudformation stack it says the s3 bucket exists is actually the newly created stack, not sure how to fix this issue. can anyone help me out with this issue and tell me how to fix the deployment issue and the cause for the issue :).
Thanks in advance.
The issue I had was, for one of the lambdas I had the above-mentioned bucket as the event source, so when some bucket is added as event source it actually creating that bucket as well, therefore when it runs the actual creation related cloudformation it is saying the bucket already exists.
So I fixed it by only keeping the event source and removed the actual declaration of that bucket.
If you add existing: true to the S3 config in your serverless.yml file it won't try to create the S3 bucket like the below:-
funcName:
handler: handler
events:
- s3:
bucket: 'my-bucket-name'
events: s3:ObjectCreated:*
existing: true
rules:
- suffix: .pdf
- prefix: documents
Anything involving CloudFormation (or any other infrastructure-in-code) is fussy, and the error messages can mislead, meaning there are a ton of things that can cause this problem (see issues on GitHub like this one).
But in my experience, the most common causes of these kind of problems are are not the pre-existing bucket, but problems with AWS credentials, permissions, or region that give misleading error messages. To fix these, or at least rule them out:
Make sure your serveless.yml is set to the region you already deployed the stack in. Example:
custom:
stage: dev
region: us-east-2
Override any latent credentials from, for example, ~/.aws/credentials, by explicitly setting your credentials in the shell you'll use to deploy. Example from the Serverless docs:
export AWS_ACCESS_KEY_ID=<your access key here>
export AWS_SECRET_ACCESS_KEY=<your access secret here.
Make sure those AWS credentials have the roles and permissions they need.
But, as I mentioned, CloudFormation is fussy. There may be other problems to solve, but try these first. You may try them and still be beating your head against the wall, but it'll more likely be the right wall. Hope this helps.
Try to use Conditional statements and pass them as a Parameter to create the bucket or not
AWSTemplateFormatVersion: 2010-09-09
Parameters:
EnvType:
Description: Environment type.
Default: test
Type: String
AllowedValues:
- prod
- test
ConstraintDescription: must specify prod or test.
Conditions:
CreateProdResources: !Equals
- !Ref EnvType
- prod
Resources:
EC2Instance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: ami-0ff8a91507f77f867
MountPoint:
Type: 'AWS::EC2::VolumeAttachment'
Condition: CreateProdResources
Properties:
InstanceId: !Ref EC2Instance
VolumeId: !Ref NewVolume
Device: /dev/sdh
NewVolume:
Type: 'AWS::EC2::Volume'
Condition: CreateProdResources
Properties:
Size: 100
AvailabilityZone: !GetAtt
- EC2Instance
- AvailabilityZone
Follow the sample condition flow to decide wheather to create a resource or not.
See this for more details
When deploying, the BucketName must be unique across all regions. So if anyone has already created a bucket with "local-bucket-dev," it will throw
An error occurred: AttachmentsBucket - local-bucket-dev already
exists.
Try to just the BucketName to be unique.
I hope that helps.