AWS CloudFormation Exercise 1: EC2 Instance creation

Exercise 1: Cloud Formation Template for EC2 Instance with Apache UserData

In This Exercise, we are going to create EC2 Instance using the Cloud Formation Template written in YAML format. For this exercise, we need to keep few things ready.
1.   VPC (Default or Custom)
2.   Public Subnets
3.   Security Groups
4.   KeyPair
We are going to create EC2 Instance in Mumbai Region (ap-south-1), so we have used image-id “ami-0732b62d310b80e97”, we have already created KeyPair separately to access our instance, the security group is configured with Port 22 and 80 inbound, the subnet we are using here is ap-south-1a.

To get the Stack click on the link: https://github.com/pranavdhopey and save it to server say under /opt directory.

1.   Login to AWS Management Console. AWS Console

2.   On Management Console click on “Cloud Formation” under the “Management and Governance” section. 

3.   Now you will land on Cloud Formation Console. In Cloud Formation Console
click on the “Create Stack” button.

Now follow the below steps to create a stack for this exercise.

Step 1: Specify template

In this section choose the “Template is Ready” button and select “Upload a template file”. Now choose a file to upload from your personal computer where it is saved and upload. Now click on next.

Step 2: Specify stack details

Now Specify “Stack name” for e.g. Say “EC2Stack” for this exercise. Now provide the values for parameters need to create EC2 stack, here we are giving the below parameter values.

1. MyInstanceType: t2.micro(Choose From DropDown)
2. MyKeyName: MumbaiKP(Provide your KeyPair Name)
3. MyAvailabilityZone: ap-south-1a(Value to be replace)
4. MySubnetId: subnet-xxxxxxxxxx(Value to be replace)
6. MySecurityGroups: sg-xxxxxxxxxx(Value to be replace)

Step 3: Configure stack options

On the “Configure stack options” page leave all settings default and click on next.

Step 4: Review Stack

In this step review all the settings that you have filled in and click on create stack.

After some time stack will be created and you can view and access resources created by the cloud formation stack.

Click below to get started:

Create Stack

We can also create a stack using AWS CLI.

AWS CLI for creating stack:

1.   To validate cloudformation template template

#aws cloudformation validate-template --template-body file://<path-to-file>/CFNTemplatesWithApacheUserData.yml


2.   To create stack

#aws cloudformation create-stack --stack-name EC2Stack1 --template-body

file://<path-to-file>/CFNTemplatesWithApacheUserData.yml --parameters

ParameterKey=MyKeyName,ParameterValue=MumbaiKP

ParameterKey=MyInstanceType,ParameterValue=t2.micro

ParameterKey=MyAvailabilityZone,ParameterValue=ap-south-1a

ParameterKey=MySecurityGroups,ParameterValue=sg-xxxxxxxxxx

ParameterKey=MySubnetId,ParameterValue=subnet-xxxxxxxxxx

3.   To describe stack
#aws cloudformation describe-stacks --stack-name EC2Stack

4.   To view the stack events
#aws cloudformation describe-stack-events --stack-name EC2Stack


5.   To delete the stack

#aws cloudformation delete-stack --stack-name EC2Stack

This completes EC2 instance creation using a cloud formation stack with various parameters. 

Docker Interview Questions: Part 2

Q) How to keep the container alive, even when Docker Daemon is down?
By default, when the Docker daemon terminates, it shuts down running containers. You can configure the daemon so that containers remain running if the daemon becomes unavailable. This functionality is called live restore. The live restore option helps reduce container downtime due to daemon crashes, planned outages, or upgrades.
 
Add the configuration to the daemon configuration file. On Linux, this defaults to /etc/docker/daemon.json
{
  "live-restore": true
}
Ref Link: https://docs.docker.com/config/containers/live-restore/

Q) How to view the log for the last one hrs, logs for a particular date, tail the log of the container continuously?
To view log for last 1hr: # docker logs --since 1h <container-id>
To view log for particular date: #docker logs --until yyyy-mm-ddThh:mm:ss <container-id>         
To view log continuously:   #docker logs --follow <container-id>

Q) How to get the IP address and gateway details of the container?
#docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container-id>
#docker inspect --format '{{ .NetworkSettings.Gateway }}' <container-id>
#docker inspect <container-id>|grep –wm1 "IPAddress"| cut -d '"' -f4
#docker inspect <container-id>|grep –wm1 "Gateway"| cut -d '"' -f4

