
Looking for Senior AWS Serverless Architects & Engineers?
Let's TalkIn this article, we are going to take an AWS CloudFormation file written in JSON and then convert that file to YAML format.
Luckily, AWS has a way to do this for us which is super easy.
Steps
Login to your AWS account

Navigate to AWS CloudFormation

Select “Design Template”

Click “Template” at the bottom

Paste in the following CloudFormation template
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Example Stack, version 2.2.2.0",
"Parameters": {
"Stages": {
"Type": "String",
"AllowedValues": [
"dev",
"test",
"prod",
"qa"
],
"Default": "dev",
"Description": "Multi-stage support"
}
},
"Mappings": {
"TrueFalse": {
"Yes": {
"Value": "True"
},
"No": {
"Value": "False"
}
}
},
"Resources": {
"MyPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "MyPolicy",
"Roles": [
{
"Ref": "MyRole"
}
],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchWriteItem"
],
"Resource": [
{
"Fn::Join": [
"",
[
{
"Fn::Join": [
":",
[
"arn:aws:dynamodb",
{
"Ref": "AWS::Region"
},
{
"Ref": "AWS::AccountId"
},
"table/"
]
]
},
{
"Ref": "MyTable"
}
]
]
}
]
}
]
}
}
},
"MyRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"Path": "/"
}
},
"MyTable": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": "1",
"WriteCapacityUnits": "1"
}
}
}
},
"Outputs": {
"AccountId": {
"Value": {
"Ref": "AWS::AccountId"
},
"Description": "AWS Account Id"
},
"MyTableName": {
"Value": {
"Ref": "MyTable"
},
"Description": "Name of the DynomoDB Table",
"Export": {
"Name": {
"Fn::Join": [
":",
[
{
"Ref": "AWS::StackName"
},
"MyTableName"
]
]
}
}
},
"MyTableArn": {
"Value": {
"Fn::GetAtt": [
"MyTable",
"Arn"
]
},
"Description": "Arn of the DynomoDB Table",
"Export": {
"Name": {
"Fn::Join": [
":",
[
{
"Ref": "AWS::StackName"
},
"MyTableArn"
]
]
}
}
}
}
}
Select “YAML”

Boom! Now copy the converted YAML and fly away into the sunset 🌄 👋
AWSTemplateFormatVersion: 2010-09-09
Description: 'Example stack, version 2.2.2.0'
Parameters:
Stages:
Type: String
AllowedValues:
- dev
- test
- prod
- qa
Default: dev
Description: Multi-stage support
Mappings:
TrueFalse:
'Yes':
Value: 'True'
'No':
Value: 'False'
Resources:
MyPolicy:
Type: 'AWS::IAM::Policy'
Properties:
PolicyName: MyPolicy
Roles:
- !Ref MyRole
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: '*'
- Effect: Allow
Action:
- 'ec2:*'
Resource:
- '*'
- Effect: Allow
Action:
- 'dynamodb:DeleteItem'
- 'dynamodb:GetItem'
- 'dynamodb:PutItem'
- 'dynamodb:Query'
- 'dynamodb:Scan'
- 'dynamodb:BatchWriteItem'
Resource:
- !Join
- ''
- - !Join
- ':'
- - 'arn:aws:dynamodb'
- !Ref 'AWS::Region'
- !Ref 'AWS::AccountId'
- table/
- !Ref MyTable
MyRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: 'sts:AssumeRole'
Path: /
MyTable:
Type: 'AWS::DynamoDB::Table'
Properties:
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: '1'
WriteCapacityUnits: '1'
Outputs:
AccountId:
Value: !Ref 'AWS::AccountId'
Description: AWS Account Id
MyTableName:
Value: !Ref MyTable
Description: Name of the DynomoDB Table
Export:
Name: !Join
- ':'
- - !Ref 'AWS::StackName'
- MyTableName
MyTableArn:
Value: !GetAtt
- MyTable
- Arn
Description: Arn of the DynomoDB Table
Export:
Name: !Join
- ':'
- - !Ref 'AWS::StackName'
- MyTableArn
Now doesn’t that look much cleaner? The final recommendation, don’t upload AWS Cloudformation directly through the AWS console, use a deployment framework such as the Serverless Framework to make your IAC (Infrastructure as Code) even cleaner.