I Tried Deploying an EC2 Web Server with CloudFormation and Ansible
In this blog, I will walk you through the process of deploying an EC2 instance using CloudFormation and then configuring a web server in it using Ansible. i will be using personal laptop as an Ansible controller for seamless management and configuration.
Prerequisites
- Install Ansible using Homebrew:
brew install ansible
- Make sure you have AWS CLI installed and configured with your credentials.
Cloudformation Template for EC2 and Networking
save this file with name ec2.yaml
AWSTemplateFormatVersion: 2010-09-09 Description: this template will create ec2 Parameters: Keypair: Description: please enterthe name of keypair available in ap-northeast-1a Type: String Default: web SystemName: Description: this name will be the prefix of all the resources. Type: String Default: Web VpcCidr: Description: CIDR Blocjk for the VPC . the Cidr dhould be unique in your environment Type: String Default: 10.0.0.0/18 InstanceType: Description: please selecet based on performance and network requirement Type: String Default: t3.micro AmiId: Description: make sure your ami is of correct region Type: String Default: ami-0947c48ae0aaf6781 SubnetCidr: Description: this is the CIDR of public Subnet which should lie between VPC CIDR and should have enough capacity with 5 IPs for aws Type: String Default: 10.0.0.1/24 Resources: ########################## #Network ######################### VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidr EnableDnsSupport: true Tags: - Key: Name Value: !Sub ${SystemName}-vpc IGW: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub ${SystemName}-IGW AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref IGW PublicSubnet: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-1a VpcId: !Ref VPC CidrBlock: !Ref SubnetCidr Tags: - Key: Name Value: !Sub ${SystemName}-publicsubnet PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${SystemName}-RouteTable PublicRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref IGW PublicRouteTableAssoc: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet RouteTableId: !Ref PublicRouteTable ############################# #EC2 ############################# EIP1: Type: AWS::EC2::EIP EniAssociation: Type: AWS::EC2::EIPAssociation Properties: AllocationId: !GetAtt EIP1.AllocationId InstanceId: !Ref ServerInstance ServerInstance: Type: AWS::EC2::Instance Properties: ImageId : !Ref AmiId InstanceType: !Ref InstanceType KeyName : !Ref Keypair SubnetId : !Ref PublicSubnet SecurityGroupIds: - !Ref SecGroup Tags: - Key: Name Value: !Sub ${SystemName} SecGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: serverinstance-sg GroupDescription: thi is the security group for web server VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: !Sub ${SystemName}-sg
Deploy EC2 Server
- Run the CloudFormation template to create an EC2 instance. Replace `Your-Keypair-Name` with your keypair name:
aws cloudformation deploy --template-file ec2.yml --stack-name ec2 --region ap-northeast-1 --parameter-overrides keypair=Your-Keypair-Name
Note: This will create the EC2 instance using the specified CloudFormation template. Make sure to change the Keypair
parameter to match your keypair file.
- Update the values in the `inventory.txt` file with the appropriate username and host information.
save the bellow code with file name inventory.txt
# Inventory file for Ansible playbook # Group definition for the EC2 instance(s) to manage [web_ec2_instance] # Define the hostname or IP address of the EC2 instance # Replace 'xx.xx.xx.xxx' with the actual IP address or hostname of the EC2 instance # Define the SSH user to be used for connecting to the EC2 instance (in this case, 'ec2-user') # Define the SSH connection type ('ssh' in this case) # Define the path to the private key file ('xxx.pem') for SSH authentication web ansible_host=xx.xx.xx.xxx ansible_user=ec2-user ansible_connection=ssh ansible_ssh_private_key_file=/.ssh/xxx.pem
Ansible Configuration
Save the below template with name playbook.yml
# Play 1: Install httpd package on all hosts - name: play 1 hosts: all # Replace with the target host/group where you want to create the file become: true tasks: - name: Install httpd yum: name: httpd state: present # Play 2: Start the httpd service on all hosts - name: play 2 hosts: all # Replace with the target host/group where the service should be started become: true tasks: - name: Start the httpd service service: name: httpd state: started # Play 3: Create an index.html file on all hosts - name: play 3 hosts: all become: true tasks: - name: Create the index.html file file: path: /var/www/html/index.html state: touch # Play 4: Append a line to the index.html file on all hosts - name: play 4 hosts: all become: true tasks: - name: Append line to index.html lineinfile: path: /var/www/html/index.html line: '<h1>Hello, World!</h1>'
- Run the Ansible playbook to configure the server. Make sure to specify the inventory file:
ansible-playbook playbook.yml -i inventory.txt
The playbook will execute tasks defined in playbook.yml
on the target hosts specified in the inventory.txt
file.
Conclusion
With this combined approach, you can quickly and confidently deploy and manage your EC2 web server, ensuring a reliable and scalable infrastructure for your applications. Embrace the power of CloudFormation and Ansible, and take your infrastructure management to the next level. Happy deploying!