Q) Explain the below command, their difference and purpose
#docker run -d --read-only -it --tmpfs /app/tmp voiptempdata

Above command will run container with read-only root file system and tmpfs mount on target directory “/app/tmp“. You can write to the directory as tmpfs creates file outside containers writeable layer. 
The --tmpfs flag does not allow you to specify any configurable options.
The --tmpfs flag cannot be used with swarm services. Its is for standalone
container. 

#docker run -d -it --name voiptempdata --mount type=tmpfs,destination=/app/tmp voipasterix

Above command will run container named “voiptempdata” with tmpfs mount on
target directory “/app/tmp“
The --mount flag allow you to specify any configurable options.It consists of
multiple key-value pairs, separated by commas.
The --mount flag is compatible with swarm services.

Ref Link: https://docs.docker.com/storage/tmpfs

Q) What is the use of tmpfs mount and where it resides? Is it possible to share them between containers?
When you don’t want to store the container’s data on the host machine and also don’t want to write data into the container's writable layer then you can use tmpfs mount option for the container.
This is useful to temporarily store sensitive files that you don’t want to persist in either the host or the container writable layer.
tmpfs mount is temporary and only persisted in the host memory. When the container stops, the tmpfs mount is removed, and files are written there won’t be persisted.
you can't share tmpfs mounts between containers.

Ref Link: http://docs.docker.oeynet.com/engine/admin/volumes/tmpfs/

Q) When to use Volume and When to use Bind Mounts?
Docker provides two options for the container to store their data on the host machine, so that data can be persisted even after the container stops and those are
Volume mounts and Bind mounts
Volumes are stored in a part of the host filesystem which is managed by Docker. The non-Docker process on Docker hosts can not modify this part of the filesystem.
Bind mounts may be stored anywhere on the host system. The non-Docker process on Docker host or docker container can modify them at any time.
The use of Volume and Bind mounts depends on your application requirements. If you want that everything should be managed by docker then use volume mount and if you want to use your own directory structure managed by you then use bind mount.
As the bind mount depends on the directory structure of the host machine, it has the potential of failure where as volume mount is managed by docker there is no chance of failure. 

Ref Link: http://docs.docker.oeynet.com/engine/admin/volumes/#choose-the-right-type-of-mount

Q) Explain the below commands and their purpose
#docker run -it –name voip1 -v voipdata:/datav voipserver

The above command will run a container with a volume that does not exist. In this case, a volume “voipdata” will be created and mounted on “/datav” inside container filesystem named “voip1”.

#docker run -it –name voip2 --volumes-from voip1 voipserver

The above command will run a container with a volume referenced from another container. In this case, a volume that is referenced from “voip1” will be mounted inside the container filesystem named “voip2”.

Ref Link: https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from

Q) How to run the containers only on manager node?
#docker service create --replicas=3 --constraint="node.role==manager" <image>

Q) Write a sample services section in Docker compose file for 3 replicas, worker node role and to restart on failure?
 
version: "3.8"
services:
  web:
    image: httpd:alpine
    ports:
      - 80:80
    deploy:
      placement:
        constraints:
          - "node.role==worker"
      mode: replicated
      replicas: 3
      restart_policy:
        condition: on-failure

Q) What are the types of logging driver available for docker? What is the default one and how to limit size of the log file?
There are different logging drivers available for docker, like none, local, json-file, syslog, journal etc. Below is the link for supported logging driver in docker.
supported-logging-drivers
 
The default logging driver of Docker for Linux distributions is “json-file”.

To limit size of log file set “max-size” value in “log-opts” configuration options in the daemon.json
 
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m"
      }
}

Q) What is difference between below commands?
CMD [“/appboot.sh”] à This form is know as exec form of CMD,in this the <command> is expressed as JSON array.
CMD /appboot.sh  à This form is know as shell form of CMD,in this the <command> will execute in “/bin/sh -c “
 
Ref Link: https://docs.docker.com/engine/reference/builder/#cmd

Docker Command Line / Docker Cheat Sheet

########## Docker ########## 

## To pull the image from registry

docker pull <registry>/<repository>:<tag>
docker pull docker.io/busybox:latest

## To list images on the host machine

docker image ls
docker images

## To run container in detached mode 

docker container run --detach --name <name-to-container> <container-name>
docker container run -d --name <name-to-container>  <container-name>

