CloudformationInterviewQuestions
CloudformationInterviewQuestions
Answer: AWS CloudFormation is an Infrastructure as Code (IaC) service that allows you to model,
provision, and manage AWS and third-party resources by defining them in code. You create a
template that describes all the resources (such as EC2 instances, S3 buckets, VPCs) and
dependencies, and CloudFormation takes care of provisioning and configuring them in a predictable
and repeatable way.
13. How do you ensure your CloudFormation stack does not delete specific
resources during an update or deletion?
Answer: You can use Stack Policies and Deletion Policies:
Stack Policies: Define rules that control which resources can be updated during a stack
update. This prevents certain critical resources from being unintentionally modified.
Deletion Policies: Use Retain, Snapshot, or Delete as part of a resource’s
configuration. For example, setting Retain ensures that a resource will not be deleted
when the stack is deleted.
Parameters:
DBUsername:
Type: String
Description: Username for the database
DBPasswordParameter:
Type: AWS::SSM::Parameter::Value<SecureString>
Description: SSM Parameter Store key for the database password
Resources:
MyDBInstance:
Type: "AWS::RDS::DBInstance"
Properties:
DBName: "MyDatabase"
Engine: "mysql"
MasterUsername: !Ref DBUsername
MasterUserPassword: !Ref DBPasswordParameter
DBInstanceClass: "db.t2.micro"
AllocatedStorage: "20"
StorageType: "gp2"
Outputs:
DBInstanceEndpoint:
Description: Endpoint for the created RDS instance.
Value: !GetAtt MyDBInstance.Endpoint.Address
DBInstancePort:
Description: Port for the created RDS instance.
Value: !GetAtt MyDBInstance.Endpoint.Port
Explanation:
1. Parameters Section:
DBUsername: Accepts the database username as a standard string parameter.
DBPasswordParameter: Specifies a SecureString parameter from the SSM
Parameter Store. This is an encrypted value in the Parameter Store, ensuring that the
password is never exposed in plaintext within the template.
2. SSM SecureString:
When creating the SSM parameter, ensure it’s of type SecureString. For
example, you can store it using the AWS CLI:
aws ssm put-parameter --name "my-database-password" --value "yourpassword" --type
"SecureString"
1. Resource Section:
MyDBInstance: Creates an RDS instance using the MasterUsername and
MasterUserPassword. The password is securely fetched from the SSM
Parameter Store.
2. Benefits:
The password remains securely encrypted in the Parameter Store.
There is no plaintext exposure of the sensitive information in the template or the
CloudFormation console.
The use of AWS::SSM::Parameter::Value<SecureString> ensures that
CloudFormation retrieves the encrypted parameter without exposing it.
Additional Tips:
You can also use AWS Secrets Manager to manage sensitive information. When using
Secrets Manager, you can reference the secret in your CloudFormation template using the
AWS::SecretsManager::Secret resource.
Ensure IAM permissions are set up correctly so that CloudFormation can access the SSM
parameters or Secrets Manager secrets during stack creation and updates.
1. Can you define custom macros with the Transform function? Answer: Yes, you can
create custom macros using AWS Lambda functions to extend CloudFormation's
functionality. By defining a custom macro, you can manipulate and process the
CloudFormation template before it is executed. This allows for greater flexibility, such as
adding custom logic or generating resources dynamically.
2. What are some benefits of using AWS SAM with the Transform function? Answer:
AWS SAM simplifies the process of creating and managing serverless applications by
providing shorthand resource definitions for common services like Lambda, API Gateway,
and DynamoDB. It reduces boilerplate code, speeds up development, and provides tools like
sam-cli to build, test, and deploy serverless applications.
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: >
Example of using Transform in CloudFormation to deploy a serverless application with AWS
SAM
Resources:
HelloWorldFunction:
Type: 'AWS::Serverless::Function'
Properties:
Handler: index.handler
Runtime: nodejs18.x
CodeUri: s3://my-bucket/lambda/helloworld.zip
Events:
HelloWorldAPI:
Type: Api
Properties:
Path: /hello
Method: get
Outputs:
LambdaFunction:
Description: ARN of the Lambda function
Value: !GetAtt HelloWorldFunction.Arn
ApiGatewayUrl:
Description: URL of the API Gateway endpoint
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/
hello"
Explanation:
1. Transform Section:
The Transform function uses AWS::Serverless-2016-10-31 to indicate
that this template will be processed as an AWS SAM template. This allows the
shorthand syntax for defining serverless resources.
2. Resources:
HelloWorldFunction: A Lambda function is defined with a minimal set of
properties. The Events section specifies that this Lambda function will be triggered
by an HTTP GET request to /hello, automatically creating an API Gateway.
Handler and Runtime: Define how the Lambda function runs.
CodeUri: Points to the location of the Lambda function code in an S3 bucket.
3. Outputs:
LambdaFunction: Exposes the ARN of the deployed Lambda function.
ApiGatewayUrl: Constructs the URL for the API Gateway endpoint using
CloudFormation intrinsic functions.
Benefits:
The template is concise and easier to read compared to traditional CloudFormation
definitions.
You don’t need to manually define all the components of the serverless stack; SAM handles
it automatically.
You can test, build, and deploy this serverless application using AWS SAM CLI, simplifying
the development process.
This example showcases how the Transform function can make creating serverless applications
more efficient, reducing the need for verbose configuration, and offering a streamlined approach to
infrastructur
Parameters:
VPCID:
Type: String
Description: "VPC ID"
SubnetID:
Type: String
Description: "Subnet ID"
KeyName:
Type: String
Description: "Name of an existing EC2 KeyPair to enable SSH access"
Resources:
MyEC2Instance:
Type: "AWS::EC2::Instance"
Properties:
InstanceType: "t2.micro"
KeyName: !Ref KeyName
SubnetId: !Ref SubnetID
ImageId: "ami-0c55b159cbfafe1f0" # Example Amazon Linux 2 AMI
SecurityGroupIds:
- !Ref InstanceSecurityGroup
Tags:
- Key: Name
Value: MyEC2Instance
InstanceSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "Enable SSH access via port 22"
VpcId: !Ref VPCID
SecurityGroupIngress:
- IpProtocol: "tcp"
FromPort: 22
ToPort: 22
CidrIp: "0.0.0.0/0"
Resources:
S3Bucket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: "my-versioned-encrypted-bucket"
VersioningConfiguration:
Status: "Enabled"
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: "AES256"
Outputs:
S3BucketName:
Value: !Ref S3Bucket
Description: "Name of the S3 bucket"
Resources:
MyIAMRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: "ec2.amazonaws.com"
Action: "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: "S3EC2AccessPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "s3:*"
Resource: "*"
- Effect: Allow
Action:
- "ec2:*"
Resource: "*"
InstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Roles:
- !Ref MyIAMRole
Path: "/"
Outputs:
IAMRoleName:
Value: !Ref MyIAMRole
Description: "Name of the created IAM role"
Resources:
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: "10.0.0.0/16"
EnableDnsSupport: "true"
EnableDnsHostnames: "true"
Tags:
- Key: Name
Value: MyVPC
PublicSubnet:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref VPC
CidrBlock: "10.0.1.0/24"
MapPublicIpOnLaunch: true
AvailabilityZone: !Select [ 0, !GetAZs ]
PrivateSubnet:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref VPC
CidrBlock: "10.0.2.0/24"
AvailabilityZone: !Select [ 0, !GetAZs ]
InternetGateway:
Type: "AWS::EC2::InternetGateway"
AttachGateway:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
PublicRoute:
Type: "AWS::EC2::Route"
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
NATGateway:
Type: "AWS::EC2::NatGateway"
Properties:
SubnetId: !Ref PublicSubnet
AllocationId: !GetAtt EIP.AllocationId
EIP:
Type: "AWS::EC2::EIP"
PrivateRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
PrivateRoute:
Type: "AWS::EC2::Route"
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref NATGateway
PrivateSubnetRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref PrivateRouteTable
Parameters:
DBInstanceIdentifier:
Type: String
Default: "my-postgresql-db"
DBUsername:
Type: String
Default: "admin"
DBPassword:
Type: String
NoEcho: true
Resources:
MyDBInstance:
Type: "AWS::RDS::DBInstance"
Properties:
DBInstanceIdentifier: !Ref DBInstanceIdentifier
AllocatedStorage: 20
DBInstanceClass: "db.t2.micro"
Engine: "postgres"
MasterUsername: !Ref DBUsername
MasterUserPassword: !Ref DBPassword
DBSubnetGroupName: !Ref DBSubnetGroup
DBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupDescription: "Subnet group for RDS instance"
SubnetIds:
- subnet-12345678
- subnet-87654321
Outputs:
RDSInstanceEndpoint:
Value: !GetAtt MyDBInstance.Endpoint.Address
Description: "PostgreSQL database endpoint"
Parameters:
VPC:
Type: String
Description: "VPC ID"
Subnets:
Type: List<AWS::EC2::Subnet::Id>
Description: "List of Subnet IDs"
ClusterName:
Type: String
Default: "MyECSCluster"
Description: "ECS Cluster name"
DesiredCount:
Type: Number
Default: 2
Description: "Desired number of ECS tasks"
ImageUrl:
Type: String
Default: "nginx"
Description: "Docker image URL for the ECS tasks"
ContainerPort:
Type: Number
Default: 80
Description: "Port on which the container will listen"
CPU:
Type: String
Default: "256"
Description: "Fargate task CPU units"
Memory:
Type: String
Default: "512"
Description: "Fargate task memory in MiB"
Resources:
# ECS Cluster
ECSCluster:
Type: "AWS::ECS::Cluster"
Properties:
ClusterName: !Ref ClusterName
# ALB Listener
ALBListener:
Type: "AWS::ElasticLoadBalancingV2::Listener"
Properties:
DefaultActions:
- Type: "forward"
TargetGroupArn: !Ref ALBTargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
# ECS Task Definition
ECSTaskDefinition:
Type: "AWS::ECS::TaskDefinition"
Properties:
Family: "MyFargateTask"
Cpu: !Ref CPU
Memory: !Ref Memory
NetworkMode: "awsvpc"
RequiresCompatibilities:
- "FARGATE"
ExecutionRoleArn: !GetAtt ECSRole.Arn
TaskRoleArn: !GetAtt ECSRole.Arn
ContainerDefinitions:
- Name: "nginx"
Image: !Ref ImageUrl
PortMappings:
- ContainerPort: !Ref ContainerPort
Protocol: "tcp"
Explanation:
Parameters: The template uses parameters like VPC, Subnets, ClusterName,
DesiredCount, ImageUrl, ContainerPort, CPU, and Memory to make the
template customizable.
Resources:
ECS Cluster: An ECS Cluster named MyECSCluster is created.
ALB: An internet-facing Application Load Balancer (ALB) is set up to distribute
incoming traffic.
Target Group: A target group is created for routing traffic to the ECS Fargate tasks.
ALB Listener: The ALB Listener listens on port 80 (HTTP).
ECS Task Definition: Defines an ECS Fargate task using the Docker image
specified (default: nginx).
ECS Fargate Service: Deploys an ECS service with tasks running on the Fargate
launch type.
IAM Role: Grants ECS tasks permissions to interact with AWS services like ECR
and CloudWatch Logs.
Outputs: The template outputs the DNS name of the load balancer, which is useful to access
the deployed service.