## To run container in interactive mode 

docker container run --tty --interactive --name <name-to-container> <container-name>
docker container run -it --name <name-to-container> <container-name>

## To execute comand on running container

docker container exec --tty --interactive  <name-to-container> <cmd-to-run>
docker container exec -it <name-to-container> <cmd-to-run>

## To inspect docker container

docker container inspect <container-name>

## To list running containers 

docker container ls

## To list all the containers including running, exited 

docker ps 
docker ps -a
docker container ls -a
docker container ls -all

## To list all the containers with exit statue 

docker ps -a --filter "status=exited"
docker container ls -a --filter "status=exited"

## To list all the containers with running status 

docker ps --filter status=running
docker container ls --filter status=running

## To list container id's 

docker container ls --all --quiet
docker container ls -a -q

## To check the stats  

docker container stats <container-id>

## To check the logs

docker container logs <container-id>

## To check process running inside container

docker container top <container-id>

## To check disk space that docker is using

docker system df

## To remove stopped containers, unused volumes, networks, and dangling images

docker system prune

## To remove dangling images

docker image prune

## To remove stopped containers

docker container prune

## To List all networks

docker network ls 

## To create network

docker network create <network-name>
docker network create -d <driver> <network-name>  
docker network create --driver <driver> <network-name> 

## To display detailed information of network

docker network inspect <network-name> 

## List port mappings for the container

docker container port <container-id>

## To Remove one or more networks

docker network rm <network-name>

## Create volume

docker volume create <vol-name>

## Bind Mount local directory to container 

docker container run --mount type=bind,source=<source-path>,target=<target-path> <image-name>
docker container run -v <source-path>:<target-path> <image-name>

## Mount local directory to container 

docker container run --mount type=volume,source=<vol-name>,target=<target-path> <image-name>
docker container run -v <vol-name>:<target-path> <image-name>

## To run container with restart policy

docker container run -d --restart always <image-name>
docker container run -d --restart on-failure <image-name>
docker container run -d --restart unless-stopped <image-name>

## To create docker secret

echo "<secret>" | docker secret create <my_secret> -
echo "pass123" | docker secret create db_pass -

## To create docker secret using file

docker secret create <my_secret> <file-name>
docker secret create db_pass pass-file.txt

## To list the secrets in docker

docker secret ls

## To inspect secret

docker secret inspect <my_secret>
docker secret inspect db_pass

## To removes a secret

docker secret rm <my_secret>
docker secret rm db_pass


########## DOCKER COMPOSE ##########

## To create and start the container 

docker-compose up

## To create and start the container in detached mode

docker-compose up --detach
docker-compose up -d

## To List all the containers

docker-compose ps

## To Display services

docker-compose ps --services

## To scale particular service in docker-compose

docker-compose up --detach --scale <service-name>=<count>

## Stops containers and removes containers, networks, volumes, and images created 

docker-compose down

## To Validate and view the Compose file

docker-compose config

##List images used by the created containers

docker-compose images

## To view logs output from services

docker-compose logs
docker-compose logs --tail=10

## To stop running containers without removing them

docker-compose stop

## To start running containers for service

docker-compose start

## Displays the running processes

docker-compose top


########## DOCKER SWARM ##########

## To initialize swarm mode 

docker swarm init --advertise-addr <IP-Address> 

## To create Token for Worker/Manager

docker swarm join-token worker
docker swarm join-token manager

## To list swarm nodes in the cluster

docker node ls

## To leave worker node from the swarm

docker swarm leave

## To remove worker node from the swarm

docker node rm <node-name>

## To promote node to worker

docker node promote <node-name>

## To demote node to worker

docker node demote <node-name>

## To update role of node 

docker node update --role <manager|worker> <node-name>

## To create service 3 replicas 

docker service create --name <service-name> --replicas <no-of-replicas> <image-name>
docker service create --name web-server --replicas 3 nginx:latest

## To adds a published service port to an existing service

docker service update --publish-add published=<hport>,target=<cport> <service-name>
docker service update --publish-add published=8080,target=80 web-server

## To update no. of replicas 

docker service update --replicas=<count> <service-name>
docker service update --replicas=3 web-server

## To check status of running service

docker service ps <service-name>
docker service ps web-service

## To check logs of service

docker service logs <service-name>
docker service logs web-server

## To scale replicas of service

docker service scale <service-name>=<no-of-replicas>
docker service scale web-server=6

## To run one task for the service on every available node in the cluster

docker service create --name <service-name> mode=global <image-name>
docker service create --name web-server mode=global busybox

## To update service to use new docker image

docker service update --image <new-image> <service-name>
docker service update --image nginx:alpine web-server

## To create service on Manager Node only

docker service create --constraint="node.role==manager" <image-name>

## To create service on Worker Node only

docker service create --constraint="node.role==worker" <image-name>


AWS Command Line Example to configure VPC

Tasks to perform:

1. Create VPC with a CIDR block of 10.0.0.0/16.
2. Create Public and Private Subnets in 4 availability zones and Tag them.
3. Change Public subnet IPv4 addressing behavior (auto-assign public IPv4).
4. Create Internet gateway, tag it and attach it to VPC.
5. Create Public Route Table and Tag them.
6. Tag main Route Table
7. Create Route entry for internet gateway.
8. Associate Public Subnets with Public Route Table and Private Subnets with Private Route Table. 

Note: Change Resource Id's with your Respective Resource Id's (eg: vpc-xxxxxxx, subnet-xxxxxxx, rtb-xxxxxxx)

1.Create VPC with CIDR block 10.0.0.0/16

#aws ec2 create-vpc --cidr-block 10.0.0.0/16
#aws ec2 create-tags --resources vpc-001c305ff96094653 --tags Key=Name,Value=My-VPC

2.Create two public subnets and Tag them

#aws ec2 create-subnet --vpc-id vpc-001c305ff96094653 --cidr-block 10.0.0.0/24 --availability-zone us-east-1a
#aws ec2 create-tags --resources subnet-0e5d976ddcf99803e --tags Key=Name,Value=Public-1a
#aws ec2 create-subnet --vpc-id vpc-001c305ff96094653 --cidr-block 10.0.1.0/24 --availability-zone us-east-1b
#aws ec2 create-tags --resources subnet-0fa40143d62ee153f --tags Key=Name,Value=Public-1b

3.Create two private subnets and Tag them

#aws ec2 create-subnet --vpc-id vpc-001c305ff96094653 --cidr-block 10.0.2.0/24 --availability-zone us-east-1c
#aws ec2 create-tags --resources subnet-08101fac2b2a63a49 --tags Key=Name,Value=Private-1c
#aws ec2 create-subnet --vpc-id vpc-001c305ff96094653 --cidr-block 10.0.3.0/24 --availability-zone us-east-1d
#aws ec2 create-tags --resources subnet-057a3aca47b2b74c9 --tags Key=Name,Value=Private-1d

4.Change a subnet's public IPv4 addressing behavior

#aws ec2 modify-subnet-attribute --subnet-id subnet-0e5d976ddcf99803e --map-public-ip-on-launch
#aws ec2 modify-subnet-attribute --subnet-id subnet-0fa40143d62ee153f --map-public-ip-on-launch

5.Create Internet Gateway For VPC

#aws ec2 create-internet-gateway
#aws ec2 create-tags --resources igw-07de90cac62aeb974 --tags Key=Name,Value=My-IGW

6.Attach Internet Gateway to VPC 

#aws ec2 attach-internet-gateway --internet-gateway-id igw-07de90cac62aeb974 --vpc-id vpc-001c305ff96094653

7.Create Public Route Table 

#aws ec2 create-route-table --vpc-id vpc-001c305ff96094653
#aws ec2 create-tags --resources rtb-0bd1ddee351f41843 --tags Key=Name,Value=PublicRT

8.Create Tag for Main RouteTable(Private RouteTable)  

#aws ec2 create-tags --resources rtb-06928448f0a014e32 --tags Key=Name,Value=PrivateRT

9.Create a route for Internet Gateway

#aws ec2 create-route --route-table-id rtb-0bd1ddee351f41843 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-07de90cac62aeb974

10.Describe a Route Table

#aws ec2 describe-route-table --route-table-id rtb-0bd1ddee351f41843 

11.Associate Public Subnet with Public RouteTable  

#aws ec2 associate-route-table --route-table-id rtb-0bd1ddee351f41843 --subnet-id subnet-0e5d976ddcf99803e
#aws ec2 associate-route-table --route-table-id rtb-0bd1ddee351f41843 --subnet-id subnet-0fa40143d62ee153f

12.Associate Private Subnet with Main RouteTable(Private RouteTable)  

#aws ec2 associate-route-table --route-table-id rtb-06928448f0a014e32 --subnet-id subnet-08101fac2b2a63a49
#aws ec2 associate-route-table --route-table-id rtb-06928448f0a014e32 --subnet-id subnet-057a3aca47b2b74c9

Kubernetes Interview Questions

 

Q) Kubernetes Components:
The control plane is the system that maintains a record of all Kubernetes objects. 
1. Master Components:
Ø kube-apiserver: It acts as front-end for Kubernetes control plane. It exposes the Kubernetes API. CLItools (like kubectl), Users and even Master components (scheduler, control manager, etcd) and worker node components (like kubelet) everything talks with API server.
Øetcd: Consistent and highly available key-value store used as Kubernetes backing store for all cluster data. It stores all master and worker node information.
Økube-scheduler: Scheduler is responsible for distributing containers across multiple nodes. It watches for the newly created pod with no assigned node and select a node for them to run on.
Økube-control-manager: Controllers are responsible for noticing and responding when nodes, containers, or endpoints go down.        They make decisions to bring up new containers in such cases.
Node controller: Responsible for noticing and responding when nodes go down.
Replication controller: Responsible for maintaining the correct number of pods for every replication controller object in the system.
Endpoints controller: Populates the Endpoints object (that is, joins Services & Pods).
Service Account & Token controllers: Create default accounts and API access tokens for new namespaces.
2. Worker Components:
Ø  kubete: It is the Agent that runs on each node in the cluster. This agent is responsible for making sure that containers are running in a pod on a node.
Ø  kube-proxy: It is a network proxy that runs on each node in your cluster. It maintains network rules on nodes. Handles network communication between nodes by adding firewall routing rules.
Container Runtime: The container runtime is the software that is responsible for running containers. Kubernetes supports several container runtimes: Docker, containerd, CRI-O

Q) Kubernetes Node Type:
Kube Cluster is made up of two types of nodes:
Kube Masters: These servers are responsible for managing the Kube cluster as a whole. It has all the master components installed on it. They are also referred to as the controller node.  
Kube Workers:
These servers are responsible for running the actual pods, that the Kube Master instructs them to run. They have all the worker components installed on them. 

Q) Kubernetes Service and its Type?
A Service enables network access to a set of Pods in Kubernetes.
The type property in the Service's spec determines how the service is exposed to the network. The possibles types are ClusterIP, NodePort, LoadBalancer, and ExternalName
Ø  ClusterIp: The default value. The service is only accessible from within the Kubernetes cluster
Ø  NodePort: This makes the service accessible on a static port on each Node in the cluster.
Ø  LoadBalancer: The service becomes accessible externally through a cloud provider's load balancer functionality. GCP, AWS, Azure, and OpenStack offer this functionality.
Ø  ExternalName: Exposes the Service using an arbitrary name by returning a CNAME record with the name.

                 

Cloud Formation Template Examples

1. Simple Cloud Formation template to create EC2 instance.

---
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template will create an EC2 instance with default tenancy, with specific AMI, Availability zone, Subnet, KeyPair and instance type "
 
Resources:
  DEVEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: ap-south-1a
      ImageId: ami-0732b62d310b80e97
      InstanceType: t2.micro
      KeyName: MumbaiKP
      SubnetId: subnet-03a896945c3e5eb15
      Tags:
        Key: "Name"
          Value: "CFInstance"
      Tenancy: default

2. A Cloud Formation template to create EC2 instance with EIP.

---
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template will create an EC2 instance with default tenancy, with specific AMI, Availability zone, Subnet, KeyPair and Instance type and EIP"
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0732b62d310b80e97
      InstanceType: t2.micro
      KeyName: MumbaiKP
      SecurityGroups:
        - default
      Tags:
        - Key: "Name"
          Value: "CFInstance"
      Tenancy: default
 
  MyElasticIP:                  
    Type: AWS::EC2::EIP
    Properties:
      InstanceId: !Ref MyEC2Instance

3. A Cloud Formation template to create EC2 instance with EIP and Security Group.

---
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template will create an EC2 instance with default tenancy, with specific AMI, Availability zone, Subnet, KeyPair, and Instance type and EIP"
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0732b62d310b80e97
      InstanceType: t2.micro
      KeyName: MumbaiKP
      SecurityGroups:
        - !Ref SSHSecurityGroup
      Tags:
        - Key: "Name"
          Value: "CFInstance"
      Tenancy: default
     
  SSHSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: My SSH SG to allow 22 port
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
 
  MyElasticIP:                 
    Type: AWS::EC2::EIP
    Properties:
      InstanceId: !Ref MyEC2Instance

4. A Cloud Formation template to create EC2 instance with Security Group and allows you to select AZ, Instance Type, and Key Pair.

---
AWSTemplateFormatVersion: "2010-09-09"
 
Description: "This template allows you to select AvailabilityZone, InstanceType, and KeyPair to create EC2 instance with SecurityGroup allowing 22 port"
 
Parameters:
  MyKeyName:
    Description: Select the Kay Name from the List
    Type: AWS::EC2::KeyPair::KeyName
         
  MyAvailabilityZone:
    Description: Select the AZ from the List
    Type: String
    Default: ap-south-1a
    AllowedValues:
      - ap-south-1a
      - ap-south-1b
      - ap-south-1c
           
  MyInstanceType:
    Description: Select the AZ from the List
    Type: String
    Default: t2.micro
    AllowedValues:
      - "t2.nano"
      - "t2.micro"
      - "t2.small"
      - "t2.medium"
      - "t2.large"
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0732b62d310b80e97
      InstanceType: !Ref MyInstanceType
      KeyName: !Ref MyKeyName
      SecurityGroups:
        - !Ref SSHSecurityGroup
      Tags:
        - Key: "Name"
          Value: "CFInstance"
      Tenancy: default
      AvailabilityZone: !Ref MyAvailabilityZone
 
  SSHSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "My SSH SG to allow 22 port"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0

5. A Cloud Formation template to create EC2 instance with Dev, Test, Prod environment with respective instance type.

 ---
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template allows you to select an environmnent like dev, test, prod based on which EC2 instance of respective instance type will be launched with AZ, KeyPair, existing SecurityGroup inside selected subnet."
 
Parameters:
  MyKeyName:
    Description: Select the key name from the list
    Type: AWS::EC2::KeyPair::KeyName
 
  MyEnvironment:
    Description: Select Your Environment
    Type: String
    Default: Dev
    AllowedValues:
      - Dev
      - Test
      - Prod
 
  MyAvailabilityZone:
    Description: Select the Availability Zone from the List
    Type: String
    Default: ap-south-1a
    AllowedValues:
      - ap-south-1a
      - ap-south-1b
      - ap-south-1c
 
  MySecurityGroups:
    Description: The list of SecurityGroupIds in your Virtual Private Cloud (VPC)
    Type: List<AWS::EC2::SecurityGroup::Id>      
 
  MySubnetId:
    Description: Select Subnet from the List.
    Type: AWS::EC2::Subnet::Id
 
Mappings:
  MyRegionMap:
    ap-south-1:
      AMI1: ami-0732b62d310b80e97   
 
  MyEnvironmentMap:
    Dev:
      instanceType: t2.micro
    Test:
      instanceType: t2.small       
    Prod:
      instanceType: t2.medium
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: !Ref MyAvailabilityZone
      ImageId: !FindInMap
        - MyRegionMap
        - !Ref 'AWS::Region'
        - AMI1         
      InstanceType: !FindInMap
        - MyEnvironmentMap
        - !Ref MyEnvironment
        - instanceType                
      KeyName: !Ref MyKeyName
      SecurityGroupIds: !Ref MySecurityGroups
      SubnetId: !Ref MySubnetId
      Tags:
        - Key: "Name"
          Value: "CFInstance"
      Tenancy: default

6. A Cloud Formation template to create VPC with public and private subnets, Internet Gateway, Nat Gateway, Route Tables.

---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'This template will create VPC with two public and private subnets spread across two AZ, creates Internet gateway, Nat Gateway, Route Tables and also associate these subnets with respective route tables, Also adds route entries to route tables for traffic destined to the Internet.' 
Parameters:
  EnvironmentName:
    Description: An environment name that is prefixed to resource names
    Type: String
 
  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: 10.192.0.0/16
   
  PublicSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for Public Subnet 1
    Type: String
    Default: 10.192.1.0/24
 
  PublicSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for Public Subnet 2
    Type: String
    Default: 10.192.2.0/24
 
  PrivateSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for Private Subnet 1
    Type: String
    Default: 10.192.11.0/24
 
  PrivateSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for Private Subnet 2
    Type: String
    Default: 10.192.12.0/24   
 
Resources:
##### Create VPC #####
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-VPC
 
##### Create Internet Gateway and Attach to VPC #####                
 
  MyInternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-IGW
 
  AttachMyInternetGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref MyInternetGateway
 
##### Create Nat Gateway in Public Subnet #####
##### Allocate Elastic IP to Nat Gateway #####
 
  NatEIP:
    DependsOn: AttachMyInternetGateway
    Type: AWS::EC2::EIP
    Properties:
       Domain: vpc
 
  MyNATGateway:
    Type: AWS::EC2::NatGateway
    DependsOn: AttachMyInternetGateway
    Properties:
       AllocationId: !GetAtt NatEIP.AllocationId
       SubnetId: !Ref PublicSubnet1
       Tags:
         - Key: Name
           Value: !Sub ${EnvironmentName}-NGW
 
##### Create Public and Private Subnets #####   
 
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 0, !GetAZs ]
      CidrBlock: !Ref PublicSubnet1CIDR
      MapPublicIpOnLaunch: true
      Tags:
       - Key: Name
         Value: !Sub ${EnvironmentName}-Public-A
      VpcId: !Ref MyVPC
 
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 1, !GetAZs ]
      CidrBlock: !Ref PublicSubnet2CIDR
      MapPublicIpOnLaunch: true
      Tags:
       - Key: Name
         Value: !Sub ${EnvironmentName}-Public-B
      VpcId: !Ref MyVPC
 
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 0, !GetAZs ]
      CidrBlock: !Ref PrivateSubnet1CIDR
      MapPublicIpOnLaunch: false
      Tags:
       - Key: Name
         Value: !Sub ${EnvironmentName}-Private-A
      VpcId: !Ref MyVPC
 
  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 1, !GetAZs ]
      CidrBlock: !Ref PrivateSubnet2CIDR
      MapPublicIpOnLaunch: false
      Tags:
       - Key: Name
         Value: !Sub ${EnvironmentName}-Private-B
      VpcId: !Ref MyVPC
 
##### Create Public Route Table and add Route to InternetGateway #####
 
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
      - Key: Name
        Value: !Sub ${EnvironmentName}-PublicRT
 
  MyPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachMyInternetGateway
    Properties:
       RouteTableId: !Ref PublicRouteTable
       DestinationCidrBlock: 0.0.0.0/0
       GatewayId: !Ref MyInternetGateway
 
##### Create Private Route Table add Route to NATGateway #####
 
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
      - Key: Name
        Value: !Sub ${EnvironmentName}-PrivateRT
 
  MyPrivateRoute:
    Type: AWS::EC2::Route
    Properties:
       RouteTableId: !Ref PrivateRouteTable
       DestinationCidrBlock: 0.0.0.0/0
       NatGatewayId: !Ref MyNATGateway
 
##### Associate Public RT and Private RT with subnets #####
 
  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable
 
  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable
 
  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable
 
  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable
 
Outputs:
  VPC:
    Description: A reference to the created VPC
    Value: !Ref MyVPC
 
  PublicSubnets:
    Description: A list of the public subnets
    Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]]
 
  PrivateSubnets:
    Description: A list of the private subnets
    Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]]
 
  PublicSubnet1:
    Description: A reference to the public subnet in the 1st Availability Zone
    Value: !Ref PublicSubnet1
 
  PublicSubnet2:
    Description: A reference to the public subnet in the 2nd Availability Zone
    Value: !Ref PublicSubnet2
 
  PrivateSubnet1:
    Description: A reference to the private subnet in the 1st Availability Zone
    Value: !Ref PrivateSubnet1
 
  PrivateSubnet2:
    Description: A reference to the private subnet in the 2nd Availability Zone
    Value: !Ref PrivateSubnet2

7. A Cloud Formation template to create EC2 Instance with Apache web server installed using CloudFormation bootstrap scripts.

--- 
AWSTemplateFormatVersion: 2010-09-09
Description: "AWS CloudFormation Sample Template for Apache Web Server This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server at instance launch time."
Parameters:
  MyKeyName:
    Description: Select The Key Name From The List.
    Type: 'AWS::EC2::KeyPair::KeyName'
  MyInstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
  MyAvailabilityZone:
    Description: Select the Availability Zone from the List
    Type: String
    Default: ap-south-1a
    AllowedValues:
      - ap-south-1a
      - ap-south-1b
      - ap-south-1c
  MySecurityGroups:
    Description: The list of SecurityGroupIds in your Virtual Private Cloud (VPC)
    Type: 'List<AWS::EC2::SecurityGroup::Id>'
  MySubnetId:
    Description: Select Subnet From The List.
    Type: 'AWS::EC2::Subnet::Id'
Resources:
  MyEC2Instance:
    Type: 'AWS::EC2::Instance'
    Metadata:
      Comment: Install httpd package
      'AWS::CloudFormation::Init':
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: |
                <html>
                  <body>
                    <h1>Goinit.Net</h1>
                    <h2>CloudFormation Web Server</h2>
                    <p>Welcome to My page.</p>
                  </body>
                </html>
              mode: '000644'
              owner: root
              group: root
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                stack=$(AWS::StackId}
                region=${AWS::Region}
                interval=7
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.MyEC2Instance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource MyEC2Instance --region ${AWS::Region}
              mode: '000400'
              owner: root
              group: root
          services:
            sysvinit:
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
              cfn-hup:
                enabled: 'true'
                ensureRunning: 'true'
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf   
    Properties:
      AvailabilityZone: !Ref MyAvailabilityZone
      ImageId: ami-0732b62d310b80e97
      InstanceType: !Ref MyInstanceType
      KeyName: !Ref MyKeyName
      SecurityGroupIds: !Ref MySecurityGroups
      SubnetId: !Ref MySubnetId
      Tags:
        - Key: Name
          Value: CFInstance
      Tenancy: default
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash -xe
            #Get latest cfn package
            yum update -y aws-cfn-bootstrap
            #Start cfn-init to install all metadata content
            /opt/aws/bin/cfn-init --stack ${AWS::StackName} --resource MyEC2Instance --region ${AWS::Region} || error_exit 'Failed to run cfn-init'
            #Signal the status from cfn-init
            /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource MyEC2Instance --region ${AWS::Region}
Outputs:
  MyInstanceURL:
    Description: Apache web URL
    Value: !Sub 'http://${MyEC2Instance.PublicDnsName}'

8. A Cloud Formation template to create EC2 Instance with S3 Read Only Access by using EC2 IAM Role.
---
AWSTemplateFormatVersion: "2010-09-09"
Description: "AWS Cloud Formation template to create EC2 Instance with S3 Read Only Access(List* and Get*) by using EC2 IAM Role "
 
Parameters:
  InstanceName:
    Description: Give Tag to Instance
    Type: String
    Default: WebServer
 
  MyKeyName:
    Description: "Select The Key Name From The List."
    Type: AWS::EC2::KeyPair::KeyName
 
  MyInstanceType:
    Description: "WebServer EC2 instance type"
    Type: String
    Default: "t2.micro"
    AllowedValues:
      - "t2.nano"
      - "t2.micro"
      - "t2.small"
      - "t2.medium"
      - "t2.large"
 
  MyAvailabilityZone:
    Description: Select the Availability Zone from the List
    Type: String
    Default: ap-south-1a
    AllowedValues:
      - ap-south-1a
      - ap-south-1b
      - ap-south-1c
 
  MySecurityGroups:
    Description: The list of SecurityGroupIds in your Virtual Private Cloud (VPC)
    Type: List<AWS::EC2::SecurityGroup::Id>      
 
  MySubnetId:
    Description: Select Subnet From The List.
    Type: AWS::EC2::Subnet::Id
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: !Ref MyAvailabilityZone
      ImageId: ami-0e306788ff2473ccb
      InstanceType: !Ref MyInstanceType
      KeyName: !Ref MyKeyName
      SecurityGroupIds: !Ref MySecurityGroups
      SubnetId: !Ref MySubnetId
      Tags:
        - Key: "Name"
          Value: !Ref InstanceName
      Tenancy: default
      IamInstanceProfile: !Ref MyInstanceS3AccessProfile
 
  MyEc2S3AccessProfileRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
              - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: MyEc2InstanceS3AccessPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 's3:Get*'
                  - 's3:List*'
                Resource: '*'
 
  MyInstanceS3AccessProfile:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      Path: /
      Roles:
        - !Ref MyEc2S3AccessProfileRole  
 
Outputs:
  MyInstanceId:
    Description: Public IP Address
    Value: !GetAtt MyEC2Instance.PublicIp