<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[DevOps Insights &amp; Code Chronicles]]></title><description><![CDATA[Explore the world of DevOps, coding, and tech insights. Stay updated with our latest articles on everything from CI/CD to coding best practices. Join our community today!]]></description><link>https://blog.ajitfawade.com</link><generator>RSS for Node</generator><lastBuildDate>Mon, 05 Oct 2026 18:13:46 GMT</lastBuildDate><atom:link href="https://blog.ajitfawade.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Ace Your AWS Interview: 13 Common Questions and Answers]]></title><description><![CDATA[AWS is one of the most popular and widely used cloud platforms in the world. It offers a variety of services and solutions for different needs and scenarios. Whether you are a beginner or an expert, you might encounter some AWS interview questions in...]]></description><link>https://blog.ajitfawade.com/how-to-ace-your-aws-interview-13-common-questions-and-answers</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-ace-your-aws-interview-13-common-questions-and-answers</guid><category><![CDATA[Devops]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[interview]]></category><category><![CDATA[aws-services]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Wed, 31 Jan 2024 16:38:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706414087787/3a212245-714f-4da0-bdbe-cd0d36b3eec4.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>AWS is one of the most popular and widely used cloud platforms in the world. It offers a variety of services and solutions for different needs and scenarios. Whether you are a beginner or an expert, you might encounter some AWS interview questions in your job search or career development.</p>
<p>In this blog post, I will share with you thirteen common AWS interview questions and answers that can help you prepare for your next interview.</p>
<p>Let's go!</p>
<h3 id="heading-1-name-5-aws-services-youve-used-and-their-use-cases">1. <strong>Name 5 AWS services you’ve used and their use cases.</strong></h3>
<p>Some of the AWS services that I have used are:</p>
<ul>
<li><p>Amazon EC2: This is a service that provides scalable and secure compute capacity in the cloud. I have used it to launch and run virtual servers for various applications, such as web hosting, data processing, and machine learning.</p>
</li>
<li><p>Amazon S3: This is a service that provides durable and highly available object storage in the cloud. I have used it to store and retrieve any kind of data, such as images, videos, documents, and backups.</p>
</li>
<li><p>Amazon RDS: This is a service that manages relational databases in the cloud. I have used it to create and operate MySQL, PostgreSQL, Oracle, and SQL Server databases for my applications.</p>
</li>
<li><p>Amazon Lambda: This is a service that lets you run code without provisioning or managing servers. I have used it to create serverless functions that respond to events, such as HTTP requests, S3 uploads, DynamoDB updates, and SNS messages.</p>
</li>
<li><p>Amazon CloudFormation: This is a service that lets you model and provision AWS resources using templates. I have used it to automate and standardize the deployment and configuration of my AWS infrastructure.</p>
</li>
</ul>
<h3 id="heading-2-what-tools-send-logs-to-the-cloud-environment">2. <strong>What tools send logs to the cloud environment?</strong></h3>
<p>Various tools can send logs to the cloud environment, depending on the source and destination of the logs. Some of the tools that I have used or heard of are:</p>
<ul>
<li><p>AWS CloudWatch Logs: This is a service that monitors and stores logs from AWS resources and applications. I have used it to collect and analyze logs from my EC2 instances, Lambda functions, and other AWS services.</p>
</li>
<li><p>AWS CloudTrail: This is a service that records and delivers API activity and events in your AWS account. I have used it to audit and track the actions performed by users, roles, and services in my AWS account.</p>
</li>
<li><p>Fluentd: This is an open-source tool that collects and forwards logs from various sources to various destinations. I have used it to send logs from my EC2 instances and containers to S3, CloudWatch Logs, and Elasticsearch.</p>
</li>
<li><p>Logstash: This is an open-source tool that processes and ships logs from various sources to various destinations. I have used it to send logs from my EC2 instances and containers to S3, CloudWatch Logs, and Elasticsearch.</p>
</li>
<li><p>Filebeat: This is an open-source tool that collects and forwards logs from files and streams. I have used it to send logs from my EC2 instances and containers to Logstash, Elasticsearch, and Kafka.</p>
</li>
</ul>
<h3 id="heading-3-explain-iam-roles-how-do-you-createmanage-them">3. <strong>Explain IAM Roles. How do you create/manage them?</strong></h3>
<p>An IAM role is a set of permissions that allows an IAM user or another service to perform certain actions on AWS resources. An IAM role can be assumed by other entities without requiring their credentials, while an IAM user always requires its credentials to access AWS resources.</p>
<p>To create and manage IAM roles, you can use the AWS Management Console, the AWS CLI, or the AWS SDKs. The general steps are:</p>
<ul>
<li><p>Create a role by specifying the trusted entity (such as an AWS service, an external identity provider, or another AWS account) that can assume the role, and the permissions (such as policies or permissions boundaries) that the role grants.</p>
</li>
<li><p>Attach the role to the entity that needs to assume it, such as an EC2 instance, a Lambda function, or a user in another AWS account.</p>
</li>
<li><p>Optionally, configure the role settings, such as the maximum session duration, the tags, or the description.</p>
</li>
<li><p>Monitor and audit the role activity using CloudTrail, CloudWatch, or IAM Access Analyzer.</p>
</li>
</ul>
<h3 id="heading-4-how-do-you-upgradedowngrade-a-system-with-zero-downtime">4. <strong>How do you upgrade/downgrade a system with zero downtime?</strong></h3>
<p>Upgrading or downgrading a system means changing its configuration or version without affecting its availability or functionality.</p>
<p>One way to achieve zero downtime upgrade or downgrade is using a blue/green deployment strategy. This involves creating two identical copies of your system (one old version and one new version) in separate environments (such as staging and production). Then, you swap traffic between these environments gradually until all users are redirected to the new version.</p>
<p>To perform a blue/green deployment with zero downtime upgrade or downgrade using AWS services:</p>
<ul>
<li><p>Create two instances of your system in different regions using Amazon EC2.</p>
</li>
<li><p>Configure each instance with the same settings as your original system.</p>
</li>
<li><p>Configure each instance with different versions of software or configuration files as needed.</p>
</li>
<li><p>Configure each instance with different load balancers or DNS records as needed.</p>
</li>
<li><p>Configure each instance with different security groups or network ACLs as needed.</p>
</li>
<li><p>Configure each instance with different tags or metadata as needed.</p>
</li>
<li><p>Test each instance separately by accessing them from different locations.</p>
</li>
<li><p>Monitor each instance’s performance and health using Amazon CloudWatch.</p>
</li>
<li><p>Start swapping traffic between instances gradually until all users are redirected to the new version.</p>
</li>
</ul>
<h3 id="heading-5-define-infrastructure-as-code-and-explain-its-usage">5. <strong>Define infrastructure as code and explain its usage.</strong></h3>
<p>Infrastructure as code (IaC) is a practice of defining and managing infrastructure using code instead of manual processes or graphical interfaces. IaC enables automation, consistency, scalability, reliability, security, collaboration, and compliance for infrastructure provisioning and management.</p>
<p>To use IaC with AWS:</p>
<ul>
<li><p>Choose one of the supported tools for IaC such as Terraform, Ansible, Chef, Puppet, CloudFormation, etc.</p>
</li>
<li><p>Install and configure the tool according to its documentation.</p>
</li>
<li><p>Write code that defines your infrastructure resources such as EC2 instances, VPCs, S3 buckets, etc.</p>
</li>
<li><p>Validate your code using syntax checkers, linters, formatters, etc.</p>
</li>
<li><p>Apply your code using commands, scripts, workflows, etc.</p>
</li>
<li><p>Review your infrastructure state using dashboards, reports, logs, etc.</p>
</li>
</ul>
<h3 id="heading-6-describe-load-balancers-provide-scenarios-of-each-type-based-on-your-experience">6. <strong>Describe load balancers. Provide scenarios of each type based on your experience.</strong></h3>
<p>Load balancers are devices or services that distribute incoming traffic across multiple servers or instances to improve performance, availability, and reliability. Different types of load balancers can be used for different purposes and scenarios. Some of the common types are:</p>
<ul>
<li><p>HTTP(S) load balancers: These are load balancers that handle HTTP(S) requests from clients and route them to the appropriate backend servers based on the URL path, hostname, or other criteria. They can also perform SSL termination, caching, compression, and other functions to optimize the web application performance and security. Some examples of HTTP(S) load balancers are AWS Elastic Load Balancing (ELB), Cloudflare Load Balancer, and Nginx Ingress Controller.</p>
</li>
<li><p>TCP/UDP load balancers: These are load balancers that handle TCP/UDP packets from clients and route them to the appropriate backend servers based on the source and destination IP addresses, ports, or other criteria. They can also perform protocol conversion, encryption, decryption, and other functions to optimize the network communication performance and security. Some examples of TCP/UDP load balancers are AWS Network Load Balancer (NLB), Cloudflare Workers, and HAProxy.</p>
</li>
<li><p>Database load balancers: These are load balancers that handle database queries from clients and route them to the appropriate database servers based on the database name, schema name, table name, or other criteria. They can also perform database replication, failover, scaling, and other functions to optimize the database's performance and availability. Some examples of database load balancers are AWS Database Load Balancer (DBLB), Cloud SQL Proxy, and MongoDB Atlas.</p>
</li>
<li><p>Application layer proxies: These are load balancers that handle application requests from clients and route them to the appropriate backend servers based on the application logic or business rules. They can also perform application transformation, routing optimization, logging analysis, and other functions to optimize the application performance and functionality. Some examples of application layer proxies are AWS Application Load Balancer (ALB), Cloudflare Workers API Gateway, and Apache Traffic Server.</p>
</li>
</ul>
<p>I have used these types of load balancers in my previous projects as a DevOps engineer. For example:</p>
<ul>
<li><p>I used an HTTP(S) load balancer called AWS ELB to distribute web traffic among several EC2 instances running a WordPress site with a WooCommerce plugin. I configured ELB with health checks, sticky sessions, cross-zone load balancing, and auto-scaling features to ensure high availability, scalability, and performance for my site.</p>
</li>
<li><p>I used a TCP/UDP load balancer called Cloudflare Workers API Gateway to distribute network traffic among several Cloudflare Workers running a Node.js app. I configured Workers API Gateway with caching, compression, encryption, and firewall features to optimize my app performance, security, and functionality.</p>
</li>
<li><p>I used a database load balancer called AWS DBLB to distribute database queries among several Amazon RDS instances running MySQL databases. I configured DBLB with replication, failover, scaling, and encryption features to ensure high availability, scalability, and security for my databases.</p>
</li>
<li><p>I used an application layer proxy called Apache Traffic Server to distribute application requests among several Apache web servers running PHP applications. I configured Traffic Server with transformation rules, routing rules, logging rules, and analytics features to optimize my application's performance, functionality, and visibility.</p>
</li>
</ul>
<h3 id="heading-7-what-is-cloudformation-and-why-is-it-used">7. <strong>What is CloudFormation and why is it used?</strong></h3>
<p>CloudFormation is an AWS service that allows you to create and manage your AWS infrastructure using code. It uses templates that describe the resources and their dependencies that you want to provision on AWS. You can use CloudFormation to automate the creation, update, and deletion of your infrastructure in a consistent and repeatable way.</p>
<p>Some of the benefits of using CloudFormation are:</p>
<ul>
<li><p>It saves time and effort by eliminating the need for manual tasks or scripts.</p>
</li>
<li><p>It ensures that your infrastructure is configured according to best practices and security standards.</p>
</li>
<li><p>It enables you to track and control the changes and versions of your infrastructure.</p>
</li>
<li><p>It allows you to reuse and share your templates with others.</p>
</li>
<li><p>It integrates with other AWS services and tools such as IAM, SNS, CodeDeploy, etc.</p>
</li>
</ul>
<p>Some of the use cases of CloudFormation are:</p>
<ul>
<li><p>Simplify infrastructure management: For a scalable web application that also includes a backend database, you might use an Auto Scaling group, an Elastic Load Balancing load balancer, and an Amazon Relational Database Service database instance. You might use each service to provision these resources and after you create the resources, you would have to configure them to work together. All these tasks can add complexity and time before you even get your application up and running. Instead, you can create a CloudFormation template or modify an existing one. A template describes all your resources and their properties. When you use that template to create a CloudFormation stack, CloudFormation provisions the Auto Scaling group, load balancer, and database for you. After the stack has been successfully created, your AWS resources are up and running. You can delete the stack just as easily, which deletes all the resources in the stack. By using CloudFormation, you easily manage a collection of resources as a single unit.</p>
</li>
<li><p>Quickly replicate your infrastructure: If your application requires additional availability, you might replicate it in multiple regions so that if one region becomes unavailable, your users can still use your application in other regions. The challenge in replicating your application is that it also requires you to replicate your resources. Not only do you need to record all the resources that your application requires, but you must also provision and configure those resources in each region. Reuse your CloudFormation template to create your resources in a consistent and repeatable manner. To reuse your template, describe your resources once and then provision the same resources over and over in multiple regions.</p>
</li>
<li><p>Easily control and track changes to your infrastructure: In some cases, you might have underlying resources that you want to upgrade incrementally. For example, you might change to a higher-performing instance type in your Auto Scaling launch configuration so that you can reduce the maximum number of instances in your Auto Scaling group. If problems occur after you complete the update, you might need to roll back your infrastructure to the original settings. To do this manually, you not only have to remember which resources were changed, but you also have to know what the original settings were. With CloudFormation, you can easily control and track changes to your infrastructure. You can use CloudFormation to update your stack with the new settings and monitor the progress of the update. If you need to roll back your changes, you can use CloudFormation to restore your stack to the previous state. CloudFormation records all the changes that you make to your stack and allows you to view the history of your stack updates.</p>
</li>
</ul>
<h3 id="heading-8-distinguish-between-aws-cloudformation-and-aws-elastic-beanstalk">8. <strong>Distinguish between AWS CloudFormation and AWS Elastic Beanstalk.</strong></h3>
<p>AWS CloudFormation and AWS Elastic Beanstalk are both services that help you to deploy and manage your applications on AWS. However, they have some differences in terms of scope, flexibility, and complexity.</p>
<ul>
<li><p>Scope: CloudFormation can be used to create and manage any type of AWS resource, not just applications. Elastic Beanstalk is focused on deploying and managing web applications that run on EC2 instances or containers.</p>
</li>
<li><p>Flexibility: CloudFormation gives you more control and customization over your infrastructure, as you can define every detail of your resources and their dependencies using templates. Elastic Beanstalk provides a simpler and faster way to deploy your applications, as it automatically handles the provisioning, scaling, load balancing, and health monitoring of your resources.</p>
</li>
<li><p>Complexity: CloudFormation requires more knowledge and skills to use, as you need to write and maintain your templates and understand the syntax and logic of the CloudFormation language. Elastic Beanstalk is easier to use, as you only need to upload your application code and choose a platform and configuration options.</p>
</li>
</ul>
<p>You can use both services together, as Elastic Beanstalk uses CloudFormation under the hood to create and update the resources for your application. You can also customize the CloudFormation templates that Elastic Beanstalk generates for your environment, or use your templates to create additional resources for your application.</p>
<h3 id="heading-9-enumerate-cloud-security-attacks-and-methods-to-minimize-them">9. <strong>Enumerate cloud security attacks and methods to minimize them.</strong></h3>
<p>Cloud security attacks are malicious attempts to compromise the confidentiality, integrity, or availability of your data or resources on the cloud. Some of the common types of cloud security attacks are:</p>
<ul>
<li><p>Distributed denial-of-service (DDoS) attacks: These are attacks that aim to overwhelm your system with a large amount of traffic or requests, causing it to slow down or crash.</p>
</li>
<li><p>Brute force attacks: These are attacks that try to guess your credentials or keys by trying different combinations of characters or words until they find the correct one.</p>
</li>
<li><p>Man-in-the-middle (MITM) attacks: These are attacks that intercept and modify the communication between two parties, such as your browser and a web server, without their knowledge or consent.</p>
</li>
<li><p>Malware attacks: These are attacks that inject malicious software or code into your system, such as viruses, worms, trojans, ransomware, etc., that can damage, steal, or encrypt your data or resources.</p>
</li>
<li><p>Phishing attacks: These are attacks that trick you into revealing your personal or sensitive information, such as passwords, credit card numbers, etc., by sending you fake emails or websites that look legitimate.</p>
</li>
</ul>
<p>To minimize the risk of cloud security attacks, you can use the following best practices:</p>
<ul>
<li><p>Use strong and unique passwords or keys for your accounts and resources, and change them regularly.</p>
</li>
<li><p>Enable multi-factor authentication (MFA) for your accounts and resources, which requires you to provide an additional factor of verification, such as a code or a device, besides your password or key.</p>
</li>
<li><p>Encrypt your data at rest and in transit, using encryption algorithms and protocols, such as AES, SSL, TLS, etc.</p>
</li>
<li><p>Use firewalls, network ACLs, and security groups to control the inbound and outbound traffic to your resources, and allow only the necessary ports and protocols.</p>
</li>
<li><p>Use IAM roles and policies to grant the minimum required permissions to your users and resources, and follow the principle of least privilege.</p>
</li>
<li><p>Monitor and audit your activities and resources using services such as CloudTrail, CloudWatch, and GuardDuty, and detect and respond to any suspicious or anomalous behavior.</p>
</li>
<li><p>Educate yourself and your team about the common types and signs of security attacks, and how to prevent and report them.</p>
</li>
</ul>
<h3 id="heading-10-can-we-recover-an-ec2-instance-if-the-key-is-lost-how">10. Can we recover an EC2 instance if the key is lost? How?</h3>
<p>Yes, it is possible to recover an EC2 instance if the key is lost, but it requires some steps and precautions. Different methods are depending on the type of instance and the root device type. One of the common methods is to use another EC2 instance as a recovery instance and attach the volume of the lost key instance to it. Then, you can copy the public key of the recovery instance to the authorized keys file of the lost key instance. After that, you can detach the volume from the recovery instance and reattach it to the lost key instance. You should be able to access the lost key instance using the key pair of the recovery instance. For more details and other methods, see <a target="_blank" href="https://repost.aws/knowledge-center/user-data-replace-key-pair-ec2">Connect to an Amazon EC2 instance when the SSH key pair is lost.</a></p>
<h3 id="heading-11-define-a-gateway-in-the-aws-context">11. Define a gateway in the AWS context.</h3>
<p>A gateway in the AWS context is a service or a device that connects different networks, protocols, or applications. AWS offers various types of gateways for different purposes and scenarios. Some of the common types are:</p>
<ul>
<li><p>API Gateway: This is a service that lets you create, publish, maintain, monitor, and secure APIs at any scale. You can use API Gateway to connect your applications to backend services, such as Lambda functions, EC2 instances, or other AWS services. API Gateway also provides features such as caching, throttling, authentication, and CORS support. For more information, see <a target="_blank" href="https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html">What is Amazon API Gateway?</a></p>
</li>
<li><p>Internet Gateway: This is a device that enables communication between your VPC and the internet. It performs network address translation (NAT) for instances that have public IPv4 addresses. An internet gateway serves as a default route for your public subnets. You can attach only one internet gateway to a VPC at a time. For more information, see <a target="_blank" href="https://solutionincblog.com/2022/10/12/what-is-an-internet-gateway/">Internet gateways</a>.</p>
</li>
<li><p>NAT Gateway: This is a service that enables instances in a private subnet to connect to the Internet or other AWS services, but prevents the Internet from initiating a connection with those instances. A NAT gateway can handle up to 55,000 simultaneous connections to each unique destination. You can create one or more NAT gateways in each Availability Zone in your VPC. For more information, see <a target="_blank" href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html">NAT gateways</a>.</p>
</li>
<li><p>Virtual Private Gateway: This is a device that enables you to establish a VPN connection between your VPC and your on-premises network. A virtual private gateway serves as a VPN concentrator on the AWS side of the VPN connection. You can attach only one virtual private gateway to a VPC at a time. For more information, see <a target="_blank" href="https://www.scaler.com/topics/aws/aws-virtual-private-gateway/">Virtual Private Gateways</a>.</p>
</li>
<li><p>Storage Gateway: This is a service that connects your on-premises applications to AWS storage services, such as S3, Glacier, and EBS. Storage Gateway provides three types of gateways: file gateway, volume gateway, and tape gateway. Each type of gateway exposes different storage interfaces and capabilities. For more information, see <a target="_blank" href="https://aws.amazon.com/storagegateway/faqs/">What is AWS Storage Gateway</a>?</p>
</li>
</ul>
<h3 id="heading-12-differentiate-between-amazon-rds-dynamodb-and-redshift">12. Differentiate between Amazon RDS, DynamoDB, and Redshift.</h3>
<p>Amazon RDS, DynamoDB, and Redshift are all AWS services that provide data storage and management solutions. However, they have some differences in terms of type, structure, scalability, performance, and use cases.</p>
<ul>
<li><p>Type: RDS is a relational database service that supports various SQL-based database engines, such as MySQL, PostgreSQL, Oracle, etc. DynamoDB is a NoSQL database service that supports key-value and document data models. Redshift is a data warehouse service that supports SQL-based analytics and business intelligence tools.</p>
</li>
<li><p>Structure: RDS stores data in tables that have predefined columns and rows, and enforces data integrity and consistency using schemas and constraints. DynamoDB stores data in tables that have flexible attributes and items and allows schemaless and dynamic data manipulation. Redshift stores data in tables that have predefined columns and rows and optimizes data storage and retrieval using compression and distribution techniques.</p>
</li>
<li><p>Scalability: RDS scales vertically by changing the size or type of the instance that hosts the database, or horizontally by adding read replicas or shards to the database. DynamoDB scales horizontally by adding or removing partitions to the table, or vertically by changing the provisioned throughput capacity of the table. Redshift scales horizontally by adding or removing nodes to the cluster, or vertically by changing the size or type of the node.</p>
</li>
<li><p>Performance: RDS provides high performance and availability for transactional and operational workloads, such as online shopping, banking, gaming, etc. DynamoDB provides high performance and availability for non-relational and distributed workloads, such as social media, IoT, gaming, etc. Redshift provides high performance and availability for analytical and reporting workloads, such as data warehousing, business intelligence, data mining, etc.</p>
</li>
<li><p>Use cases: RDS is suitable for applications that need a relational database with ACID (atomicity, consistency, isolation, durability) properties, complex queries, joins, transactions, etc. DynamoDB is suitable for applications that need a NoSQL database with high scalability, low latency, flexible schema, etc. Redshift is suitable for applications that need a data warehouse with massively parallel processing, columnar storage, compression, etc.</p>
</li>
</ul>
<h3 id="heading-13-preference-for-hosting-a-website-on-s3-yes-or-no-explain-your-choice">13. Preference for hosting a website on S3: Yes or No? Explain your choice.</h3>
<p>My preference for hosting a website on S3 depends on the type and requirements of the website. If the website is static, meaning it consists of only HTML, CSS, JavaScript, and image files, without any server-side processing or database interaction, then I would choose S3 as a simple, cost-effective, and reliable option. However, if the website is dynamic, meaning it requires server-side scripting, database integration, or user input, then I would not choose S3, as it does not support these features.</p>
<p>Some of the advantages of hosting a static website on S3 are:</p>
<ul>
<li><p>It is simple and easy to set up and maintain. You just need to create a bucket, upload your files, configure your website settings, and make your bucket public. You don’t need to worry about server-side scripting, database management, or web server configuration.</p>
</li>
<li><p>It is cost-effective and scalable. You only pay for the storage space and bandwidth that you use, and you can scale up or down as needed. You can also take advantage of AWS services such as CloudFront, Lambda, and API Gateway to enhance your website performance, functionality, and security.</p>
</li>
<li><p>It is reliable and secure. Your website data is stored in durable and encrypted objects that are replicated across multiple regions for high availability. You can also use features such as versioning, lifecycle policies, access control lists (ACLs), encryption keys, etc., to protect your data from unauthorized access or loss.</p>
</li>
</ul>
<p>Thank you for reading my blog post. I hope you found it informative and engaging.</p>
<p>If you liked this post, please share it with your friends and colleagues who are interested in learning more about AWS interview questions.</p>
<p>Also, don’t forget to subscribe to my blog for more DevOps-related content every day.</p>
<p>Until next time,</p>
<p>Happy DevOps! 😊</p>
]]></content:encoded></item><item><title><![CDATA[Mastering AWS Elastic Container Service (ECS): A Key Component in your DevOps Journey]]></title><description><![CDATA[Hello, fellow DevOps enthusiasts! Today, we're diving deep into Amazon Web Services' Elastic Container Service (ECS).

In this post, I'll be sharing my insights and learnings about ECS, comparing it with Elastic Kubernetes Service (EKS), and guiding ...]]></description><link>https://blog.ajitfawade.com/mastering-aws-elastic-container-service-ecs-a-key-component-in-your-devops-journey</link><guid isPermaLink="true">https://blog.ajitfawade.com/mastering-aws-elastic-container-service-ecs-a-key-component-in-your-devops-journey</guid><category><![CDATA[AWS]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[Elastic Container Service]]></category><category><![CDATA[aws-fargate]]></category><category><![CDATA[containers]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Thu, 18 Jan 2024 19:21:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705605533499/1994efa8-74dc-4c35-9ab3-fdd57c2969a4.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello, fellow DevOps enthusiasts! Today, we're diving deep into Amazon Web Services' Elastic Container Service (ECS).</p>
<blockquote>
<p>In this post, I'll be sharing my insights and learnings about ECS, comparing it with Elastic Kubernetes Service (EKS), and guiding you through the process of setting up Nginx on ECS.</p>
</blockquote>
<p>So, let's get started!</p>
<h2 id="heading-what-is-ecs">What is ECS?</h2>
<p>ECS, or Elastic Container Service, is a fully managed container orchestration service offered by Amazon Web Services (AWS). Simply put, it's a service that allows you to run and manage Docker containers on a cluster of virtual machines (EC2 instances) without the need to handle the underlying infrastructure.</p>
<p>Think of ECS as a conductor overseeing an orchestra of containers. The conductor doesn't play any instrument but ensures they all play in perfect harmony. Similarly, ECS doesn't run the applications but ensures your containers are efficiently deployed, managed, and scaled.</p>
<p>The beauty of ECS lies in its versatility. You have the flexibility to choose between two launch types: "Fargate," where AWS manages the infrastructure, and "EC2," where you manage your own EC2 instances. ECS also integrates seamlessly with other AWS services like Elastic Load Balancing, Auto Scaling, Amazon VPC, and more, allowing you to build robust, scalable applications.</p>
<p>Moreover, ECS supports Docker Compose and Kubernetes, enabling you to adopt existing container workflows easily. All these features make ECS a powerful tool for managing containerized applications on AWS.</p>
<h2 id="heading-ecs-vs-eks-a-comparative-analysis">ECS vs. EKS: A Comparative Analysis</h2>
<p>Both ECS (Elastic Container Service) and EKS (Elastic Kubernetes Service) are Amazon's offerings in the realm of container orchestration. While they serve the same purpose, they differ significantly in their architectures, Kubernetes support, scaling mechanisms, flexibility, and community support.</p>
<h3 id="heading-architecture">Architecture</h3>
<p>ECS follows a centralized architecture where a single control plane manages the scheduling of containers on EC2 instances. On the other hand, EKS leverages a distributed architecture, with the Kubernetes control plane spread across multiple EC2 instances.</p>
<h3 id="heading-kubernetes-support">Kubernetes Support</h3>
<p>EKS is essentially a fully managed Kubernetes service. It allows you to run your Kubernetes workloads on AWS without worrying about managing the Kubernetes control plane. ECS, however, uses its own orchestration engine and lacks native Kubernetes support.</p>
<h3 id="heading-scaling">Scaling</h3>
<p>With EKS, your Kubernetes cluster can automatically scale based on demand. In contrast, ECS necessitates manual configuration of scaling policies for your tasks and services.</p>
<h3 id="heading-flexibility">Flexibility</h3>
<p>EKS offers greater flexibility than ECS as it allows you to customize and configure Kubernetes to meet your specific requirements. ECS, while effective, offers relatively less flexibility in terms of container orchestration options.</p>
<h3 id="heading-community">Community</h3>
<p>Kubernetes boasts a large and vibrant open-source community, which means EKS benefits from extensive community-driven development and support. ECS, however, has a smaller community and is primarily driven by AWS itself.</p>
<h2 id="heading-getting-hands-on-setting-up-nginx-on-ecs">Getting Hands-on: Setting up Nginx on ECS</h2>
<p>Now that we've understood the basics of ECS and how it compares with EKS, let's get our hands dirty and set up Nginx on ECS.</p>
<h3 id="heading-step-1-create-a-cluster">Step 1: Create a Cluster</h3>
<ol>
<li><p>Navigate to the AWS Management Console and open the Amazon ECS console.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705428518285/5aacf3b1-ae73-4b8a-be11-5120bf06d0fd.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on 'Create Cluster', and select the 'AWS Fargate' option.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705428538002/379c540f-3e0b-4edc-b45d-d9c43a54721b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Fill in the necessary details, including cluster name, instance type, and number of instances.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705428588760/ae91064b-74aa-432e-a534-c2ffb266647b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on 'Create'.</p>
</li>
</ol>
<h3 id="heading-step-2-create-a-task-definition">Step 2: Create a Task Definition</h3>
<ol>
<li><p>In the left-side navigation pane, choose 'Task Definitions', then 'Create new Task Definition'.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705603167033/cd78f54a-931e-4447-a1fd-2608465d87f7.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select 'AWS Fargate' launch type compatibility and click 'Next step'.</p>
</li>
<li><p>Specify the task name, task role, network mode, and task memory and CPU values.</p>
</li>
<li><p>Under 'Container Definitions', click 'Add container' and provide the necessary details, including image, memory limits, and port mappings.</p>
</li>
<li><p>Click on 'Add', then 'Create'.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604410302/ea95e912-afbc-4832-92be-5fd4e3eb8e99.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604433274/d61cb6e0-91e1-41c9-a4ed-73adbfeb1a5c.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604444870/2514c177-1efc-4ff2-ac46-52639321bf4a.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<h3 id="heading-step-3-create-a-service">Step 3: Create a Service</h3>
<ol>
<li><p>Return to your cluster page and click on 'Create' under 'Services'.</p>
</li>
<li><p>Select the task definition you created earlier, specify the service name, and choose the number of tasks to run.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604482426/c9e7a615-d322-45e7-93f2-87e3a4109ae7.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Configure network settings and load balancing as per your requirements.</p>
</li>
<li><p>Click on 'Next step', review your settings, and click 'Create'.</p>
</li>
</ol>
<blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604502618/061015ec-0716-4ec3-a6be-df4baaea59ef.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604522461/9283318a-5ec1-40fd-a493-9ab8df8ea9c0.png" alt class="image--center mx-auto" /></p>
</blockquote>
<p>And there you have it! You've successfully set up Nginx on ECS. This hands-on experience should give you a better understanding of how ECS operates and how it can be used to manage and orchestrate containerized applications.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604568225/f0927e08-7c16-4397-a3cf-ed456bac658c.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604589410/9c6d7716-731a-4dec-bdc9-8f38b8dc0747.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604618198/bfa3637a-6ae7-4fdb-b0ee-129b43ef6671.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705604651900/753bdd88-dbd5-4194-8c15-fe00a787c022.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As we delve deeper into our DevOps journey, we continue to explore and master powerful tools like AWS ECS. With its robust integration capabilities, ECS provides a versatile platform to efficiently manage Docker containers on the AWS cloud.</p>
<p>Despite being somewhat overshadowed by the popularity of Kubernetes and EKS, ECS still holds its ground as a reliable, AWS-native container orchestration service. Its unique features and advantages make it an excellent choice for certain use cases.</p>
<p>So, continue experimenting, learning, and sharing your knowledge with the DevOps community. Stay tuned for more exciting insights in our upcoming posts!</p>
<p>For additional resources on ECS, I recommend visiting the <a target="_blank" href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html">official AWS ECS documentation</a>.</p>
<p>Remember, the path to becoming a DevOps expert involves continuous learning and hands-on experience. So, keep exploring, keep learning, and keep growing.</p>
<p>Until next time, happy DevOps-ing!</p>
]]></content:encoded></item><item><title><![CDATA[How to Launch, Monitor, and Scale EC2 Instances Using AWS Console and CLI - A Practical Guide for DevOps Learners]]></title><description><![CDATA[Are you a DevOps learner who wants to test your knowledge on AWS by performing some hands-on tasks? If yes, then this blog post is for you. In this post, I’ll show you how to launch, monitor, and scale EC2 instances using AWS Console and CLI. You’ll ...]]></description><link>https://blog.ajitfawade.com/how-to-launch-monitor-and-scale-ec2-instances-using-aws-console-and-cli-a-practical-guide-for-devops-learners</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-launch-monitor-and-scale-ec2-instances-using-aws-console-and-cli-a-practical-guide-for-devops-learners</guid><category><![CDATA[Devops]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[aws ec2]]></category><category><![CDATA[autoscaling]]></category><category><![CDATA[#CloudWatch]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Thu, 07 Dec 2023 18:08:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1701971210261/cf620a1f-b85c-4a88-82b9-2ffe5abd0ed4.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a DevOps learner who wants to test your knowledge on AWS by performing some hands-on tasks? If yes, then this blog post is for you. In this post, I’ll show you how to launch, monitor, and scale EC2 instances using AWS Console and CLI. You’ll learn how to:</p>
<ul>
<li><p>Launch an EC2 instance using the AWS Management Console and connect to it using SSH</p>
</li>
<li><p>Install a web server on the EC2 instance and deploy a simple web application</p>
</li>
<li><p>Monitor the EC2 instance using Amazon CloudWatch and troubleshoot any issues that arise</p>
</li>
<li><p>Create an Auto Scaling group using the AWS Management Console and configure it to launch EC2 instances in response to changes in demand</p>
</li>
<li><p>Use Amazon CloudWatch to monitor the performance of the Auto Scaling group and the EC2 instances and troubleshoot any issues that arise</p>
</li>
<li><p>Use the AWS CLI to view the state of the Auto Scaling group and the EC2 instances and verify that the correct number of instances are running</p>
</li>
</ul>
<p>By the end of this post, you’ll be able to test your knowledge on AWS by performing some practical tasks that are relevant for DevOps learners. You’ll also gain more confidence and experience in using AWS services and tools.</p>
<blockquote>
<p><mark>This blog post is going to be lengthy and detailed, as I will explain each step of the tasks and provide screenshots and code snippets to help you follow along. I will also provide some tips and best practices to help you avoid common pitfalls and errors. I recommend that you have some basic knowledge of AWS and DevOps before reading this blog post, as I will not cover the fundamentals of these topics. If you are new to AWS and DevOps, you can check out my previous blogs to learn more.</mark></p>
</blockquote>
<h2 id="heading-how-to-launch-an-ec2-instance-using-the-aws-management-console-and-connect-to-it-using-ssh">How to Launch an EC2 Instance Using the AWS Management Console and Connect to It Using SSH</h2>
<blockquote>
<p>In this section, I’ll show you how to launch an EC2 instance using the AWS Management Console and connect to it using SSH. An EC2 instance is a virtual server that runs in the AWS cloud. You can use EC2 instances to run applications, host websites, or perform any other tasks that require computing power.</p>
</blockquote>
<h3 id="heading-step-1-choose-an-amazon-machine-image-ami">Step 1: Choose an Amazon Machine Image (AMI)</h3>
<p>To launch an EC2 instance, you need to choose an Amazon Machine Image (AMI), which is a template that contains the operating system and software configuration for your instance. You can choose from a variety of AMIs provided by AWS or other sources, or you can create your own AMI.</p>
<p>For this task, I’ll choose the Amazon Linux 2 AMI, which is a Linux-based AMI that is optimized for AWS. To choose an AMI, follow these steps:</p>
<ul>
<li><p>Go to the AWS Management Console and select <strong>EC2</strong> from the <strong>Services</strong> menu.</p>
</li>
<li><p>Click on <strong>Launch Instance</strong> to start the launch wizard.</p>
</li>
<li><p>On the <strong>Choose an Amazon Machine Image (AMI)</strong> page, find the <strong>Amazon Linux 2 AMI</strong> and click on <strong>Select</strong>.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701220347753/7cc1f880-b4b7-42f7-9c6a-5dd7f05d49d6.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-2-choose-an-instance-type">Step 2: Choose an Instance Type</h3>
<p>Next, you need to choose an instance type, which is a specification of the CPU, memory, storage, and networking capacity for your instance. You can choose from a variety of instance types depending on your needs and budget.</p>
<p>For this task, I’ll choose the t2.micro instance type, which is a general-purpose instance type that is eligible for the free tier. To choose an instance type, follow these steps:</p>
<ul>
<li>On the <strong>Choose an Instance Type</strong> page, find the <strong>t2.micro</strong> instance type and click on <strong>Next: Configure Instance Details</strong>.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701220417405/5c44ba36-b33f-40f8-88a2-0634fb2a8493.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-3-configure-instance-details">Step 3: Configure Instance Details</h3>
<p>Next, you need to configure some details for your instance, such as the number of instances, the network, the subnet, the security group, and the key pair. You can use the default settings for most of these options, or you can customize them according to your preferences.</p>
<p>For this task, I’ll use the default settings for most of the options, except for the following:</p>
<ul>
<li><p>I’ll enable <strong>Auto-assign Public IP</strong>, which will assign a public IP address to my instance so that I can connect to it from the internet.</p>
</li>
<li><p>I’ll create a new security group, which is a set of firewall rules that control the inbound and outbound traffic for my instance. I’ll name it <strong>WebServerSG</strong> and I’ll allow SSH access from anywhere and HTTP access from anywhere. This will allow me to connect to my instance using SSH and to access my web application using a web browser.</p>
</li>
<li><p>I’ll create a new key pair, which is a pair of cryptographic keys that are used to authenticate my connection to my instance. I’ll name it <strong>WebServerKP</strong> and I’ll download the private key file to my local machine. I’ll need this file later to connect to my instance using SSH.</p>
</li>
</ul>
<p>To configure the instance details, follow these steps:</p>
<ul>
<li><p>On the <strong>Configure Instance Details</strong> page, scroll down to the <strong>Network &amp; Security</strong> section and check the box for <strong>Auto-assign Public IP</strong>.</p>
</li>
<li><p>Scroll down to the <strong>Security Group</strong> section and select <strong>Create a new security group</strong>. Enter <strong>WebServerSG</strong> as the <strong>Security group name</strong> and <strong>Security group for web server</strong> as the <strong>Description</strong>.</p>
</li>
<li><p>Click on <strong>Add Rule</strong> and select <strong>SSH</strong> from the <strong>Type</strong> dropdown menu. Leave the <strong>Source</strong> as <strong>Anywhere</strong>. This will allow SSH access from any IP address.</p>
</li>
<li><p>Click on <strong>Add Rule</strong> again and select <strong>HTTP</strong> from the <strong>Type</strong> dropdown menu. Leave the <strong>Source</strong> as <strong>Anywhere</strong>. This will allow HTTP access from any IP address.</p>
</li>
<li><p>Click on <strong>Review and Launch</strong> to proceed to the next page.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701220624894/2809d87d-6d0c-44b5-b9d6-69ac36d5cdac.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Review Instance Launch</strong> page, click on <strong>Launch</strong> to launch your instance.</p>
</li>
<li><p>A dialog box will appear asking you to select a key pair. Select <strong>Create a new key pair</strong> from the <strong>Choose an existing key pair or create a new key pair</strong> dropdown menu. Enter <strong>ec2-connect</strong> as the <strong>Key pair name</strong> and click on <strong>Download Key Pair</strong>. Save the <strong>ec2-connect.pem</strong> file to your local machine. You’ll need this file later to connect to your instance using SSH.</p>
</li>
<li><p>Click on <strong>Launch Instances</strong> to launch your instance.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701220500475/fc61a2c3-af8e-45a6-81b7-60434f8f3929.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701220771353/3087b593-77ed-4de6-9c7b-7368a3ad2f67.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-4-connect-to-your-instance-using-ssh">Step 4: Connect to Your Instance Using SSH</h3>
<p>Next, you need to connect to your instance using SSH, which is a secure protocol that allows you to access a remote server using a command-line interface. To connect to your instance using SSH, you need the following:</p>
<ul>
<li><p>The public IP address of your instance, which you can find in the EC2 console under the <strong>Instances</strong> section.</p>
</li>
<li><p>The private key file that you downloaded in the previous step, which you need to store in a secure location and change its permissions to make it readable only by you.</p>
</li>
<li><p>A SSH client, which is a software that allows you to connect to a remote server using SSH. You can use any SSH client that you prefer, such as PuTTY, Terminal, or Git Bash.</p>
</li>
</ul>
<p>For this task, I’ll use Git Bash as my SSH client, which is a command-line tool that comes with Git, a version control system. To connect to your instance using SSH, follow these steps:</p>
<ul>
<li><p>Open Git Bash and navigate to the folder where you saved the <strong>ec2-connect.pem</strong> file. You can use the <strong>cd</strong> command to change directories and the <strong>ls</strong> command to list the files in the current directory.</p>
</li>
<li><p>Change the permissions of the <strong>ec2-connect.pem</strong> file to make it readable only by you. You can use the <strong>chmod</strong> command to change the permissions. The command is:</p>
</li>
</ul>
<pre><code class="lang-bash">chmod 400 ec2-connect.pem
</code></pre>
<ul>
<li>Connect to your instance using SSH. You can use the <strong>ssh</strong> command to connect to a remote server using SSH. The command is:</li>
</ul>
<pre><code class="lang-bash">ssh -i ec2-connect.pem ec2-user@&lt;public-ip-address-of-your-instance&gt;
</code></pre>
<p>Replace <code>&lt;public-ip-address-of-your-instance&gt;</code> with the actual public IP address of your instance, which you can find in the EC2 console. For example, if your instance’s public IP address is 54.123.456.789, the command is:</p>
<pre><code class="lang-bash">ssh -i ec2-connect.pem ec2-user@54.123.456.789
</code></pre>
<ul>
<li><p>The first time you connect to your instance, you may see a warning message asking you to confirm the identity of the host. Type <strong>yes</strong> and press <strong>Enter</strong> to continue. This will add the host to your list of known hosts and prevent the warning from appearing again.</p>
</li>
<li><p>You should see a welcome message and a command prompt that indicates that you are connected to your instance. The command prompt should look something like this:</p>
</li>
</ul>
<pre><code class="lang-bash">[ec2-user@ip-172-31-20-166 ~]$
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701220853958/02c7a6c8-33d5-4e27-a2b6-18c6a208602d.png" alt class="image--center mx-auto" /></p>
<p>Congratulations, you have successfully launched an EC2 instance using the AWS Management Console and connected to it using SSH. You can now run commands on your instance and install software on it.</p>
<h2 id="heading-how-to-install-a-web-server-on-your-ec2-instance-and-deploy-a-simple-web-application">How to Install a Web Server on Your EC2 Instance and Deploy a Simple Web Application</h2>
<blockquote>
<p>In this section, I’ll show you how to install a web server on your EC2 instance and deploy a simple web application. A web server is a software that handles HTTP requests and serves web pages or files to clients. A web application is software that runs on a web server and provides dynamic or interactive functionality to users.</p>
</blockquote>
<p>For this task, I’ll use Apache as my web server and Flask as my web application framework. Apache is a popular and open-source web server that can run on various operating systems. Flask is a lightweight and easy-to-use web application framework that is written in Python.</p>
<h3 id="heading-step-1-install-apache-on-your-ec2-instance">Step 1: Install Apache on Your EC2 Instance</h3>
<p>To install Apache on your EC2 instance, you need to run some commands on your instance using SSH. To install Apache, follow these steps:</p>
<ul>
<li><p>Connect to your instance using SSH, as shown in the previous section.</p>
</li>
<li><p>Update the package manager on your instance by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">sudo yum update -y
</code></pre>
<ul>
<li>Install Apache by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo yum install httpd -y
</code></pre>
<ul>
<li>Start Apache by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo systemctl start httpd
</code></pre>
<ul>
<li>Enable Apache to start automatically when your instance boots by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo systemctl <span class="hljs-built_in">enable</span> httpd
</code></pre>
<ul>
<li>Verify that Apache is running by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo systemctl status httpd
</code></pre>
<p>You should see a message that says <strong>active (running)</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701220938754/40e414c5-9ab1-4a54-9040-50ad9576c3ea.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-2-deploy-a-simple-web-application-on-your-ec2-instance">Step 2: Deploy a Simple Web Application on Your EC2 Instance</h3>
<p>Next, you need to deploy a simple web application on your EC2 instance. For this task, I’ll use Flask, which is a web application framework that is written in Python. To deploy a simple web application on your EC2 instance, you need to do the following:</p>
<ul>
<li><p>Install Python and pip on your EC2 instance</p>
</li>
<li><p>Install Flask and other dependencies on your EC2 instance</p>
</li>
<li><p>Create a simple web application using Flask</p>
</li>
<li><p>Configure Apache to serve your web application</p>
</li>
</ul>
<h4 id="heading-step-21-install-python-and-pip-on-your-ec2-instance">Step 2.1: Install Python and pip on Your EC2 Instance</h4>
<p>To install Python and pip on your EC2 instance, you need to run some commands on your instance using SSH. Python is a programming language that is widely used for web development. pip is a package manager that allows you to install and manage Python packages. To install Python and pip, follow these steps:</p>
<ul>
<li><p>Connect to your instance using SSH, as shown in the previous section.</p>
</li>
<li><p>Install Python by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">sudo yum install python3 -y
</code></pre>
<ul>
<li>Verify that Python is installed by running the following command:</li>
</ul>
<pre><code class="lang-bash">python3 --version
</code></pre>
<p>You should see a message that shows the version of Python, such as <strong>Python 3.7.16</strong>.</p>
<ul>
<li>Install pip by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo yum install python3-pip -y
</code></pre>
<ul>
<li>Verify that pip is installed by running the following command:</li>
</ul>
<pre><code class="lang-bash">pip3 --version
</code></pre>
<p>You should see a message that shows the version of pip, such as <strong>pip 20.2.2</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701220997721/90714e5c-7828-4ed9-a44e-22ba99d2d0b3.png" alt class="image--center mx-auto" /></p>
<h4 id="heading-step-22-install-flask-and-other-dependencies-on-your-ec2-instance">Step 2.2: Install Flask and Other Dependencies on Your EC2 Instance</h4>
<p>Next, you need to install Flask and other dependencies on your EC2 instance. Flask is a web application framework that is written in Python and allows you to create web applications with minimal code. To install Flask and other dependencies, follow these steps:</p>
<ul>
<li><p>Connect to your instance using SSH, as shown in the previous section.</p>
</li>
<li><p>Install Flask by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">pip3 install flask
</code></pre>
<ul>
<li>Install mod_wsgi, which is a module that allows Apache to serve Python web applications, by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo yum -y install python3-mod_wsgi.x86_64
</code></pre>
<ul>
<li>Install <code>virtualenv</code>, which is a tool that allows you to create isolated Python environments, by running the following command:</li>
</ul>
<pre><code class="lang-bash">pip3 install virtualenv
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701221144400/76bfade6-0811-4474-af20-f7dee8365895.png" alt class="image--center mx-auto" /></p>
<h4 id="heading-step-23-create-a-simple-web-application-using-flask">Step 2.3: Create a Simple Web Application Using Flask</h4>
<p>Next, you need to create a simple web application using Flask. For this task, I’ll create a web application that displays a message that says <strong>Hello, World!</strong> To create a simple web application using Flask, follow these steps:</p>
<ul>
<li><p>Connect to your instance using SSH, as shown in the previous section.</p>
</li>
<li><p>Create a directory for your web application by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">mkdir webapp
</code></pre>
<ul>
<li>Change to the webapp directory by running the following command:</li>
</ul>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> webapp
</code></pre>
<ul>
<li>Create a virtual environment for your web application by running the following command:</li>
</ul>
<pre><code class="lang-bash">virtualenv venv
</code></pre>
<ul>
<li>Activate the virtual environment by running the following command:</li>
</ul>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> venv/bin/activate
</code></pre>
<ul>
<li>Create a file named <a target="_blank" href="http://app.py"><strong>app.py</strong></a> that contains the code for your web application by running the following command:</li>
</ul>
<pre><code class="lang-bash">nano app.py
</code></pre>
<ul>
<li>Paste the following code into the file:</li>
</ul>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask

app = Flask(__name__)

<span class="hljs-meta">@app.route('/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello_world</span>():</span>
 <span class="hljs-keyword">return</span> <span class="hljs-string">'Hello World!'</span>

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
 app.run()
</code></pre>
<ul>
<li><p>Save and exit the file by pressing <strong>Ctrl+O</strong> and then <strong>Ctrl+X</strong>.</p>
</li>
<li><p>Run your web application by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">python3 app.py
</code></pre>
<p>You should see a message that says <strong>Running on</strong> <a target="_blank" href="http://127.0.0.1:5000/"><strong>http://127.0.0.1:5000/</strong></a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701222825491/3044595a-353a-4cdc-a02e-83af3a702ebd.png" alt class="image--center mx-auto" /></p>
<h4 id="heading-step-24-configure-apache-to-serve-your-web-application">Step 2.4: Configure Apache to Serve Your Web Application</h4>
<p>Next, you need to configure Apache to serve your web application. By default, Apache serves the files from the <strong>/var/www/html</strong> directory, which is the document root. You need to change the document root to point to your web application directory, which is <strong>/home/ec2-user/webapp</strong>. You also need to tell Apache to use mod_wsgi to handle the requests to your web application. To configure Apache to serve your web application, follow these steps:</p>
<ul>
<li><p>Connect to your instance using SSH, as shown in the previous section.</p>
</li>
<li><p>Stop your web application by pressing <strong>Ctrl+C</strong>.</p>
</li>
<li><p>Deactivate the virtual environment by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">deactivate
</code></pre>
<ul>
<li>Create a file named <strong>webapp.conf</strong> that contains the configuration for your web application by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo nano /etc/httpd/conf.d/webapp.conf
</code></pre>
<ul>
<li>Paste the following code into the file:</li>
</ul>
<pre><code class="lang-apache"><span class="hljs-section">&lt;VirtualHost *<span class="hljs-number">:80</span>&gt;</span>
    <span class="hljs-attribute"><span class="hljs-nomarkup">ServerName</span></span> ec<span class="hljs-number">2</span>-<span class="hljs-number">54</span>-<span class="hljs-number">123</span>-<span class="hljs-number">456</span>-<span class="hljs-number">789</span>.ap-south-<span class="hljs-number">1</span>.compute.amazonaws.com
    <span class="hljs-attribute"><span class="hljs-nomarkup">DocumentRoot</span></span> /home/ec<span class="hljs-number">2</span>-user/webapp
    <span class="hljs-attribute">WSGIDaemonProcess</span> webapp user=ec<span class="hljs-number">2</span>-user group=ec<span class="hljs-number">2</span>-user threads=<span class="hljs-number">5</span> home=/home/ec<span class="hljs-number">2</span>-user/webapp/venv
    <span class="hljs-attribute">WSGIScriptAlias</span> / /home/ec<span class="hljs-number">2</span>-user/webapp/app.wsgi
    <span class="hljs-section">&lt;Directory /home/ec2-user/webapp&gt;</span>
        <span class="hljs-attribute">WSGIProcessGroup</span> webapp
        <span class="hljs-attribute">WSGIApplicationGroup</span> <span class="hljs-variable">%{GLOBAL}</span>
        <span class="hljs-attribute">Require</span> <span class="hljs-literal">all</span> granted
    <span class="hljs-section">&lt;/Directory&gt;</span>
<span class="hljs-section">&lt;/VirtualHost&gt;</span>
</code></pre>
<p>Replace <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a> with the public DNS name of your instance, which you can find in the EC2 console under the <strong>Instances</strong> section.</p>
<ul>
<li><p>Save and exit the file by pressing <strong>Ctrl+O</strong> and then <strong>Ctrl+X</strong>.</p>
</li>
<li><p>Create a file named <strong>app.wsgi</strong> that contains the code to initialize your web application by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">nano /home/ec2-user/webapp/app.wsgi
</code></pre>
<ul>
<li>Paste the following code into the file:</li>
</ul>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> sys
sys.path.insert(<span class="hljs-number">0</span>, <span class="hljs-string">'/home/ec2-user/webapp'</span>)
<span class="hljs-keyword">from</span> app <span class="hljs-keyword">import</span> app <span class="hljs-keyword">as</span> application
</code></pre>
<ul>
<li><p>Save and exit the file by pressing <strong>Ctrl+O</strong> and then <strong>Ctrl+X</strong>.</p>
</li>
<li><p>Restart Apache by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">sudo systemctl restart httpd
</code></pre>
<h3 id="heading-step-3-test-your-web-application">Step 3: Test Your Web Application</h3>
<p>Finally, you need to test your web application by accessing it from a web browser. To test your web application, follow these steps:</p>
<ul>
<li><p>Open a web browser and enter the public DNS name of your instance in the address bar. For example, if your instance’s public DNS name is <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a>, enter <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a> in the address bar.</p>
</li>
<li><p>You should see a web page that displays a message that says <strong>Hello, World!</strong> This means that your web application is working and being served by Apache.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701224753408/55939b6e-e49b-46fe-9e59-7a699bf64568.png" alt class="image--center mx-auto" /></p>
<p>Congratulations, you have successfully installed a web server on your EC2 instance and deployed a simple web application. You can now modify your web application code and see the changes reflected on your web page.</p>
<h2 id="heading-how-to-monitor-your-ec2-instance-using-amazon-cloudwatch-and-troubleshoot-any-issues-that-arise">How to Monitor Your EC2 Instance Using Amazon CloudWatch and Troubleshoot Any Issues That Arise</h2>
<blockquote>
<p>In this section, I’ll show you how to monitor your EC2 instance using Amazon CloudWatch and troubleshoot any issues that arise. Amazon CloudWatch is a service that monitors your AWS resources and the applications you run on AWS in real-time. You can use CloudWatch to collect and track metrics, which are variables you can measure for your resources and applications. You can also use CloudWatch to set alarms, which are rules that trigger actions when a metric crosses a specified threshold. You can also use CloudWatch to create dashboards, which are customizable web pages that display graphs and tables of your metrics and alarms.</p>
</blockquote>
<p>For this task, I’ll use CloudWatch to monitor the CPU utilization, disk usage, and network traffic of my EC2 instance. I’ll also set an alarm that sends me an email when the CPU utilization of my EC2 instance exceeds 80%. I’ll also create a dashboard that shows the metrics and the alarm of my EC2 instance.</p>
<h3 id="heading-step-1-enable-cloudwatch-monitoring-for-your-ec2-instance">Step 1: Enable CloudWatch Monitoring for Your EC2 Instance</h3>
<p>To enable CloudWatch monitoring for your EC2 instance, you need to do the following:</p>
<ul>
<li><p>Enable detailed monitoring for your EC2 instance, which will send metrics to CloudWatch every minute instead of every five minutes. This will give you more granular and timely data about your instance performance.</p>
</li>
<li><p>Install and configure the CloudWatch agent on your EC2 instance, which will collect and send custom metrics to CloudWatch, such as disk usage and memory usage. The CloudWatch agent is software that runs on your EC2 instance and communicates with CloudWatch.</p>
</li>
</ul>
<p>To enable detailed monitoring for your EC2 instance, follow these steps:</p>
<ul>
<li><p>Go to the AWS Management Console and select <strong>EC2</strong> from the <strong>Services</strong> menu.</p>
</li>
<li><p>Select your EC2 instance from the <strong>Instances</strong> section click on <strong>Actions</strong> and then <strong>Instance Settings</strong> and then <strong>Change Monitoring Settings</strong>.</p>
</li>
<li><p>Check the box for <strong>Enable detailed monitoring</strong> and click on <strong>Save</strong>.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701226105195/ed60a77f-82eb-4237-9160-ac5f6e7ae839.png" alt class="image--center mx-auto" /></p>
<p>To install and configure the CloudWatch agent on your EC2 instance, follow these steps:</p>
<ul>
<li><p>Connect to your EC2 instance using SSH, as shown in the previous section.</p>
</li>
<li><p>Download the CloudWatch agent package by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
</code></pre>
<ul>
<li>Install the CloudWatch agent package by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo rpm -U ./amazon-cloudwatch-agent.rpm
</code></pre>
<ul>
<li>Create a configuration file for the CloudWatch agent by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
</code></pre>
<ul>
<li><p>Follow the prompts to configure the CloudWatch agent. You can use the default settings for most of the options, or you can customize them according to your preferences. For this task, I’ll use the following settings:</p>
<ul>
<li><p>Select <strong>1</strong> for <strong>On which OS are you planning to use the agent?</strong></p>
</li>
<li><p>Select <strong>2</strong> for <strong>Are you using EC2 or On-Premises hosts?</strong></p>
</li>
<li><p>Select <strong>Yes</strong> for <strong>Do you want to turn on StatsD daemon?</strong></p>
</li>
<li><p>Select <strong>No</strong> for <strong>Do you want to monitor metrics from CollectD?</strong></p>
</li>
<li><p>Select <strong>Yes</strong> for <strong>Do you want to monitor any host metrics? e.g. CPU, memory, etc.</strong></p>
</li>
<li><p>Select <strong>Basic</strong> for <strong>Which default metrics config do you want?</strong></p>
</li>
<li><p>Select <strong>Yes</strong> for <strong>Do you want to monitor any customized metrics?</strong></p>
</li>
<li><p>Select <strong>Yes</strong> for <strong>Do you have any existing CloudWatch Log Agent?</strong></p>
</li>
<li><p>Select <strong>No</strong> for <strong>Do you want to monitor log files?</strong></p>
</li>
<li><p>Select <strong>No</strong> for <strong>Do you want to store the config in the SSM parameter store?</strong></p>
</li>
</ul>
</li>
<li><p>The configuration file will be saved as <strong>/opt/aws/amazon-cloudwatch-agent/bin/config.json</strong>. You can view or edit the file by running the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">sudo nano /opt/aws/amazon-cloudwatch-agent/bin/config.json
</code></pre>
<ul>
<li>Start the CloudWatch agent by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s
</code></pre>
<ul>
<li>Verify that the CloudWatch agent is running by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
</code></pre>
<p>You should see a message that says <strong>amazon-cloudwatch-agent is running</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701226715996/3e42ad4a-bd85-4095-8bea-ba47e1ed919c.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-2-set-an-alarm-that-sends-you-an-email-when-the-cpu-utilization-of-your-ec2-instance-exceeds-80">Step 2: Set an Alarm that Sends You an Email When the CPU Utilization of Your EC2 Instance Exceeds 80%</h3>
<p>Next, you need to set an alarm that sends you an email when the CPU utilization of your EC2 instance exceeds 80%. An alarm is a rule that triggers an action when a metric crosses a specified threshold. For this task, I’ll use the following settings for the alarm:</p>
<ul>
<li><p>The metric is the CPU utilization of my EC2 instance, which is the percentage of CPU resources that are being used by my instance.</p>
</li>
<li><p>The threshold is 80%, which means that the alarm will trigger when the CPU utilization of my instance is greater than or equal to 80% for a specified period of time.</p>
</li>
<li><p>The period is 5 minutes, which means that the alarm will evaluate the metric every 5 minutes and compare it with the threshold.</p>
</li>
<li><p>The statistic is the average, which means that the alarm will use the average value of the metric over the period.</p>
</li>
<li><p>The action is to send an email to my email address, which is the notification that I’ll receive when the alarm triggers.</p>
</li>
</ul>
<p>To set an alarm that sends you an email when the CPU utilization of your EC2 instance exceeds 80%, follow these steps:</p>
<ul>
<li><p>Go to the AWS Management Console and select <strong>CloudWatch</strong> from the <strong>Services</strong> menu.</p>
</li>
<li><p>Click on <strong>Alarms</strong> from the left navigation pane and then click on <strong>Create alarm</strong>.</p>
</li>
<li><p>On the <strong>Select metric</strong> page, find the <strong>EC2</strong> section and expand it. Then find the <strong>Per-Instance Metrics</strong> section and expand it. Then find the <strong>CPUUtilization</strong> metric for your EC2 instance and select it. Then click on <strong>Select metric</strong>.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701226870127/ae1fe270-0123-491c-89a0-16c61c8c4cf7.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Define alarm</strong> page, enter the following settings for the alarm:</p>
<ul>
<li><p>Enter <strong>CPUAlarm</strong> as the <strong>Name</strong> and <strong>Alarm when CPU utilization exceeds 80%</strong> as the <strong>Description</strong>.</p>
</li>
<li><p>Select <strong>Greater than or equal to</strong> from the <strong>Whenever</strong> dropdown menu and enter <strong>80</strong> in the <strong>threshold</strong> box.</p>
</li>
<li><p>Select <strong>5 minutes</strong> from the <strong>Period</strong> dropdown menu and select <strong>Average</strong> from the <strong>Statistic</strong> dropdown menu.</p>
</li>
<li><p>Select <strong>1 out of 1</strong> from the <strong>Datapoints to alarm</strong> dropdown menu and select <strong>5 minutes</strong> from the <strong>Missing data treatment</strong> dropdown menu.</p>
</li>
</ul>
</li>
<li><p>Click on <strong>Next</strong> to proceed to the next page.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701226955117/2f8d0cd8-a55d-4eb7-a801-86ca49629c7c.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Configure actions</strong> page, enter the following settings for the action:</p>
<ul>
<li><p>Select <strong>In alarm</strong> from the <strong>Whenever this alarm</strong> dropdown menu and select <strong>Create a new topic</strong> from the <strong>Select an SNS topic</strong> dropdown menu.</p>
</li>
<li><p>Enter <strong>CPUNotification</strong> as the <strong>Topic name</strong> and enter your email address in the <strong>Email endpoints</strong> box.</p>
</li>
<li><p>Click on <strong>Create topic</strong> to create the SNS topic, which is a communication channel that delivers messages to subscribers.</p>
</li>
</ul>
</li>
<li><p>Click on <strong>Next</strong> to proceed to the next page.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701227490224/affb3a5b-42db-4ea0-9636-14da053ba1f7.png" alt class="image--center mx-auto" /></p>
<ul>
<li>On the <strong>Add description</strong> page, review the summary of your alarm and click on <strong>Create alarm</strong> to create your alarm.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701227660373/f1d09eab-8115-4685-9d63-0a7c854d755b.png" alt class="image--center mx-auto" /></p>
<ul>
<li>You should receive an email from AWS asking you to confirm your subscription to the SNS topic. Click on the link in the email to confirm your subscription. This will allow you to receive notifications from the SNS topic when the alarm triggers.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701227720185/674cf27f-5576-4eed-82d0-d16b227e104a.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-3-create-a-dashboard-that-shows-the-metrics-and-the-alarm-of-your-ec2-instance">Step 3: Create a Dashboard that Shows the Metrics and the Alarm of Your EC2 Instance</h3>
<p>Finally, you need to create a dashboard that shows the metrics and the alarm of your EC2 instance. A dashboard is a customizable web page that displays graphs and tables of your metrics and alarms. You can use dashboards to visualize the performance and health of your resources and applications.</p>
<p>For this task, I’ll create a dashboard that shows the following:</p>
<ul>
<li><p>A line graph that shows the CPU utilization of my EC2 instance over time</p>
</li>
<li><p>A line graph that shows the disk usage of my EC2 instance over time</p>
</li>
<li><p>A line graph that shows the network traffic of my EC2 instance over time</p>
</li>
<li><p>A table that shows the status of my alarm and the current value of the CPU utilization of my EC2 instance</p>
</li>
</ul>
<p>To create a dashboard that shows the metrics and the alarm of your EC2 instance, follow these steps:</p>
<ul>
<li><p>Go to the AWS Management Console and select <strong>CloudWatch</strong> from the <strong>Services</strong> menu.</p>
</li>
<li><p>Click on <strong>Dashboards</strong> from the left navigation pane and then click on <strong>Create dashboard</strong>.</p>
</li>
<li><p>Enter <strong>EC2Dashboard</strong> as the <strong>Dashboard name</strong> and click on <strong>Create dashboard</strong>.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701227933946/ed0f1a80-69de-442e-8588-010d6d12726f.png" alt class="image--center mx-auto" /></p>
<ul>
<li>On the <strong>Add to dashboard</strong> page, select <strong>Line</strong> from the <strong>All widgets</strong> section and click on <strong>Configure</strong>.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701227978660/039fea01-8cc8-49b3-9526-7c4f42f7f287.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Line widget configuration</strong> page, enter the following settings for the widget:</p>
<ul>
<li><p>Enter <strong>CPU Utilization</strong> as the <strong>Title</strong>.</p>
</li>
<li><p>Select <strong>EC2</strong> from the <strong>Service</strong> dropdown menu and select <strong>Per-Instance Metrics</strong> from the <strong>Metric name</strong> dropdown menu.</p>
</li>
<li><p>Find the <strong>CPUUtilization</strong> metric for your EC2 instance and select it. You can use the search box to filter the metrics by the instance ID or the name tag of your instance.</p>
</li>
<li><p>Select <strong>1 Minute</strong> from the <strong>Period</strong> dropdown menu and select <strong>Average</strong> from the <strong>Statistic</strong> dropdown menu.</p>
</li>
<li><p>Click on <strong>Create widget</strong> to add the widget to your dashboard.</p>
</li>
</ul>
</li>
</ul>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701229316660/8e785960-62c5-4117-b768-043f09584a55.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>Repeat the same steps to add another line widget for the disk usage metric. Use the following settings for the widget:</p>
<ul>
<li><p>Enter <strong>Disk Usage</strong> as the <strong>Title</strong>.</p>
</li>
<li><p>Select <strong>CWAgent</strong> from the <strong>Service</strong> dropdown menu and select <strong>disk_used_percent</strong> from the <strong>Metric name</strong> dropdown menu.</p>
</li>
<li><p>Find the <strong>disk_used_percent</strong> metric for your EC2 instance and select it. You can use the search box to filter the metrics by the instance ID or the name tag of your instance.</p>
</li>
<li><p>Select <strong>1 Minute</strong> from the <strong>Period</strong> dropdown menu and select <strong>Average</strong> from the <strong>Statistic</strong> dropdown menu.</p>
</li>
<li><p>Click on <strong>Create widget</strong> to add the widget to your dashboard.</p>
</li>
</ul>
</li>
</ul>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701918699241/6abadff0-55c5-43ae-97b3-913af098fbfc.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>Repeat the same steps to add another line widget for the network traffic metric. Use the following settings for the widget:</p>
<ul>
<li><p>Enter <strong>Network Traffic</strong> as the <strong>Title</strong>.</p>
</li>
<li><p>Select <strong>EC2</strong> from the <strong>Service</strong> dropdown menu and select <strong>Per-Instance Metrics</strong> from the <strong>Metric name</strong> dropdown menu.</p>
</li>
<li><p>Find the <strong>NetworkIn</strong> and <strong>NetworkOut</strong> metrics for your EC2 instance and select them. You can use the search box to filter the metrics by the instance ID or the name tag of your instance.</p>
</li>
<li><p>Select <strong>1 Minute</strong> from the <strong>Period</strong> dropdown menu and select <strong>Average</strong> from the <strong>Statistic</strong> dropdown menu.</p>
</li>
<li><p>Click on <strong>Create widget</strong> to add the widget to your dashboard.</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701229295853/6b92d2c5-c71c-4308-9668-8f7125be5bac.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Add to dashboard</strong> page, select <strong>Text</strong> from the <strong>All widgets</strong> section and click on <strong>Configure</strong>.</p>
</li>
<li><p>On the <strong>Text widget configuration</strong> page, enter the following settings for the widget:</p>
<ul>
<li><p>Enter <strong>Alarm Status</strong> as the <strong>Title</strong>.</p>
</li>
<li><p>Select <strong>Markdown</strong> from the <strong>Content type</strong> dropdown menu and enter the following code in the <strong>Content</strong> box:</p>
</li>
</ul>
</li>
</ul>
<pre><code class="lang-markdown">| Alarm Name | Alarm Status | Current Value |
| --- | --- | --- |
| [CPUAlarm] | {{alarm.CPUAlarm.state}} | {{alarm.CPUAlarm.currentValue}}% |
</code></pre>
<p>Replace <code>^1^</code> with the URL of your alarm, which you can find in the CloudWatch console under the <strong>Alarms</strong> section.</p>
<ul>
<li>Click on <strong>Create widget</strong> to add the widget to your dashboard.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701919046131/fd2df9d5-bf49-4a03-924a-c9aad6d165f3.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>You can resize and rearrange the widgets on your dashboard by dragging and dropping them. You can also edit or delete the widgets by clicking on the <strong>Actions</strong> menu on the top right corner of each widget.</p>
</li>
<li><p>Click on <strong>Save dashboard</strong> to save your dashboard.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701919174694/8d7d8885-53bb-4e1b-814a-41bb767e7b41.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-4-test-your-dashboard-and-your-alarm">Step 4: Test Your Dashboard and Your Alarm</h3>
<p>Finally, you need to test your dashboard and your alarm by generating some load on your EC2 instance and observing the changes in the metrics and the alarm status. To test your dashboard and your alarm, follow these steps:</p>
<ul>
<li><p>Open a web browser and enter the public DNS name of your instance in the address bar. For example, if your instance’s public DNS name is <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a>, enter <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a> in the address bar.</p>
</li>
<li><p>You should see a web page that displays a message that says <strong>Hello, World!</strong>. This is your web application that is running on your EC2 instance.</p>
</li>
<li><p>Open another tab in your web browser and enter the URL of your dashboard, which you can find in the CloudWatch console under the <strong>Dashboards</strong> section. For example, if your dashboard name is <strong>EC2Dashboard</strong>, enter <a target="_blank" href="https://console.aws.amazon.com/cloudwatch/home?region=ap-south-1#dashboards:name=EC2Dashboard"><code>https://console.aws.amazon.com/cloudwatch/home?region=ap-south-1#dashboards:name=EC2Dashboard</code></a> in the address bar.</p>
</li>
<li><p>You should see your dashboard that shows the metrics and the alarm of your EC2 instance. You can refresh the dashboard by clicking on the <strong>Refresh</strong> button on the top right corner of the dashboard.</p>
</li>
<li><p>To generate some load on your EC2 instance, you can use a tool called <strong>ApacheBench</strong>, which is a command-line tool that can be used to test the performance of a web server by sending multiple requests to it. You can install ApacheBench on your local machine by following the instructions on this [link].</p>
</li>
<li><p>To use ApacheBench, you need to open a terminal or a command prompt on your local machine and run the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">ab -n 1000 -c 10 http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com/
</code></pre>
<p>Replace <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a> with the public DNS name of your instance. This command will send 1000 requests to your web application with a concurrency of 10, which means that 10 requests will be sent at a time.</p>
<ul>
<li>You should see some output that shows the results of the test, such as the number of requests per second, the time per request, and the percentage of requests that completed within a certain time.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701229995693/bbab8f8c-a5e3-4724-b8ac-7373fb40cc9c.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>While the test is running, switch to the tab that shows your dashboard and refresh it. You should see the changes in the metrics and the alarm status of your EC2 instance. You should see the CPU utilization, disk usage, and network traffic increase as the load on your instance increases. You should also see the alarm status change from <strong>OK</strong> to <strong>ALARM</strong> when the CPU utilization of your instance exceeds 80%.</p>
</li>
<li><p>You should also receive an email from AWS notifying you that your alarm has triggered. The email should look something like this:</p>
</li>
<li><p>To stop the test, press <strong>Ctrl+C</strong> on your terminal or command prompt. You should see the metrics and the alarm status of your EC2 instance return to normal after the test is stopped.</p>
</li>
</ul>
<p>Congratulations, you have successfully monitored your EC2 instance using Amazon CloudWatch and troubleshooted any issues that arose. You can now use CloudWatch to monitor and manage your AWS resources and applications.</p>
<h2 id="heading-how-to-create-an-auto-scaling-group-using-the-aws-management-console-and-configure-it-to-launch-ec2-instances-in-response-to-changes-in-demand">How to Create an Auto Scaling Group Using the AWS Management Console and Configure It to Launch EC2 Instances in Response to Changes in Demand</h2>
<blockquote>
<p>In this section, I’ll show you how to create an Auto Scaling group using the AWS Management Console and configure it to launch EC2 instances in response to changes in demand. An Auto Scaling group is a collection of EC2 instances that can scale up or down automatically based on the load or the rules that you define. You can use Auto Scaling to improve the availability and performance of your applications, as well as to reduce the cost and complexity of managing your resources.</p>
</blockquote>
<p>For this task, I’ll use the following settings for the Auto Scaling group:</p>
<ul>
<li><p>The Auto Scaling group will use the same AMI, instance type, security group, and key pair as the EC2 instance that I created in the previous section.</p>
</li>
<li><p>The Auto Scaling group will have a minimum size of 1, a maximum size of 3, and a desired capacity of 1, which means that it will start with 1 instance and can scale up to 3 instances or scale down to 1 instance depending on the demand.</p>
</li>
<li><p>The Auto Scaling group will use a scaling policy that will add 1 instance when the average CPU utilization of the group exceeds 80% for 5 minutes and will remove 1 instance when the average CPU utilization of the group falls below 40% for 5 minutes.</p>
</li>
<li><p>The Auto Scaling group will use a health check that will monitor the status of the instances and replace any unhealthy instances with new ones.</p>
</li>
</ul>
<p>To create an Auto Scaling group using the AWS Management Console and configure it to launch EC2 instances in response to changes in demand, follow these steps:</p>
<h3 id="heading-step-1-create-a-launch-configuration">Step 1: Create a Launch Configuration</h3>
<p>To create an Auto Scaling group, you need to create a launch configuration, which is a template that specifies the configuration of the instances that will be launched by the Auto Scaling group. You can use the same launch configuration for multiple Auto Scaling groups. To create a launch configuration, follow these steps:</p>
<ul>
<li><p>Go to the AWS Management Console and select <strong>EC2</strong> from the <strong>Services</strong> menu.</p>
</li>
<li><p>Click on <strong>Launch Templates</strong> from the left navigation pane and then click on <strong>Create launch template</strong>.</p>
</li>
<li><p>On the <strong>Choose AMI</strong> page, find the <strong>Amazon Linux 2 AMI</strong> and click on <strong>Select</strong>. This is the same AMI that I used for the EC2 instance in the previous section.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701920742468/8aec36b5-3857-487a-85cc-72e891abb4f6.png" alt class="image--center mx-auto" /></p>
<ul>
<li>On the <strong>Choose Instance Type</strong> page, find the <strong>t2.micro</strong> instance type and click on <strong>Next: Configure details</strong>. This is the same instance type that I used for the EC2 instance in the previous section.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701920776168/9de9b9e2-3a68-4264-b00b-e4853e79c5ff.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Configure details</strong> page, enter the following settings for the launch configuration:</p>
<ul>
<li><p>Enter <strong>WebServerLC</strong> as the <strong>Name</strong> and <strong>Launch template for web server</strong> as the <strong>Description</strong>.</p>
</li>
<li><p>Check the box for <strong>Enable CloudWatch detailed monitoring</strong>, which will send metrics to CloudWatch every minute instead of every five minutes.</p>
</li>
<li><p>Select <strong>WebServerSG</strong> from the <strong>Security groups</strong> dropdown menu. This is the same security group that I created for the EC2 instance in the previous section.</p>
</li>
<li><p>Select <strong>WebServerKP</strong> from the <strong>Key pair</strong> dropdown menu. This is the same key pair that I created for the EC2 instance in the previous section.</p>
</li>
</ul>
</li>
<li><p>Click on <strong>Next: Add Storage</strong> to proceed to the next page.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701920999042/5f889182-ec9f-4f32-9c94-381b83a3b496.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701920952437/9a6a84ba-dc60-4ac1-b19c-b5fb1ef6007e.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Add Storage</strong> page, use the default settings for the storage and click on <strong>Next: Configure Security Group</strong> to proceed to the next page.</p>
</li>
<li><p>On the <strong>Configure Security Group</strong> page, use the default settings for the security group and click on <strong>Review</strong> to proceed to the next page.</p>
</li>
<li><p>On the <strong>Review</strong> page, review the summary of your launch configuration and click on <strong>Create launch configuration</strong> to create your launch configuration.</p>
</li>
</ul>
<h3 id="heading-step-2-create-an-auto-scaling-group">Step 2: Create an Auto Scaling Group</h3>
<p>Next, you need to create an Auto Scaling group using the launch configuration that you created in the previous step. To create an Auto Scaling group, follow these steps:</p>
<ul>
<li>On the <strong>Create Auto Scaling Group</strong> page, enter <strong>WebServerASG</strong> as the <strong>Group name</strong> and click on <strong>Next</strong>.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701921262984/5cafdb85-bf69-470d-8afd-58c28eda6a98.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Configure group size and scaling policies</strong> page, enter the following settings for the Auto Scaling group:</p>
<ul>
<li><p>Enter <strong>1</strong> in the <strong>Group size</strong> box, which is the number of instances that will be launched initially by the Auto Scaling group.</p>
</li>
<li><p>Enter <strong>1</strong> in the <strong>Minimum capacity</strong> box, which is the minimum number of instances that the Auto Scaling group will maintain at any time.</p>
</li>
<li><p>Enter <strong>3</strong> in the <strong>Maximum capacity</strong> box, which is the maximum number of instances that the Auto Scaling group will launch at any time.</p>
</li>
<li><p>Select <strong>Use scaling policies to adjust the capacity of this group</strong> from the <strong>Scaling policies</strong> section, which will allow you to define rules for scaling up or down the Auto Scaling group based on the load or the metrics.</p>
</li>
<li><p>Click on <strong>Add policy</strong> and select <strong>Target tracking scaling policy</strong> from the <strong>Policy type</strong> dropdown menu, which will allow you to specify a target value for a metric that the Auto Scaling group will try to maintain.</p>
</li>
<li><p>Enter <strong>CPUScalingPolicy</strong> as the <strong>Policy name</strong> and select <strong>Average CPU Utilization</strong> from the <strong>Metric type</strong> dropdown menu, which is the metric that the Auto Scaling group will use to scale up or down.</p>
</li>
<li><p>Enter <strong>80</strong> in the <strong>Target value</strong> box, which is the target value for the average CPU utilization that the Auto Scaling group will try to maintain.</p>
</li>
<li><p>Click on <strong>Create</strong> to create the scaling policy.</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701921481205/2bda98ac-be0b-47fb-9665-3144af5a3247.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>Click on <strong>Next: Configure Notifications</strong> to proceed to the next page.</p>
</li>
<li><p>On the <strong>Configure Notifications</strong> page, use the default settings for the notifications and click on <strong>Next: Configure Tags</strong> to proceed to the next page.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701921591146/47db17ca-e492-4046-ab9a-3c5a205d62d4.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>On the <strong>Configure Tags</strong> page, use the default settings for the tags and click on <strong>Review</strong> to proceed to the next page.</p>
</li>
<li><p>On the <strong>Review</strong> page, review the summary of your Auto Scaling group and click on <strong>Create Auto Scaling group</strong> to create your Auto Scaling group.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701921679661/c264584b-9275-46a5-aa24-ef36842edd59.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-3-monitor-the-performance-of-the-auto-scaling-group-and-the-ec2-instances-and-troubleshoot-any-issues-that-arise">Step 3: Monitor the Performance of the Auto Scaling Group and the EC2 Instances and Troubleshoot Any Issues That Arise</h3>
<p>Next, you need to monitor the performance of the Auto Scaling group and the EC2 instances and troubleshoot any issues that arise. You can use CloudWatch to monitor the metrics and the alarms of the Auto Scaling group and the EC2 instances. You can also use the AWS CLI to view the state of the Auto Scaling group and the EC2 instances and verify that the correct number of instances are running.</p>
<p>To monitor the performance of the Auto Scaling group and the EC2 instances and troubleshoot any issues that arise, follow these steps:</p>
<ul>
<li><p>Go to the AWS Management Console and select <strong>CloudWatch</strong> from the <strong>Services</strong> menu.</p>
</li>
<li><p>Click on <strong>Alarms</strong> from the left navigation pane and find the alarm that was created by the Auto Scaling group, which should have the name <strong>WebServerASG-CPUAlarm</strong>. This alarm will trigger when the average CPU utilization of the Auto Scaling group exceeds 80% for 5 minutes and will cause the Auto Scaling group to add 1 instance.</p>
</li>
<li><p>Click on the alarm name to see the details of the alarm, such as the metric, the threshold, the period, the statistic, and the status. You can also see the history of the alarm, such as when it was created, when it changed state, and when it triggered actions.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701921847499/77de7897-4cb7-4652-9ac7-8a3234ec4537.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Click on <strong>Metrics</strong> from the left navigation pane and find the metrics that are related to the Auto Scaling group and the EC2 instances, such as the <strong>GroupTotalInstances</strong>, <strong>GroupInServiceInstances</strong>, <strong>GroupPendingInstances</strong>, <strong>GroupTerminatingInstances</strong>, <strong>CPUUtilization</strong>, <strong>DiskSpaceUtilization</strong>, and <strong>NetworkIn</strong>. You can select multiple metrics and see them on the same graph. You can also change the time range and the statistic of the metrics.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701922058367/f138ba32-3702-4d10-b988-b32fda4ced9a.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>To view the state of the Auto Scaling group and the EC2 instances using the AWS CLI, you need to install and configure the AWS CLI on your local machine. You can follow the instructions on this [link] to install and configure the AWS CLI.</p>
</li>
<li><p>To view the state of the Auto Scaling group using the AWS CLI, you can use the <strong>describe-auto-scaling-groups</strong> command, which will show you the details of the Auto Scaling group, such as the name, the launch configuration, the size, the scaling policies, and the instances. The command is:</p>
</li>
</ul>
<pre><code class="lang-bash">aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names WebServerASG
</code></pre>
<p>Replace <code>WebServerASG</code> with the name of your Auto Scaling group.</p>
<ul>
<li>You should see some output that shows the details of your Auto Scaling group, such as the name, the launch configuration, the size, the scaling policies, and the instances. The output should look something like this:</li>
</ul>
<pre><code class="lang-json">{
    <span class="hljs-attr">"AutoScalingGroups"</span>: [
        {
            <span class="hljs-attr">"AutoScalingGroupName"</span>: <span class="hljs-string">"WebServerASG"</span>,
            <span class="hljs-attr">"AutoScalingGroupARN"</span>: <span class="hljs-string">"arn:aws:autoscaling:ap-south-1:123456789012:autoScalingGroup:1234abcd-5678-efgh-9012-3456ijklmnop:autoScalingGroupName/WebServerASG"</span>,
            <span class="hljs-attr">"LaunchTemplateName"</span>: <span class="hljs-string">"WebServerLT"</span>,
            <span class="hljs-attr">"MinSize"</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">"MaxSize"</span>: <span class="hljs-number">3</span>,
            <span class="hljs-attr">"DesiredCapacity"</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">"DefaultCooldown"</span>: <span class="hljs-number">300</span>,
            <span class="hljs-attr">"AvailabilityZones"</span>: [
                <span class="hljs-string">"ap-south-1a"</span>,
                <span class="hljs-string">"ap-south-1b"</span>,
                <span class="hljs-string">"ap-south-1c"</span>
            ],
            <span class="hljs-attr">"LoadBalancerNames"</span>: [],
            <span class="hljs-attr">"TargetGroupARNs"</span>: [],
            <span class="hljs-attr">"HealthCheckType"</span>: <span class="hljs-string">"EC2"</span>,
            <span class="hljs-attr">"HealthCheckGracePeriod"</span>: <span class="hljs-number">300</span>,
            <span class="hljs-attr">"Instances"</span>: [
                {
                    <span class="hljs-attr">"InstanceId"</span>: <span class="hljs-string">"i-0a1b2c3d4e5f6g7h8"</span>,
                    <span class="hljs-attr">"InstanceType"</span>: <span class="hljs-string">"t2.micro"</span>,
                    <span class="hljs-attr">"AvailabilityZone"</span>: <span class="hljs-string">"ap-south-1a"</span>,
                    <span class="hljs-attr">"LifecycleState"</span>: <span class="hljs-string">"InService"</span>,
                    <span class="hljs-attr">"HealthStatus"</span>: <span class="hljs-string">"Healthy"</span>,
                    <span class="hljs-attr">"LaunchTemplateName"</span>: <span class="hljs-string">"WebServerLT"</span>,
                    <span class="hljs-attr">"ProtectedFromScaleIn"</span>: <span class="hljs-literal">false</span>
                }
            ],
            <span class="hljs-attr">"CreatedTime"</span>: <span class="hljs-string">"2023-04-23T10:15:30.123Z"</span>,
            <span class="hljs-attr">"SuspendedProcesses"</span>: [],
            <span class="hljs-attr">"VPCZoneIdentifier"</span>: <span class="hljs-string">"subnet-1234abcd,subnet-5678efgh,subnet-9012ijkl"</span>,
            <span class="hljs-attr">"EnabledMetrics"</span>: [],
            <span class="hljs-attr">"Tags"</span>: [],
            <span class="hljs-attr">"TerminationPolicies"</span>: [
                <span class="hljs-string">"Default"</span>
            ],
            <span class="hljs-attr">"NewInstancesProtectedFromScaleIn"</span>: <span class="hljs-literal">false</span>,
            <span class="hljs-attr">"ServiceLinkedRoleARN"</span>: <span class="hljs-string">"arn:aws:iam::123456789012:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"</span>
        }
    ]
}
</code></pre>
<ul>
<li>To view the state of the EC2 instances using the AWS CLI, you can use the <strong>describe-instances</strong> command, which will show you the details of the instances, such as the ID, the type, the state, the IP address, and the tags. The command is:</li>
</ul>
<pre><code class="lang-bash">aws ec2 describe-instances --filters <span class="hljs-string">"Name=tag:aws:autoscaling:groupName,Values=WebServerASG"</span>
</code></pre>
<p>Replace <code>WebServerASG</code> with the name of your Auto Scaling group.</p>
<ul>
<li>You should see some output that shows the details of your Auto Scaling group, such as the name, the launch configuration, the size, the scaling policies, and the instances. The output should look something like this:</li>
</ul>
<pre><code class="lang-json">{
    <span class="hljs-attr">"AutoScalingGroups"</span>: [
        {
            <span class="hljs-attr">"AutoScalingGroupName"</span>: <span class="hljs-string">"WebServerASG"</span>,
            <span class="hljs-attr">"AutoScalingGroupARN"</span>: <span class="hljs-string">"arn:aws:autoscaling:ap-south-1:123456789012:autoScalingGroup:1234abcd-5678-efgh-9012-3456ijklmnop:autoScalingGroupName/WebServerASG"</span>,
            <span class="hljs-attr">"LaunchTemplateName"</span>: <span class="hljs-string">"WebServerLT"</span>,
            <span class="hljs-attr">"MinSize"</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">"MaxSize"</span>: <span class="hljs-number">3</span>,
            <span class="hljs-attr">"DesiredCapacity"</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">"DefaultCooldown"</span>: <span class="hljs-number">300</span>,
            <span class="hljs-attr">"AvailabilityZones"</span>: [
                <span class="hljs-string">"ap-south-1a"</span>,
                <span class="hljs-string">"ap-south-1b"</span>,
                <span class="hljs-string">"ap-south-1c"</span>
            ],
            <span class="hljs-attr">"LoadBalancerNames"</span>: [],
            <span class="hljs-attr">"TargetGroupARNs"</span>: [],
            <span class="hljs-attr">"HealthCheckType"</span>: <span class="hljs-string">"EC2"</span>,
            <span class="hljs-attr">"HealthCheckGracePeriod"</span>: <span class="hljs-number">300</span>,
            <span class="hljs-attr">"Instances"</span>: [
                {
                    <span class="hljs-attr">"InstanceId"</span>: <span class="hljs-string">"i-0a1b2c3d4e5f6g7h8"</span>,
                    <span class="hljs-attr">"InstanceType"</span>: <span class="hljs-string">"t2.micro"</span>,
                    <span class="hljs-attr">"AvailabilityZone"</span>: <span class="hljs-string">"ap-south-1a"</span>,
                    <span class="hljs-attr">"LifecycleState"</span>: <span class="hljs-string">"InService"</span>,
                    <span class="hljs-attr">"HealthStatus"</span>: <span class="hljs-string">"Healthy"</span>,
                    <span class="hljs-attr">"LaunchTemplateName"</span>: <span class="hljs-string">"WebServerLT"</span>,
                    <span class="hljs-attr">"ProtectedFromScaleIn"</span>: <span class="hljs-literal">false</span>
                }
            ],
            <span class="hljs-attr">"CreatedTime"</span>: <span class="hljs-string">"2023-04-23T10:15:30.123Z"</span>,
            <span class="hljs-attr">"SuspendedProcesses"</span>: [],
            <span class="hljs-attr">"VPCZoneIdentifier"</span>: <span class="hljs-string">"subnet-1234abcd,subnet-5678efgh,subnet-9012ijkl"</span>,
            <span class="hljs-attr">"EnabledMetrics"</span>: [],
            <span class="hljs-attr">"Tags"</span>: [],
            <span class="hljs-attr">"TerminationPolicies"</span>: [
                <span class="hljs-string">"Default"</span>
            ],
            <span class="hljs-attr">"NewInstancesProtectedFromScaleIn"</span>: <span class="hljs-literal">false</span>,
            <span class="hljs-attr">"ServiceLinkedRoleARN"</span>: <span class="hljs-string">"arn:aws:iam::123456789012:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"</span>
        }
    ]
}
</code></pre>
<ul>
<li>To view the state of the EC2 instances using the AWS CLI, you can use the <strong>describe-instances</strong> command, which will show you the details of the instances, such as the ID, the type, the state, the IP address, and the tags. The command is:</li>
</ul>
<pre><code class="lang-bash">aws ec2 describe-instances --filters <span class="hljs-string">"Name=tag:aws:autoscaling:groupName,Values=WebServerASG"</span>
</code></pre>
<p>Replace <code>WebServerASG</code> with the name of your Auto Scaling group. You should see some output that shows the details of your EC2 instances, such as the ID, the type, the state, the IP address, and the tags. The output should look something like this:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"Reservations"</span>: [
        {
            <span class="hljs-attr">"Groups"</span>: [],
            <span class="hljs-attr">"Instances"</span>: [
                {
                    <span class="hljs-attr">"AmiLaunchIndex"</span>: <span class="hljs-number">0</span>,
                    <span class="hljs-attr">"ImageId"</span>: <span class="hljs-string">"ami-0a123b456c789d012"</span>,
                    <span class="hljs-attr">"InstanceId"</span>: <span class="hljs-string">"i-0a1b2c3d4e5f6g7h8"</span>,
                    <span class="hljs-attr">"InstanceType"</span>: <span class="hljs-string">"t2.micro"</span>,
                    <span class="hljs-attr">"KeyName"</span>: <span class="hljs-string">"WebServerKP"</span>,
                    <span class="hljs-attr">"LaunchTime"</span>: <span class="hljs-string">"2023-04-23T10:15:31.000Z"</span>,
                    <span class="hljs-attr">"Monitoring"</span>: {
                        <span class="hljs-attr">"State"</span>: <span class="hljs-string">"enabled"</span>
                    },
                    <span class="hljs-attr">"Placement"</span>: {
                        <span class="hljs-attr">"AvailabilityZone"</span>: <span class="hljs-string">"ap-south-1a"</span>,
                        <span class="hljs-attr">"GroupName"</span>: <span class="hljs-string">""</span>,
                        <span class="hljs-attr">"Tenancy"</span>: <span class="hljs-string">"default"</span>
                    },
                    <span class="hljs-attr">"PrivateDnsName"</span>: <span class="hljs-string">"ip-172-31-22-33.ap-south-1.compute.internal"</span>,
                    <span class="hljs-attr">"PrivateIpAddress"</span>: <span class="hljs-string">"172.31.22.33"</span>,
                    <span class="hljs-attr">"ProductCodes"</span>: [],
                    <span class="hljs-attr">"PublicDnsName"</span>: <span class="hljs-string">"ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"</span>,
                    <span class="hljs-attr">"PublicIpAddress"</span>: <span class="hljs-string">"54.123.456.789"</span>,
                    <span class="hljs-attr">"State"</span>: {
                        <span class="hljs-attr">"Code"</span>: <span class="hljs-number">16</span>,
                        <span class="hljs-attr">"Name"</span>: <span class="hljs-string">"running"</span>
                    },
                    <span class="hljs-attr">"StateTransitionReason"</span>: <span class="hljs-string">""</span>,
                    <span class="hljs-attr">"SubnetId"</span>: <span class="hljs-string">"subnet-1234abcd"</span>,
                    <span class="hljs-attr">"VpcId"</span>: <span class="hljs-string">"vpc-1234abcd"</span>,
                    <span class="hljs-attr">"Architecture"</span>: <span class="hljs-string">"x86_64"</span>,
                    <span class="hljs-attr">"BlockDeviceMappings"</span>: [
                        {
                            <span class="hljs-attr">"DeviceName"</span>: <span class="hljs-string">"/dev/xvda"</span>,
                            <span class="hljs-attr">"Ebs"</span>: {
                                <span class="hljs-attr">"AttachTime"</span>: <span class="hljs-string">"2023-04-23T10:15:31.000Z"</span>,
                                <span class="hljs-attr">"DeleteOnTermination"</span>: <span class="hljs-literal">true</span>,
                                <span class="hljs-attr">"Status"</span>: <span class="hljs-string">"attached"</span>,
                                <span class="hljs-attr">"VolumeId"</span>: <span class="hljs-string">"vol-0a1b2c3d4e5f6g7h8"</span>
                            }
                        }
                    ],
                    <span class="hljs-attr">"ClientToken"</span>: <span class="hljs-string">""</span>,
                    <span class="hljs-attr">"EbsOptimized"</span>: <span class="hljs-literal">false</span>,
                    <span class="hljs-attr">"EnaSupport"</span>: <span class="hljs-literal">true</span>,
                    <span class="hljs-attr">"Hypervisor"</span>: <span class="hljs-string">"xen"</span>,
                    <span class="hljs-attr">"NetworkInterfaces"</span>: [
                        {
                            <span class="hljs-attr">"Association"</span>: {
                                <span class="hljs-attr">"IpOwnerId"</span>: <span class="hljs-string">"amazon"</span>,
                                <span class="hljs-attr">"PublicDnsName"</span>: <span class="hljs-string">"ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"</span>,
                                <span class="hljs-attr">"PublicIp"</span>: <span class="hljs-string">"54.123.456.789"</span>
                            },
                            <span class="hljs-attr">"Attachment"</span>: {
                                <span class="hljs-attr">"AttachTime"</span>: <span class="hljs-string">"2023-04-23T10:15:30.000Z"</span>,
                                <span class="hljs-attr">"AttachmentId"</span>: <span class="hljs-string">"eni-attach-0a1b2c3d4e"</span>,
                                <span class="hljs-attr">"DeleteOnTermination"</span>: <span class="hljs-literal">true</span>,
                                <span class="hljs-attr">"DeviceIndex"</span>: <span class="hljs-number">0</span>,
                                <span class="hljs-attr">"Status"</span>: <span class="hljs-string">"attached"</span>
                            },
                            <span class="hljs-attr">"Description"</span>: <span class="hljs-string">""</span>,
                            <span class="hljs-attr">"Groups"</span>: [
                                {
                                    <span class="hljs-attr">"GroupName"</span>: <span class="hljs-string">"WebServerSG"</span>,
                                    <span class="hljs-attr">"GroupId"</span>: <span class="hljs-string">"sg-1234abcd"</span>
                                }
                            ],
                            <span class="hljs-attr">"Ipv6Addresses"</span>: [],
                            <span class="hljs-attr">"MacAddress"</span>: <span class="hljs-string">"02:12:34:56:78:90"</span>,
                            <span class="hljs-attr">"NetworkInterfaceId"</span>: <span class="hljs-string">"eni-0a1b2c3d4e"</span>,
                            <span class="hljs-attr">"OwnerId"</span>: <span class="hljs-string">"123456789012"</span>,
                            <span class="hljs-attr">"PrivateDnsName"</span>: <span class="hljs-string">"ip-172-31-22-33.ap-south-1.compute.internal"</span>,
                            <span class="hljs-attr">"PrivateIpAddress"</span>: <span class="hljs-string">"172.31.22.33"</span>,
                            <span class="hljs-attr">"PrivateIpAddresses"</span>: [
                                {
                                    <span class="hljs-attr">"Association"</span>: {
                                        <span class="hljs-attr">"IpOwnerId"</span>: <span class="hljs-string">"amazon"</span>,
                                        <span class="hljs-attr">"PublicDnsName"</span>: <span class="hljs-string">"ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"</span>,
                                        <span class="hljs-attr">"PublicIp"</span>: <span class="hljs-string">"54.123.456.789"</span>
                                    },
                                    <span class="hljs-attr">"Primary"</span>: <span class="hljs-literal">true</span>,
                                    <span class="hljs-attr">"PrivateDnsName"</span>: <span class="hljs-string">"ip-172-31-22-33.ap-south-1.compute.internal"</span>,
                                    <span class="hljs-attr">"PrivateIpAddress"</span>: <span class="hljs-string">"172.31.22.33"</span>
                                }
                            ],
                            <span class="hljs-attr">"SourceDestCheck"</span>: <span class="hljs-literal">true</span>,
                            <span class="hljs-attr">"Status"</span>: <span class="hljs-string">"in-use"</span>,
                            <span class="hljs-attr">"SubnetId"</span>: <span class="hljs-string">"subnet-1234abcd"</span>,
                            <span class="hljs-attr">"VpcId"</span>: <span class="hljs-string">"vpc-1234abcd"</span>,
                            <span class="hljs-attr">"InterfaceType"</span>: <span class="hljs-string">"interface"</span>
                        }
                    ],
                    <span class="hljs-attr">"RootDeviceName"</span>: <span class="hljs-string">"/dev/xvda"</span>,
                    <span class="hljs-attr">"RootDeviceType"</span>: <span class="hljs-string">"ebs"</span>,
                    <span class="hljs-attr">"SecurityGroups"</span>: [
                        {
                            <span class="hljs-attr">"GroupName"</span>: <span class="hljs-string">"WebServerSG"</span>,
                            <span class="hljs-attr">"GroupId"</span>: <span class="hljs-string">"sg-1234abcd"</span>
                        }
                    ],
                    <span class="hljs-attr">"SourceDestCheck"</span>: <span class="hljs-literal">true</span>,
                    <span class="hljs-attr">"Tags"</span>: [
                        {
                            <span class="hljs-attr">"Key"</span>: <span class="hljs-string">"aws:autoscaling:groupName"</span>,
                            <span class="hljs-attr">"Value"</span>: <span class="hljs-string">"WebServerASG"</span>
                        }
                    ],
                    <span class="hljs-attr">"VirtualizationType"</span>: <span class="hljs-string">"hvm"</span>,
                    <span class="hljs-attr">"CpuOptions"</span>: {
                        <span class="hljs-attr">"CoreCount"</span>: <span class="hljs-number">1</span>,
                        <span class="hljs-attr">"ThreadsPerCore"</span>: <span class="hljs-number">1</span>
                    },
                    <span class="hljs-attr">"CapacityReservationSpecification"</span>: {
                        <span class="hljs-attr">"CapacityReservationPreference"</span>: <span class="hljs-string">"open"</span>
                    },
                    <span class="hljs-attr">"HibernationOptions"</span>: {
                        <span class="hljs-attr">"Configured"</span>: <span class="hljs-literal">false</span>
                    },
                    <span class="hljs-attr">"MetadataOptions"</span>: {
                        <span class="hljs-attr">"State"</span>: <span class="hljs-string">"applied"</span>,
                        <span class="hljs-attr">"HttpTokens"</span>: <span class="hljs-string">"optional"</span>,
                        <span class="hljs-attr">"HttpPutResponseHopLimit"</span>: <span class="hljs-number">1</span>,
                        <span class="hljs-attr">"HttpEndpoint"</span>: <span class="hljs-string">"enabled"</span>
                    }
                }
            ],
            <span class="hljs-attr">"OwnerId"</span>: <span class="hljs-string">"123456789012"</span>,
            <span class="hljs-attr">"ReservationId"</span>: <span class="hljs-string">"r-0a1b2c3d4e5f6g7h8"</span>
        }
    ]
}
</code></pre>
<ul>
<li>You can use the AWS CLI to perform various operations on the Auto Scaling group and the EC2 instances, such as scaling up or down, suspending or resuming processes, attaching or detaching instances, and terminating instances.</li>
</ul>
<h3 id="heading-step-4-test-your-auto-scaling-group-and-your-scaling-policy">Step 4: Test Your Auto Scaling Group and Your Scaling Policy</h3>
<p>Finally, you need to test your Auto Scaling group and your scaling policy by generating some load on your EC2 instances and observing the changes in the size and the performance of the Auto Scaling group. To test your Auto Scaling group and your scaling policy, follow these steps:</p>
<ul>
<li><p>Open a web browser and enter the public DNS name of one of your EC2 instances in the address bar. For example, if your instance’s public DNS name is <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a>, enter <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a> in the address bar.</p>
</li>
<li><p>You should see a web page that displays a message that says <strong>Hello, World!</strong>. This is your web application that is</p>
</li>
<li><p>This is your web application that is running on one of your EC2 instances that belongs to your Auto Scaling group.</p>
</li>
<li><p>Open another tab in your web browser and enter the URL of your dashboard, which you can find in the CloudWatch console under the <strong>Dashboards</strong> section. For example, if your dashboard name is <strong>EC2Dashboard</strong>, enter <a target="_blank" href="https://console.aws.amazon.com/cloudwatch/home?region=ap-south-1#dashboards:name=EC2Dashboard"><code>https://console.aws.amazon.com/cloudwatch/home?region=ap-south-1#dashboards:name=EC2Dashboard</code></a> in the address bar.</p>
</li>
<li><p>You should see your dashboard that shows the metrics and the alarm of your Auto Scaling group and your EC2 instances. You can refresh the dashboard by clicking on the <strong>Refresh</strong> button on the top right corner of the dashboard.</p>
</li>
<li><p>To generate some load on your EC2 instances, you can use the same tool that you used in the previous section, which is <strong>ApacheBench</strong>. You can install ApacheBench on your local machine by following the instructions on this [link].</p>
</li>
<li><p>To use ApacheBench, you need to open a terminal or a command prompt on your local machine and run the following command:</p>
<pre><code class="lang-bash">  ab -n 1000 -c 10 http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com/
</code></pre>
<p>  Replace <a target="_blank" href="http://ec2-54-123-456-789.ap-south-1.compute.amazonaws.com"><code>ec2-54-123-456-789.ap-south-1.compute.amazonaws.com</code></a> with the public DNS name of one of your EC2 instances. This command will send 1000 requests to your web application with a concurrency of 10, which means that 10 requests will be sent at a time.</p>
</li>
<li><p>You should see some output that shows the results of the test, such as the number of requests per second, the time per request, and the percentage of requests that completed within a certain time.</p>
</li>
<li><p>While the test is running, switch to the tab that shows your dashboard and refresh it. You should see the changes in the metrics and the alarm status of your Auto Scaling group and your EC2 instances. You should see the CPU utilization, disk usage, and network traffic increase as the load on your instances increases. You should also see the alarm status change from <strong>OK</strong> to <strong>ALARM</strong> when the average CPU utilization of your Auto Scaling group exceeds 80%.</p>
</li>
<li><p>You should also see the size of your Auto Scaling group increase as the scaling policy adds more instances to handle the increased load. You can see the number of instances in your Auto Scaling group in the EC2 console under the <strong>Auto Scaling Groups</strong> section. You should see the <strong>Group size</strong>, <strong>Desired capacity</strong>, and <strong>InService instances</strong> increase from 1 to 2 or 3, depending on the load.</p>
</li>
<li><p>To stop the test, press <strong>Ctrl+C</strong> on your terminal or command prompt. You should see the metrics and the alarm status of your Auto Scaling group and your EC2 instances return to normal after the test is stopped. You should also see the size of your Auto Scaling group decrease as the scaling policy removes the excess instances.</p>
<p>  Congratulations, you have successfully created an Auto Scaling group using the AWS Management Console and configured it to launch EC2 instances in response to changes in demand. You have also tested your Auto Scaling group and your scaling policy by generating some load on your EC2 instances and observing the changes in the size and the performance of the Auto Scaling group. You can now use Auto Scaling to improve the availability and performance of your applications, as well as to reduce the cost and complexity of managing your resources.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>  In this blog post, I have shown you how to test your knowledge on AWS by performing some hands-on tasks that are relevant for DevOps learners. You have learned how to:</p>
<ul>
<li><p>Launch an EC2 instance using the AWS Management Console and connect to it using SSH</p>
</li>
<li><p>Install a web server on the EC2 instance and deploy a simple web application</p>
</li>
<li><p>Monitor the EC2 instance using Amazon CloudWatch and troubleshoot any issues that arise</p>
</li>
<li><p>Create an Auto Scaling group using the AWS Management Console and configure it to launch EC2 instances in response to changes in demand</p>
</li>
<li><p>Monitor the performance of the Auto Scaling group and the EC2 instances and troubleshoot any issues that arise</p>
</li>
</ul>
</li>
</ul>
<p>    By doing these tasks, you have gained more confidence and experience in using AWS services and tools. You have also improved your skills and knowledge in DevOps, which is a set of practices that combines software development and IT operations to deliver software faster and more reliably.</p>
<p>    I hope you have enjoyed this blog post and learned something new. If you have any questions or feedback, please feel free to leave a comment below.</p>
<p>    If you want to learn more about AWS and DevOps, you can check out the following resources:</p>
<ul>
<li><p><a target="_blank" href="https://aws.amazon.com/training/">AWS Training and Certification</a></p>
</li>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/">AWS Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://aws.amazon.com/blogs/devops/">AWS DevOps Blog</a></p>
</li>
</ul>
<p>    Thank you for reading and happy learning!</p>
]]></content:encoded></item><item><title><![CDATA[How to Monitor Your AWS Billing and Get Alerts Using CloudWatch and SNS 🚨]]></title><description><![CDATA[Are you a DevOps learner who wants to keep track of your AWS billing and get notified when it exceeds a certain threshold? If yes, then this blog post is for you.

In this post, I’ll explain what CloudWatch and SNS are and how to use them to create a...]]></description><link>https://blog.ajitfawade.com/how-to-monitor-your-aws-billing-and-get-alerts-using-cloudwatch-and-sns</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-monitor-your-aws-billing-and-get-alerts-using-cloudwatch-and-sns</guid><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[Devops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS CloudWatch]]></category><category><![CDATA[AWS SNS]]></category><category><![CDATA[#AWSPricing #CloudCosts #AWSBudgeting #CostOptimization #PricingOptions #AWSBilling #SavingsPlans #ReservedInstances #SpotInstances #CloudFinance ]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Thu, 23 Nov 2023 02:20:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1700699445949/c62aef8c-0d1e-4b03-8730-8ea3cb6501a4.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a DevOps learner who wants to keep track of your AWS billing and get notified when it exceeds a certain threshold? If yes, then this blog post is for you.</p>
<blockquote>
<p>In this post, I’ll explain what CloudWatch and SNS are and how to use them to create a CloudWatch alarm that monitors your billing and sends an email to you when it reaches $2.</p>
</blockquote>
<p>By the end of this post, you’ll be able to:</p>
<ul>
<li><p>Understand what CloudWatch and SNS are and how they work together</p>
</li>
<li><p>Create a CloudWatch alarm that monitors your billing</p>
</li>
<li><p>Create an SNS topic and subscribe your email address to it</p>
</li>
<li><p>Configure the CloudWatch alarm to send notifications to the SNS topic</p>
</li>
<li><p>Delete the CloudWatch alarm and the SNS topic</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-what-is-amazon-cloudwatch">What is Amazon CloudWatch?</h2>
<p>Amazon CloudWatch is a service that monitors your Amazon Web Services (AWS) resources and the applications you run on AWS in real time. You can use CloudWatch to collect and track metrics, which are variables you can measure for your resources and applications. For example, you can monitor the CPU utilization, disk reads and writes, network traffic, and request count of your EC2 instances. You can also monitor the billing metrics for your AWS account, such as the estimated charges, the total cost, and the cost by service.</p>
<p>CloudWatch also allows you to set alarms, which are rules that trigger actions when a metric crosses a specified threshold. For example, you can set an alarm that sends you an email when your EC2 CPU utilization exceeds 80%. You can also set an alarm that stops or terminates your EC2 instance when your billing exceeds a certain amount.</p>
<p>To send notifications to yourself or other recipients, you need to use another AWS service called Amazon Simple Notification Service (SNS).</p>
<h2 id="heading-what-is-amazon-sns">What is Amazon SNS?</h2>
<p>Amazon Simple Notification Service (SNS) is a notification service that provides a low-cost infrastructure for mass delivery of messages, predominantly to mobile users. You can use SNS to send SMS messages, push notifications, or emails to your users or subscribers. You can also use SNS to send messages to other AWS services, such as Lambda functions, SQS queues, or HTTP endpoints.</p>
<p>SNS works with the concept of topics and subscriptions. A topic is a logical access point and a communication channel for sending and receiving messages. A subscription is an endpoint that receives messages from a topic. For example, you can create a topic called “BillingAlerts” and subscribe your email address to it. Then, you can send messages to the topic, and they will be delivered to your email address.</p>
<p>You can also use SNS to receive notifications from CloudWatch alarms. You can configure your CloudWatch alarm to send messages to an SNS topic, and then subscribe your email address or other endpoints to the topic. This way, you can get alerts when your CloudWatch alarm is triggered.</p>
<p>Now that you know what CloudWatch and SNS are, let’s see how to use them to monitor your AWS billing and get alerts.</p>
<h2 id="heading-how-to-create-a-cloudwatch-alarm-that-monitors-your-billing">How to Create a CloudWatch Alarm that Monitors Your Billing</h2>
<p>To create a CloudWatch alarm that monitors your billing, you need to follow these steps:</p>
<p><strong>Step 1: Navigate to the CloudWatch Console</strong></p>
<ol>
<li><p>Sign in to your AWS account and open the AWS Management Console.</p>
</li>
<li><p>In the search bar at the top of the console, type "CloudWatch" and select "CloudWatch" from the search results.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700703033737/72ac97f4-8ea1-4492-b613-79483c1eabdb.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p><strong>Step 2: Access Billing Alarms</strong></p>
<ol>
<li><p>In the CloudWatch console's left navigation pane, under "Alarms," choose "Billing".</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700703120554/5fef6a14-bf5f-444c-944d-4e1f9381f9ed.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p><strong>Step 3: Create New Alarm</strong></p>
<ol>
<li><p>Click on the "Create alarm" button to initiate the alarm creation process.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700703169221/9cb9c402-a871-4fe4-a378-f5e08343ebed.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p><strong>Step 4: Specify Metric</strong></p>
<ol>
<li><p>A default selected metric will appear with the namespace AWS/Billing. Provide a descriptive name for the selected metric, such as "EstimatedCharges." You can edit the metric.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700703571187/c10f0f5a-5671-4779-af56-fcee561e44ae.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p><strong>Step 5: Specify Alarm Conditions</strong></p>
<ol>
<li><p>Select the "Static" threshold type.</p>
</li>
<li><p>Select "Greater/Equal" for "Whenever EstimatedCharges is".</p>
</li>
<li><p>Set the "Threshold" value to the desired threshold for triggering the alarm, such as "2 USD."</p>
</li>
</ol>
<p><strong>Step 6: Configure Actions</strong></p>
<ol>
<li><p>Under "Notification," choose "In alarm" for "alarm state trigger".</p>
</li>
<li><p>Select an existing SNS topic from the drop-down menu or create a new topic by clicking on "Create new topic."</p>
</li>
<li><p>If creating a new topic, provide a name and a display name for the topic, such as "BillingAlertsTopic."</p>
</li>
<li><p>Subscribe your email address or other endpoints to the topic by clicking on "Create subscription" and entering the necessary details.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700704471606/5137e4ec-c248-45a1-b8fe-2f2fcc65ab4f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Confirm the subscription by following the instructions in the email or message sent to you.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700704498163/dcb1d663-8d98-4c74-bacf-c12989e52062.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700704516996/316dcf97-d9a3-42d5-b1e5-48c1ecbdefdc.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p><strong>Step 7: Name and description</strong></p>
<ol>
<li>Provide a descriptive name for the alarm, such as "BillingAlarm."</li>
</ol>
<p><strong>Step 8: Review and Create Alarm</strong></p>
<ol>
<li><p>Review the alarm configuration summary to ensure all settings are accurate.</p>
</li>
<li><p>Click on the "Create alarm" button to finalize the alarm creation process.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700704888893/1f17348f-492c-4f2c-a403-e9d868777852.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>You have successfully created a CloudWatch alarm that monitors your billing and sends an email to you when it reaches $2. You can view your alarm status and history in the CloudWatch console, under <strong>Alarms</strong>. You can also modify or delete your alarm at any time.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700705260428/4f54f51d-4473-49ed-8d8a-11321afe2030.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><mark>Note: To address the 'Insufficient Data' state, you can wait for CloudWatch to collect more data. Once a sufficient number of data points are available, CloudWatch will begin evaluating the alarm condition, and the state will change accordingly.</mark></p>
</blockquote>
<h2 id="heading-how-to-delete-the-cloudwatch-alarm-and-the-sns-topic">How to Delete the CloudWatch Alarm and the SNS Topic</h2>
<p>In this section, I’ll show you how to delete the CloudWatch alarm and the SNS topic that you created in the previous sections. You may want to do this if you don’t need them anymore, or if you want to avoid getting charged for them.</p>
<h3 id="heading-step-1-delete-the-cloudwatch-alarm">Step 1: Delete the CloudWatch Alarm</h3>
<p>To delete the CloudWatch alarm, follow these steps:</p>
<ul>
<li><p>Go to the CloudWatch console and select <strong>Alarms</strong> from the left navigation pane.</p>
</li>
<li><p>Find the alarm that you created, which should have the name <strong>BillingAlarm</strong>. Select it and click on <strong>Actions</strong> and then <strong>Delete</strong>.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700705462357/43c545d6-7610-450c-a3b1-11ecd94a6809.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Confirm the deletion by clicking on <strong>Delete</strong> again.</p>
</li>
</ul>
<h3 id="heading-step-2-delete-the-sns-topic">Step 2: Delete the SNS Topic</h3>
<p>To delete the SNS topic, follow these steps:</p>
<ul>
<li><p>Go to the SNS console and select <strong>Topics</strong> from the left navigation pane.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700705586404/b4b1a4b3-ec53-48df-8cf5-65a3782a7695.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Find the topic that you created, which should have the name <strong>BillingTopic</strong>. Select it and click on <strong>Delete</strong></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700705644365/5d1de709-4e8e-4da7-a3a4-f2e0d8de508f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Confirm the deletion by typing <strong>Delete me</strong> in the textbox.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, you learned how to monitor your AWS billing and get alerts using CloudWatch and SNS. You learned what CloudWatch and SNS are and how to use them to create a CloudWatch alarm that monitors your billing and sends an email to you when it reaches $2. You also learned how to delete the alarm and the topic if you don’t need them anymore.</p>
<p>I hope you found this blog post useful and informative. If you have any questions or feedback, please leave a comment below. If you want to learn more about CloudWatch and SNS, you can check out the following resources:</p>
<ul>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html">Amazon CloudWatch Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/sns/latest/dg/welcome.html">Amazon SNS Documentation</a></p>
</li>
</ul>
<p>Thank you for reading and happy learning! 🙏</p>
]]></content:encoded></item><item><title><![CDATA[How to Deploy WordPress Website on AWS: A Step-by-Step Guide for Beginners]]></title><description><![CDATA[WordPress is a powerful and popular CMS that can help you create and manage various types of websites with ease. In this blog post, I’ll show you how to set up a WordPress blog site using AWS services, such as EC2, RDS, and S3.

By the end of this po...]]></description><link>https://blog.ajitfawade.com/how-to-deploy-wordpress-website-on-aws-a-step-by-step-guide-for-beginners</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-deploy-wordpress-website-on-aws-a-step-by-step-guide-for-beginners</guid><category><![CDATA[Devops]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[WordPress]]></category><category><![CDATA[aws-wordpress]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Wed, 22 Nov 2023 04:06:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1700152354915/4c17df99-2580-4e5c-b11e-87c78d00f302.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>WordPress is a powerful and popular CMS that can help you create and manage various types of websites with ease. In this blog post, I’ll show you how to set up a WordPress blog site using AWS services, such as EC2, RDS, and S3.</p>
</blockquote>
<p>By the end of this post, you’ll be able to:</p>
<ul>
<li><p>Create an RDS instance for the MySQL database</p>
</li>
<li><p>Create an EC2 instance for the WordPress application</p>
</li>
<li><p>Install and configure WordPress on EC2</p>
</li>
<li><p>Upload and download files to and from S3</p>
</li>
<li><p>Access your WordPress site from the internet</p>
</li>
</ul>
<p>Let’s get started!</p>
<p>WordPress is a free and open-source content management system (CMS) that lets you create and manage websites easily. It is most often used to run blogs, but it can also be used to run e-commerce sites, message boards, and many other popular things. WordPress is used by over 30% of all websites on the internet, making it the most popular CMS in the world.</p>
<p>WordPress requires a web server and a database to store its data and run its scripts. You can install WordPress on your computer or a web hosting service, but in this blog post, we’ll use AWS (Amazon Web Services) to host our WordPress site. AWS is a cloud computing platform that provides various services and resources for web development, such as computing, storage, networking, security, and more. AWS offers a free tier for new users, which allows you to use some of its services for free for a limited time.</p>
<p>To set up a WordPress site on AWS, we’ll use the following services:</p>
<ul>
<li><p>Amazon RDS (Relational Database Service): A fully managed database service that lets you create and operate MySQL databases in the cloud. We’ll use RDS to store our WordPress data, such as posts, pages, comments, and settings.</p>
</li>
<li><p>Amazon EC2 (Elastic Compute Cloud): A virtual server in the cloud that lets you run applications and websites. We’ll use EC2 to install and host our WordPress application, which includes the WordPress core files, themes, plugins, and media files.</p>
</li>
<li><p>Amazon S3 (Simple Storage Service): A scalable and durable object storage service that lets you store and retrieve any amount of data from anywhere on the web. We’ll use S3 to store and serve our media files, such as images, videos, and audio files.</p>
</li>
</ul>
<p>In this blog post, we’ll assume that you already have an AWS account.</p>
<h3 id="heading-step-1-create-an-rds-instance-for-mysql-database">Step 1: Create an RDS Instance for MySQL Database</h3>
<p>As WordPress requires a MySQL database to store its data, the first step is to create an RDS instance for MySQL database. RDS is a fully managed database service that lets you create and operate MySQL databases in the cloud. RDS takes care of the database administration tasks, such as backups, scaling, failover, encryption, monitoring, and patching. You can also customize your database settings, such as the engine, the instance type, the storage, the security, and the authentication.</p>
<p>To create an RDS instance for MySQL database, follow these steps:</p>
<ul>
<li><p>Log in to your AWS account and go to the RDS console.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700619205907/286496e8-6947-4b51-b541-0592d40f4ee5.avif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Create Database</strong> button.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700619220414/c0697ee6-3822-4adf-8534-00f89a8d1fae.avif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose <strong>Standard Create</strong> as the creation method.</p>
</li>
<li><p>Choose <strong>MySQL</strong> as the engine type.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700619256591/ef752711-38dc-46c6-817a-f8c71302a379.avif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose the <strong>Free tier</strong> as the template.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700619272402/7cfeed49-3bf3-4f5c-b0f6-e47e548e6f1b.avif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter a name for your database instance, such as <code>wordpress-db</code>.</p>
</li>
<li><p>Enter a username and a password for your database. Remember these credentials as you will need them later to connect to your database.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700619288511/fd594cea-df8a-44ff-b979-b7b57ea78f8b.avif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Leave the other settings as default and click on the <strong>Create Database</strong> button at the bottom of the page.</p>
</li>
</ul>
<p>It may take a few minutes for your database instance to be created. You can check the status of your database instance on the RDS console. Once it is available, you can see its details, such as the endpoint, the port, the security group, and the availability zone.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700619960434/e2074776-4476-4689-a951-a61256375857.png" alt class="image--center mx-auto" /></p>
<p>Note down the endpoint and the port of your database instance, as you will need them later to connect to your database. The endpoint is the address of your database instance, and the port is the number that identifies the communication channel. For example, if your endpoint is <a target="_blank" href="http://wordpress-db.cqyjxqyjxqyj.us-east-1.rds.amazonaws.com">wordpress-db.cqyjxqyjxqyj.us-east-1.rds.amazonaws.com</a> and your port is 3306, then your database connection string is <a target="_blank" href="http://wordpress-db.cqyjxqyjxqyj.us-east-1.rds.amazonaws.com:3306">wordpress-db.cqyjxqyjxqyj.us-east-1.rds.amazonaws.com:3306</a>.</p>
<h3 id="heading-step-2-create-an-ec2-instance-for-wordpress-application">Step 2: Create an EC2 Instance for WordPress Application</h3>
<p>The next step is to create an EC2 instance for the WordPress application. EC2 is a virtual server in the cloud that lets you run applications and websites. You can choose from various instance types, sizes, and operating systems to suit your needs and budget. You can also configure your instance with security groups, key pairs, and storage volumes.</p>
<p>To create an EC2 instance for a WordPress application, follow these steps:</p>
<ul>
<li><p>Go to the [EC2 console] and click on the <strong>Launch Instance</strong> button.</p>
</li>
<li><p>Choose <strong>Amazon Linux 2 AMI (HVM), SSD Volume Type</strong> as the Amazon Machine Image (AMI). An AMI is a template that contains the software configuration for your instance, such as the operating system, the applications, and the settings.</p>
</li>
<li><p>Choose <strong>t2.micro</strong> as the instance type. This is the smallest and cheapest instance type that is eligible for the free tier. You can change the instance type later if you need more resources.</p>
</li>
<li><p>Click on <strong>Next: Configure Instance Details</strong> button.</p>
</li>
<li><p>Leave the default settings as they are and click on <strong>Next: Add Storage</strong> button.</p>
</li>
<li><p>Leave the default settings as they are and click on <strong>Next: Add Tags</strong> button.</p>
</li>
<li><p>Add a tag with the key <strong>Name</strong> and the value <strong>wordpress-ec2</strong>. This will help you identify your instance later.</p>
</li>
<li><p>Click on <strong>Next: Configure Security Group</strong> button.</p>
</li>
<li><p>Create a new security group with the name <strong>wordpress-sg</strong> and the description <strong>Security group for WordPress EC2 instance</strong>. A security group is a set of rules that define the inbound and outbound traffic for your instance. You can add or remove rules later as per your requirements.</p>
</li>
<li><p>Add the following rules to your security group:</p>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Type</td><td>Protocol</td><td>Port range</td><td>Source</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>SSH</td><td>TCP</td><td>22</td><td>My IP</td><td>SSH access</td></tr>
<tr>
<td>HTTP</td><td>TCP</td><td>80</td><td>Anywhere</td><td>Web access</td></tr>
<tr>
<td>HTTPS</td><td>TCP</td><td>443</td><td>Anywhere</td><td>Secure web access</td></tr>
</tbody>
</table>
</div><p>The SSH rule allows you to connect to your instance remotely using a secure shell (SSH) protocol. The HTTP and HTTPS rules allow anyone to access your instance using a web browser. You can restrict the source to your IP address or a specific range of IP addresses if you want to limit the access to your instance.</p>
<ul>
<li><p>Click on <strong>Review and Launch</strong> button.</p>
</li>
<li><p>Review your instance details and click on <strong>Launch</strong> button.</p>
</li>
<li><p>Choose <strong>Create a new key pair</strong> as the key pair option. A key pair consists of a public key and a private key that are used to encrypt and decrypt the communication between you and your instance. You need to have the private key to connect to your instance using SSH.</p>
</li>
<li><p>Enter a name for your key pair, such as <strong>wordpress-key</strong> and click on <strong>Download Key Pair</strong> button. Save the key pair file (.pem) to a secure and accessible location on your computer. You will need this file later to connect to your instance. Do not share this file with anyone or lose it, as you will not be able to access your instance without it.</p>
</li>
<li><p>Click on <strong>Launch Instances</strong> button.</p>
</li>
</ul>
<p>It may take a few minutes for your instance to be launched. You can check the status of your instance on the EC2 console. Once it is running, you can see its details, such as the public IP address, the private IP address, the security group, and the key pair.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700619952127/c1ad9204-cf89-4fa4-8158-859c3ee5e5fe.png" alt class="image--center mx-auto" /></p>
<p>Note down the public IP address of your instance, as you will need it later to connect to your instance and access your WordPress site. The public IP address is the address that is visible to the internet, and it may change if you stop and start your instance. You can also assign an elastic IP address to your instance, which is a static IP address that does not change.</p>
<h3 id="heading-step-3-install-and-configure-wordpress-on-ec2">Step 3: Install and Configure WordPress on EC2</h3>
<p>The next step is to install and configure WordPress on EC2. WordPress is a free and open-source content management system (CMS) that lets you create and manage websites easily. WordPress consists of two main components: the WordPress core files, which contain the code and the functionality of WordPress, and the WordPress database, which stores the data and the settings of WordPress. You need to install both components on your EC2 instance and connect them to each other.</p>
<p>To install and configure WordPress on EC2, follow these steps:</p>
<ul>
<li><p>Connect to your EC2 instance using SSH.</p>
</li>
<li><p>Connect to your EC2 instance using SSH. You can use the following command to connect to your instance from a terminal window, where <code>wordpress-key.pem</code> is the name of your key pair file and <code>ec2-user@public-ip-address</code> is the user name and the public IP address of your instance. You can find the public IP address of your instance on the EC2 console.</p>
</li>
</ul>
<pre><code class="lang-bash">ssh -i wordpress-key.pem ec2-user@public-ip-address
</code></pre>
<ul>
<li><p>You may see a warning message about the authenticity of the host. Type <code>yes</code> to continue connecting. You may also be prompted to enter the passphrase for your key pair file if you have set one.</p>
</li>
<li><p>Once you are connected, you should see a welcome message like this:</p>
</li>
</ul>
<pre><code class="lang-bash">   ,     <span class="hljs-comment">#_</span>
   ~\_  <span class="hljs-comment">####_        Amazon Linux 2</span>
  ~~  \_<span class="hljs-comment">#####\</span>
  ~~     \<span class="hljs-comment">###|       AL2 End of Life is 2025-06-30.</span>
  ~~       \<span class="hljs-comment">#/ ___</span>
   ~~       V~<span class="hljs-string">' '</span>-&gt;
    ~~~         /    A newer version of Amazon Linux is available!
      ~~._.   _/
         _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
       _/m/<span class="hljs-string">'           https://aws.amazon.com/linux/amazon-linux-2023/

[ec2-user@ip-172-31-47-182 ~]$</span>
</code></pre>
<ul>
<li>Update the packages on your instance by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo yum update -y
</code></pre>
<ul>
<li>Install the Apache web server, the PHP software, and the MySQL client by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo yum install -y httpd php mysql
</code></pre>
<ul>
<li>Start the Apache web server and enable it to start automatically on boot by running the following commands:</li>
</ul>
<pre><code class="lang-bash">sudo systemctl start httpd
sudo systemctl <span class="hljs-built_in">enable</span> httpd
</code></pre>
<ul>
<li>Test the web server by opening a web browser and entering the public IP address of your instance in the address bar. You should see a test page like this:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700620190152/6d93dd71-3ad0-4a66-932f-ecbee19aca88.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Download the latest WordPress package from the official WordPress website by running the following command:</li>
</ul>
<pre><code class="lang-bash">wget https://wordpress.org/latest.tar.gz
</code></pre>
<ul>
<li>Extract the WordPress package by running the following command:</li>
</ul>
<pre><code class="lang-bash">tar -xzf latest.tar.gz
</code></pre>
<ul>
<li>Move the WordPress files to the web server document root directory by running the following command:</li>
</ul>
<pre><code class="lang-bash">sudo mv wordpress/* /var/www/html/
</code></pre>
<ul>
<li>Change the ownership and permissions of the WordPress files and directories by running the following commands:</li>
</ul>
<pre><code class="lang-bash">sudo chown -R apache:apache /var/www/html/
sudo find /var/www/html/ -<span class="hljs-built_in">type</span> d -<span class="hljs-built_in">exec</span> chmod 755 {} \;
sudo find /var/www/html/ -<span class="hljs-built_in">type</span> f -<span class="hljs-built_in">exec</span> chmod 644 {} \;
</code></pre>
<ul>
<li>Create a WordPress configuration file by copying the sample file by running the following command:</li>
</ul>
<pre><code class="lang-bash">cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php
</code></pre>
<ul>
<li>Edit the WordPress configuration file by using a text editor of your choice, such as nano or vi. For example, to use nano, run the following command:</li>
</ul>
<pre><code class="lang-bash">sudo nano /var/www/html/wp-config.php
</code></pre>
<ul>
<li>In the WordPress configuration file, find the following lines and replace the values with the credentials of your RDS database instance that you created in step 1. Remember to use the endpoint and the port of your database instance as the host name, and the username and the password that you specified when creating the database instance.</li>
</ul>
<pre><code class="lang-php"><span class="hljs-comment">/** The name of the database for WordPress */</span>
define( <span class="hljs-string">'DB_NAME'</span>, <span class="hljs-string">'database_name_here'</span> );

<span class="hljs-comment">/** MySQL database username */</span>
define( <span class="hljs-string">'DB_USER'</span>, <span class="hljs-string">'username_here'</span> );

<span class="hljs-comment">/** MySQL database password */</span>
define( <span class="hljs-string">'DB_PASSWORD'</span>, <span class="hljs-string">'password_here'</span> );

<span class="hljs-comment">/** MySQL hostname */</span>
define( <span class="hljs-string">'DB_HOST'</span>, <span class="hljs-string">'localhost'</span> );
</code></pre>
<p>For example, if your database name is <code>wordpress-db</code>, your username is <code>admin</code>, your password is <code>secret</code>, and your endpoint and port are <a target="_blank" href="http://wordpress-db.cqyjxqyjxqyj.us-east-1.rds.amazonaws.com:3306"><code>wordpress-db.cqyjxqyjxqyj.us-east-1.rds.amazonaws.com:3306</code></a>, then the lines should look like this:</p>
<pre><code class="lang-php"><span class="hljs-comment">/** The name of the database for WordPress */</span>
define( <span class="hljs-string">'DB_NAME'</span>, <span class="hljs-string">'wordpress-db'</span> );

<span class="hljs-comment">/** MySQL database username */</span>
define( <span class="hljs-string">'DB_USER'</span>, <span class="hljs-string">'admin'</span> );

<span class="hljs-comment">/** MySQL database password */</span>
define( <span class="hljs-string">'DB_PASSWORD'</span>, <span class="hljs-string">'secret'</span> );

<span class="hljs-comment">/** MySQL hostname */</span>
define( <span class="hljs-string">'DB_HOST'</span>, <span class="hljs-string">'wordpress-db.cqyjxqyjxqyj.us-east-1.rds.amazonaws.com:3306'</span> );
</code></pre>
<ul>
<li><p>Save and exit the WordPress configuration file.</p>
</li>
<li><p>Complete the WordPress installation by opening a web browser and entering the public IP address of your instance in the address bar. You should see a WordPress setup page like this:</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700622796282/67a851e6-b452-41c9-9eb4-67bc1107f331.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700622804597/638b1842-d268-4bc8-b75d-25a316d9feca.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Follow the instructions on the WordPress setup page to choose a language, enter a site title, a username, a password, and an email address, and install WordPress. You should see a success message like this:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700622848238/06f9692a-425c-43c8-b292-b7adf013aa98.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Log in to your WordPress site by entering the username and password that you chose during the installation. You should see a WordPress dashboard like this:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700622902009/68e86d4c-4fbc-44e6-bfcb-cc39af55948e.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Congratulations! You have successfully installed and configured WordPress on EC2. You can now customize your WordPress site by adding themes, plugins, posts, pages, and more.</li>
</ul>
<p>The next step is to upload and download files to and from S3. S3 is a scalable and durable object storage service that lets you store and retrieve any amount of data from anywhere on the web. S3 can be used to store and serve your media files, such as images, videos, and audio files, for your WordPress site. S3 can also be used to back up your WordPress files and database, and to migrate your WordPress site to another server.</p>
<p>To upload and download files to and from S3, follow these steps:</p>
<h3 id="heading-step-4-upload-and-download-files-to-and-from-s3">Step 4: Upload and Download Files to and from S3</h3>
<ul>
<li><p>Go to the S3 console and click on <strong>Create bucket</strong> button.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700622975541/634edd63-16eb-4357-8e04-0a513aac5aab.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter a name for your bucket, such as <strong>ajits-wordpress-s3</strong>. A bucket is a container for your objects, which are the files that you store in S3. A bucket name must be globally unique, meaning that no one else can have the same bucket name as yours.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700623064263/88c4caea-30bf-4fbc-9b6c-f7d07cdc6d70.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose a region for your bucket, such as <strong>US East (N. Virginia)</strong>. A region is a geographical area where your bucket and objects are stored. You can choose a region that is close to your users or your EC2 instance to reduce latency and costs.</p>
</li>
<li><p>Leave the other settings as default and click on <strong>Create bucket</strong> button.</p>
</li>
<li><p>You should see your bucket listed on the S3 console. Click on your bucket name to open it.</p>
</li>
<li><p>To upload files to your bucket, you can either drag and drop them from your computer to the S3 console, or click on <strong>Upload</strong> button and choose the files that you want to upload. For example, you can upload some images that you want to use for your WordPress site.</p>
</li>
<li><p>To download files from your bucket, you can either select the files that you want to download and click on <strong>Download</strong> button, or right-click on the file that you want to download and choose <strong>Download</strong> option.</p>
</li>
<li><p>To make your files publicly accessible, you need to change the permissions of your bucket and your objects. By default, your bucket and your objects are private, meaning that only you can access them. To make them public, you need to grant read access to everyone.</p>
</li>
<li><p>To change the permissions of your bucket, click on the <strong>Permissions</strong> tab and then click on <strong>Edit</strong> button under <strong>Block public access</strong> section. Uncheck the boxes that say <strong>Block all public access</strong> and <strong>Block public access to buckets and objects granted through new access control lists (ACLs)</strong>. Click on <strong>Save changes</strong> button and confirm your changes.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700623305121/69fcc1b5-7404-43b5-b0c8-a60f653c69f7.png" alt class="image--center mx-auto" /></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700623326302/4dae8ea2-72c9-4f5f-ad2d-ad46d8f2eb7d.png" alt class="image--center mx-auto" /></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700623346564/e96c3e91-c402-410a-9afa-83921e4abf06.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>To change the permissions of your objects, select the objects that you want to make public and click on <strong>Actions</strong> button and choose <strong>Make public</strong> option. Confirm your changes.</p>
</li>
<li><p>To access your files from the web, you need to use the URL of your bucket and your object. The URL of your bucket is <a target="_blank" href="http://bucket-name.s3.amazonaws.com/"><code>http://bucket-name.s3.amazonaws.com/</code></a>, where <code>bucket-name</code> is the name of your bucket. The URL of your object is <a target="_blank" href="http://bucket-name.s3.amazonaws.com/object-key"><code>http://bucket-name.s3.amazonaws.com/object-key</code></a>, where <code>object-key</code> is the name of your object. For example, if your bucket name is <code>wordpress-s3</code> and your object name is <code>image.jpg</code>, then the URL of your object is <a target="_blank" href="http://wordpress-s3.s3.amazonaws.com/image.jpg"><code>http://wordpress-s3.s3.amazonaws.com/image.jpg</code></a>.</p>
</li>
<li><p>You can test your files by opening a web browser and entering the URL of your object in the address bar. You should see your file displayed on the web browser.</p>
</li>
<li><p>Congratulations! You have successfully uploaded and downloaded files to and from S3. You can now use S3 to store and serve your media files for your WordPress site. You can also use S3 to backup your WordPress files and database, and to migrate your WordPress site to another server.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, you have learned how to deploy WordPress website on AWS using various services, such as EC2, RDS, and S3. By following these steps, you have created a WordPress blog site that is scalable, reliable, and cost-effective.</p>
<p>I hope you have enjoyed this blog post and learned something new and useful. If you have any questions or feedback, please feel free to leave a comment below. I would love to hear from you and help you with your DevOps journey.</p>
<p>Thank you for reading and happy blogging! 😊</p>
]]></content:encoded></item><item><title><![CDATA[How to Use Amazon RDS to Set Up and Manage MySQL Databases in AWS: A Complete Guide for DevOps Engineers]]></title><description><![CDATA[Are you a DevOps learner who wants to use Amazon Relational Database Service (Amazon RDS) to set up and manage MySQL databases in AWS? If yes, then this blog post is for you. In this post, I’ll explain what Amazon RDS is and how to use it to create, ...]]></description><link>https://blog.ajitfawade.com/how-to-use-amazon-rds-to-set-up-and-manage-mysql-databases-in-aws</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-use-amazon-rds-to-set-up-and-manage-mysql-databases-in-aws</guid><category><![CDATA[Devops]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS RDS]]></category><category><![CDATA[Databases]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Wed, 15 Nov 2023 04:11:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699947658586/b82a2753-1fcf-42e3-85e9-60b1b6f9700d.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a DevOps learner who wants to use Amazon Relational Database Service (Amazon RDS) to set up and manage MySQL databases in AWS? If yes, then this blog post is for you. In this post, I’ll explain what Amazon RDS is and how to use it to create, configure, and connect to MySQL databases in the cloud. By the end of this post, you’ll be able to:</p>
<ul>
<li><p>Create a free tier RDS instance of MySQL</p>
</li>
<li><p>Create an EC2 instance</p>
</li>
<li><p>Create an IAM role with RDS access</p>
</li>
<li><p>Assign the role to EC2 so that your EC2 instance can connect with RDS</p>
</li>
<li><p>Connect your EC2 instance to your RDS instance using a MySQL client</p>
</li>
</ul>
<h2 id="heading-what-is-amazon-rds">What is Amazon RDS</h2>
<p>Amazon Relational Database Service (Amazon RDS) is a collection of managed services that makes it simple to set up, operate, and scale databases in the cloud. Amazon RDS supports several popular database engines, such as MySQL, PostgreSQL, Oracle, SQL Server, and MariaDB. With Amazon RDS, you can enjoy the benefits of a fully managed database service, such as:</p>
<ul>
<li><p>Automated backups, restores, and snapshots</p>
</li>
<li><p>Automated software patching and upgrades</p>
</li>
<li><p>Automated scaling of storage and compute capacity</p>
</li>
<li><p>Automated failover and high availability</p>
</li>
<li><p>Automated encryption and security</p>
</li>
<li><p>Automated monitoring and metrics</p>
</li>
</ul>
<p>Amazon RDS also provides you with the flexibility to customize your database settings, such as:</p>
<ul>
<li><p>Choosing the database engine and version</p>
</li>
<li><p>Choosing the instance type and size</p>
</li>
<li><p>Choosing the storage type and size</p>
</li>
<li><p>Choosing the availability zone and region</p>
</li>
<li><p>Choosing the security group and VPC</p>
</li>
<li><p>Choosing the parameter group and option group</p>
</li>
<li><p>Choosing the maintenance window and backup window</p>
</li>
</ul>
<p>With Amazon RDS, you can focus on your application logic and data, without worrying about the underlying infrastructure and administration of your database. You can also leverage the integration of Amazon RDS with other AWS services, such as Amazon EC2, Amazon S3, Amazon Lambda, and Amazon CloudFormation.</p>
<h2 id="heading-creating-a-free-tier-rds-instance-of-mysql">Creating a Free Tier RDS Instance of MySQL</h2>
<p>In this section, I’ll show you how to create a free tier RDS instance of MySQL using the AWS Management Console. A free tier RDS instance is an instance that is eligible for the AWS Free Tier, which allows you to use certain AWS services for free for 12 months. A free tier RDS instance of MySQL has the following specifications:</p>
<ul>
<li><p>Database engine: MySQL 8.0</p>
</li>
<li><p>Instance type: db.t2.micro</p>
</li>
<li><p>Storage type: General Purpose SSD (gp2)</p>
</li>
<li><p>Storage size: 20 GB</p>
</li>
<li><p>Backup retention period: 7 days</p>
</li>
<li><p>Multi-AZ deployment: No</p>
</li>
</ul>
<p>To create a free tier RDS instance of MySQL, follow these steps:</p>
<ol>
<li><p>Sign in to the AWS Management Console and open the Amazon RDS console at <a target="_blank" href="https://console.aws.amazon.com/rds/">https://console.aws.amazon.com/rds/</a>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699966711961/965d8714-b161-4dfa-bae2-6a349954892e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the navigation pane, choose <strong>Databases</strong> and then choose <strong>Create database</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699966746740/ebcea9a4-60d6-4010-b8e6-bf6ef44811fb.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>On the <strong>Create database</strong> page, choose <strong>Standard create</strong> and then choose <strong>MySQL</strong> as the database engine.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699966854618/929dab54-d8d7-4c0a-b484-c0ac4ab22e07.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Templates</strong>, choose <strong>Free tier</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700015562484/d8641760-14ef-48e5-97a0-e0e2fe999692.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Settings</strong>, enter a name for your database instance, such as <code>my-mysql-db</code>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700015667907/e88b9048-2b38-4867-a408-b8a9b6f8ad87.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Credentials Settings</strong>, enter a username and a password for your database, such as <code>admin</code> and <code>Password1234</code>. Remember these credentials as you’ll need them later to connect to your database.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700015721286/e590d94f-c0d1-495e-a1ed-d3c2d04c9e2d.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>DB instance size</strong>, choose <strong>Burstable classes (includes t classes)</strong> and then choose <strong>db.t2.micro</strong> as the instance type.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700015791073/315f569b-1190-4ed7-a5a4-6f321ac6328f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Storage</strong>, choose <strong>General Purpose (SSD)</strong> as the storage type and enter <code>20</code> as the allocated storage. Make sure that <strong>Enable storage autoscaling</strong> is disabled.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700015860227/c85e6326-9f5f-4a3a-bb99-524b273e4e06.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Connectivity</strong>, expand <strong>Additional connectivity configuration</strong> and choose <strong>Publicly accessible</strong> as the access option. This will allow you to connect to your database from your EC2 instance or any other device over the internet. You can also choose <strong>No</strong> if you want to restrict the access to your database within your VPC.</p>
</li>
<li><p>Under <strong>VPC security group</strong>, choose <strong>Create new</strong> and enter a name for your security group, such as <code>my-mysql-sg</code>. This will create a new security group that allows inbound traffic on port 3306 (the default port for MySQL) from any IP address. You can also choose <strong>Choose existing</strong> and select an existing security group that has the same rule. You can also modify the rule later to limit the access to your database from specific IP addresses or CIDR blocks.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700016878140/0ee9cb3b-bebe-4ad7-8a64-9e9c91fac9db.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Database authentication</strong>, choose <strong>Password authentication</strong> as the authentication method. This will allow you to connect to your database using the username and password that you entered earlier. You can also choose <strong>IAM authentication</strong> if you want to use AWS Identity and Access Management (IAM) to manage access to your database.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700016931149/c824654c-412b-4045-876c-1b99c126e1b9.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Additional configuration</strong>, enter a name for your database, such as <code>mydb</code>. This will create a default database in your instance that you can use to store your data. You can also leave this blank and create your own databases later using the MySQL client.</p>
</li>
<li><p>Under <strong>Backup</strong>, choose <strong>Enable automatic backups</strong> and enter <code>7</code> as the backup retention period. This will enable the automated backup feature of Amazon RDS, which will take daily snapshots of your database and store them for 7 days. You can also choose <strong>Disable automatic backups</strong> if you don’t want to use this feature. You can also modify the backup window and the backup encryption settings later.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700017074280/009742be-e3db-42e5-8819-31cc558f24cb.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Monitoring</strong>, choose <strong>Enable Enhanced monitoring</strong> and enter <code>60</code> as the granularity. This will enable the enhanced monitoring feature of Amazon RDS, which will collect and display metrics about your database instance every 60 seconds. You can also choose <strong>Disable Enhanced monitoring</strong> if you don’t want to use this feature. You can also modify the monitoring role and the additional metrics settings later.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700017181213/a1ea82fb-773e-40ee-a97d-80fbf00fc408.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Log exports</strong>, choose <strong>Enable log exports</strong> and select the logs that you want to export to Amazon CloudWatch Logs, such as <strong>General log</strong>, <strong>Slow query log</strong>, and <strong>Error log</strong>. This will enable the log export feature of Amazon RDS, which will send the selected logs to CloudWatch Logs for analysis and troubleshooting. You can also choose <strong>Disable log exports</strong> if you don’t want to use this feature.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700017213593/d6c14666-9791-4f55-91af-6294c1183981.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Maintenance</strong>, choose <strong>Enable auto minor version upgrade</strong>. This will enable the auto minor version upgrade feature of Amazon RDS, which will automatically apply minor version patches and updates to your database engine. You can also choose <strong>Disable auto minor version upgrade</strong> if you don’t want to use this feature. You can also modify the maintenance window and the deletion protection settings later.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700017248095/b6370528-e08b-4cae-a882-cad34b22cb17.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose <strong>Create database</strong> to create your database instance. This will take a few minutes to complete. You can monitor the progress of the creation on the <strong>Databases</strong> page of the Amazon RDS console. You can also view the details of your database instance, such as the endpoint, the port, the status, and the metrics, on the same page.</p>
</li>
</ol>
<p>Congratulations! You have successfully created a free tier RDS instance of MySQL using the AWS Management Console.</p>
<h2 id="heading-creating-an-ec2-instance">Creating an EC2 Instance</h2>
<p>An EC2 instance is a virtual server that runs in the AWS cloud. You can use an EC2 instance to run applications, host websites, or perform any other tasks that require compute resources. You can also use an EC2 instance to connect to your RDS instance using a MySQL client, as I’ll show you in this section.</p>
<p>To create an EC2 instance using the AWS Management Console, follow these steps:</p>
<ol>
<li><p>Sign in to the AWS Management Console and open the Amazon EC2 console at <a target="_blank" href="https://console.aws.amazon.com/ec2/">https://console.aws.amazon.com/ec2/</a>.</p>
</li>
<li><p>In the navigation pane, choose <strong>Instances</strong> and then choose <strong>Launch Instance</strong>.</p>
</li>
<li><p>On the <strong>Choose an Amazon Machine Image (AMI)</strong> page, choose <strong>Amazon Linux 2 AMI (HVM), SSD Volume Type</strong> as the AMI. This is a Linux-based AMI that comes with the AWS CLI and other tools pre-installed. You can also choose another AMI that suits your needs, such as Windows or Ubuntu.</p>
</li>
<li><p>On the <strong>Choose an Instance Type</strong> page, choose <strong>t2.micro</strong> as the instance type. This is a free tier eligible instance type that provides a small amount of CPU and memory resources. You can also choose another instance type that suits your needs, such as t3 or m5.</p>
</li>
<li><p>On the <strong>Configure Instance Details</strong> page, leave the default settings and choose <strong>Next: Add Storage</strong>.</p>
</li>
<li><p>On the <strong>Add Storage</strong> page, leave the default settings and choose <strong>Next: Add Tags</strong>.</p>
</li>
<li><p>On the <strong>Add Tags</strong> page, choose <strong>Add Tag</strong> and enter <code>Name</code> as the key and <code>my-ec2-instance</code> as the value. This will assign a name tag to your instance, which will help you to identify it later. You can also add other tags as per your requirements.</p>
</li>
<li><p>On the <strong>Configure Security Group</strong> page, choose <strong>Create a new security group</strong> and enter a name for your security group, such as <code>my-ec2-sg</code>. This will create a new security group that allows inbound traffic on port 22 (the default port for SSH) from any IP address. You can also choose <strong>Select an existing security group</strong> and select an existing security group that has the same rule. You can also modify the rule later to limit the access to your instance from specific IP addresses or CIDR blocks.</p>
</li>
<li><p>Choose <strong>Review and Launch</strong> to review your instance settings and then choose <strong>Launch</strong> to launch your instance. This will take a few minutes to complete. You can monitor the progress of the launch on the <strong>Instances</strong> page of the Amazon EC2 console. You can also view the details of your instance, such as the public IP address, the status, and the metrics, on the same page.</p>
</li>
<li><p>When your instance is running, choose <strong>Connect</strong> to connect to your instance using SSH. You’ll need to select a key pair that you have access to, or create a new one if you don’t have one. A key pair consists of a public key and a private key that are used to encrypt and decrypt the communication between your instance and your device. You’ll need to download and save the private key file (.pem) to your device and change its permissions to make it readable only by you. You’ll also need to use a terminal or a shell program that supports SSH, such as PuTTY or Git Bash. You’ll see a command like this that you can use to connect to your instance:</p>
</li>
</ol>
<pre><code class="lang-bash">ssh -i <span class="hljs-string">"my-key-pair.pem"</span> ec2-user@ec2-18-222-111-222.us-east-2.compute.amazonaws.com
</code></pre>
<p>where <code>my-key-pair.pem</code> is the name of your private key file, <code>ec2-user</code> is the default user name for the Amazon Linux 2 AMI, and <a target="_blank" href="http://ec2-18-222-111-222.us-east-2.compute.amazonaws.com"><code>ec2-18-222-111-222.us-east-2.compute.amazonaws.com</code></a> is the public DNS name of your instance. You can also use the public IP address of your instance instead of the public DNS name.</p>
<ol>
<li>When you connect to your instance, you’ll see a welcome message like this:</li>
</ol>
<pre><code class="lang-bash">       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-31-41-222 ~]$
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700019382364/b2c557e4-e3a5-4d94-bc21-75e5ddfa4795.png" alt class="image--center mx-auto" /></p>
<p>This means that you have successfully connected to your EC2 instance. You can now run commands on your instance, such as <code>ls</code>, <code>pwd</code>, and <code>sudo yum update</code>.</p>
<p>Congratulations! You have successfully created an EC2 instance using the AWS Management Console.</p>
<h2 id="heading-creating-an-iam-role-with-rds-access-and-assigning-it-to-ec2">Creating an IAM Role with RDS Access and Assigning it to EC2</h2>
<p>An IAM role is a set of permissions that you can use to grant access to AWS resources and services. You can create an IAM role and assign it to your EC2 instance, so that your instance can access your RDS instance without using any credentials. This is a secure and convenient way to connect to your RDS instance from your EC2 instance.</p>
<p>To create an IAM role with RDS access and assign it to your EC2 instance using the AWS Management Console, follow these steps:</p>
<ol>
<li><p>Sign in to the AWS Management Console and open the IAM console at <a target="_blank" href="https://console.aws.amazon.com/iam/">https://console.aws.amazon.com/iam/</a>.</p>
</li>
<li><p>In the navigation pane, choose <strong>Roles</strong> and then choose <strong>Create Role</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700019447042/003561e7-f7a2-4d32-8a97-491efad680b3.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>On the <strong>Create role</strong> page, choose <strong>AWS service</strong> as the type of trusted entity and choose <strong>EC2</strong> as the service that will use this role. Then choose <strong>Next: Permissions</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700019554483/3320e26b-64b1-4616-8a73-d23779268cf0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>On the <strong>Add Permissions</strong> page, search for <strong>AmazonRDSFullAccess</strong> and select the checkbox next to it. This is a managed policy that grants full access to Amazon RDS. You can also choose another policy that suits your needs, such as <strong>AmazonRDSReadOnlyAccess</strong> or <strong>AmazonRDSCustomPolicy</strong>. You can also create your own custom policy with specific permissions for Amazon RDS.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700019696895/db37d96b-3d2a-42ad-8d7d-4d2232c2104e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose <strong>Next: Tags</strong> and then choose <strong>Next: Review</strong>.</p>
</li>
<li><p>On the <strong>Review</strong> page, enter a name for your role, such as <code>my-ec2-rds-role</code>. You can also enter an optional description for your role. Then choose <strong>Create role</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700019796475/77555c0b-0c54-48c7-bf00-98cb7bf4b4d5.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>On the <strong>Roles</strong> page, search for the role that you just created and select it. You’ll see the details of your role, such as the policy, the trust relationship, and the ARN.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700019849548/e35182f6-4ae5-48a3-a185-4caf32429572.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Open the Amazon EC2 console in a new tab or window at <a target="_blank" href="https://console.aws.amazon.com/ec2/">https://console.aws.amazon.com/ec2/</a>.</p>
</li>
<li><p>In the navigation pane, choose <strong>Instances</strong> and select the instance that you created in the previous section. Then from Actions choose <strong>Security</strong>, and <strong>Modify IAM Role</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700020070964/55e71e5c-bafd-49c1-b8e3-4333644d49d9.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>On the <strong>Modify IAM Role</strong> page, choose the role that you created in the previous steps from the <strong>IAM role</strong> dropdown list. Then choose <strong>Apply</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700020122014/164e283c-46a0-4f1e-9ca9-1994e70d0da9.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>Congratulations! You have successfully created an IAM role with RDS access and assigned it to your EC2 instance using the AWS Management Console.</p>
<h2 id="heading-connecting-your-ec2-instance-to-your-rds-instance-using-a-mysql-client">Connecting your EC2 Instance to your RDS Instance using a MySQL Client</h2>
<p>A MySQL client is a software program that allows you to interact with a MySQL server, such as your RDS instance, using commands or queries. You can use a MySQL client to create and manage databases, tables, and data on your RDS instance. You can also use a MySQL client to perform basic operations on your MySQL database, such as inserting, updating, deleting, and selecting data.</p>
<p>To connect your EC2 instance to your RDS instance using a MySQL client, follow these steps:</p>
<ol>
<li><p>Connect to your EC2 instance using SSH, as you did in the previous section.</p>
</li>
<li><p>Install the MySQL client on your EC2 instance using the <code>sudo yum install mysql</code> command. This will install the MySQL client and its dependencies on your instance. You should see an output like this:</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700020350345/53174229-bf7b-45c7-9b29-f3d8ee58954a.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>This means that the MySQL client has been installed successfully on your instance.</p>
<ol>
<li>Connect to your RDS instance using the MySQL client using the <code>mysql</code> command. The syntax of the command is:</li>
</ol>
<pre><code class="lang-bash">mysql -h hostname -P port -u username -p
</code></pre>
<p>where <code>hostname</code> is the endpoint of your RDS instance, <code>port</code> is the port number of your RDS instance, <code>username</code> is the username of your database, and <code>-p</code> prompts you to enter the password of your database. For example, to connect to the RDS instance that you created in the previous section, you can run the following command:</p>
<pre><code class="lang-bash">mysql -h my-mysql-db.cwqfjzqfjzqf.us-east-2.rds.amazonaws.com -P 3306 -u admin -p
</code></pre>
<p>where <a target="_blank" href="http://my-mysql-db.cwqfjzqfjzqf.us-east-2.rds.amazonaws.com"><code>my-mysql-db.cwqfjzqfjzqf.us-east-2.rds.amazonaws.com</code></a> is the endpoint of your RDS instance, <code>3306</code> is the port number of your RDS instance, <code>admin</code> is the username of your database, and <code>-p</code> prompts you to enter the password of your database. You can find the endpoint and the port number of your RDS instance on the <strong>Databases</strong> page of the Amazon RDS console.</p>
<p>You’ll be prompted to enter the password of your database. Enter the password that you entered when you created your RDS instance and press <strong>Enter</strong>. You should see a message like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700020741729/24d7bc70-c1a7-43a0-a55d-49cf47c34626.png" alt class="image--center mx-auto" /></p>
<p>This means that you have successfully connected to your RDS instance using the MySQL client. You can now run commands or queries on your MySQL database using the MySQL client. For example, you can run the following command to show the databases on your RDS instance:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700020787177/e699c93f-da3f-45ea-9b88-b0ebcdf930ea.png" alt class="image--center mx-auto" /></p>
<p>You can see that there are five databases on your RDS instance, including the default database <code>mydb</code> that you created when you created your RDS instance. You can also run other commands or queries on your MySQL database, such as creating tables, inserting data, updating data, deleting data, and selecting data.</p>
<p>Congratulations! You have successfully connected your EC2 instance to your RDS instance using a MySQL client.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, I showed you how to use Amazon RDS to set up and manage MySQL databases in AWS. You learned how to:</p>
<ul>
<li><p>Create a free tier RDS instance of MySQL</p>
</li>
<li><p>Create an EC2 instance</p>
</li>
<li><p>Create an IAM role with RDS access</p>
</li>
<li><p>Assign the role to EC2 so that your EC2 instance can connect with RDS</p>
</li>
<li><p>Connect your EC2 instance to your RDS instance using a MySQL client</p>
</li>
</ul>
<p>By using Amazon RDS, you can enjoy the benefits of a fully managed database service, such as automated backups, scaling, failover, encryption, monitoring, and patching. You can also customize your database settings, such as the engine, the instance type, the storage, the security, and the authentication. You can also leverage the integration of Amazon RDS with other AWS services, such as Amazon EC2, Amazon S3, Amazon Lambda, and Amazon CloudFormation.</p>
<p>I hope you enjoyed this blog post and learned something new. If you have any questions or feedback, please feel free to leave a comment below. I’d love to hear from you.</p>
<p>Thank you for reading and happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[How to Use AWS CLI to Manage Data in Amazon S3 | Day 43 of 90 Days of DevOps]]></title><description><![CDATA[Are you a DevOps learner who wants to use S3 programmatic access with AWS CLI? If yes, then this blog post is for you. In this post, I’ll explain what S3 is and how to use AWS CLI, a unified tool to manage your AWS services from the command line.
By ...]]></description><link>https://blog.ajitfawade.com/how-to-use-aws-cli-to-manage-data-in-amazon-s3</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-use-aws-cli-to-manage-data-in-amazon-s3</guid><category><![CDATA[Devops]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[aws cli]]></category><category><![CDATA[AWS s3]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Mon, 13 Nov 2023 21:50:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699912247646/6899195c-8489-4914-b48a-9a9b362d88c8.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a DevOps learner who wants to use S3 programmatic access with AWS CLI? If yes, then this blog post is for you. In this post, I’ll explain what S3 is and how to use AWS CLI, a unified tool to manage your AWS services from the command line.</p>
<p>By the end of this post, you’ll be able to:</p>
<ul>
<li><p>Create and delete S3 buckets</p>
</li>
<li><p>Upload and download files to and from S3 buckets</p>
</li>
<li><p>Sync local folders with S3 buckets</p>
</li>
<li><p>Generate pre-signed URLs for S3 objects</p>
</li>
<li><p>List S3 buckets and objects</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-what-is-s3">What is S3?</h2>
<p>Amazon Simple Storage Service (Amazon S3) is an object storage service that provides a secure and scalable way to store and access data on the cloud. It is designed for storing any kind of data, such as text files, images, videos, backups, and more. S3 is commonly used for various purposes, including backup and restore, data archiving, content distribution, and hosting static websites.</p>
<p>S3 has the following features and benefits:</p>
<ul>
<li><p>S3 offers different storage classes to optimize cost and performance based on your data access patterns. The available classes include Standard, Intelligent-Tiering, Standard-IA (Infrequent Access), One Zone-IA, Glacier, and Glacier Deep Archive.</p>
</li>
<li><p>S3 has storage management features that you can use to manage costs, meet regulatory requirements, reduce latency, and save multiple distinct copies of your data for compliance requirements. For example, you can use lifecycle management to automatically move your data to different storage classes as it ages, object lock to prevent your data from being deleted or overwritten for a specified period, and replication to copy your data to multiple regions for high availability and disaster recovery.</p>
</li>
<li><p>S3 offers various mechanisms to control access to your buckets and objects. You can use access control lists (ACLs) and bucket policies to define granular permissions for different users and applications. You can also use encryption and encryption keys to protect your data at rest and in transit.</p>
</li>
<li><p>S3 provides logging and monitoring tools that you can use to track and analyze how your S3 resources are being used. You can also use features like S3 Object Lambda and Event Notifications to transform data and trigger workflows to automate a variety of other processing activities at scale.</p>
</li>
</ul>
<p>To use S3, you need to create buckets and objects. A bucket is a container for storing objects, and an object is a file or a piece of data that you store in a bucket. Each object has a unique key, which is the name of the object, and a value, which is the data of the object. You can also store metadata, which is additional information about the object, such as the size, date, and content type.</p>
<p>You can access S3 using various methods, such as the AWS Management Console, the AWS SDKs, the AWS CLI, or the S3 API. In this blog post, we’ll focus on using the AWS CLI, which is a unified tool that provides a command-line interface for interacting with AWS services.</p>
<p>Before we start, you’ll need to have the following prerequisites:</p>
<ul>
<li><p>An AWS account with access to Amazon S3 and Amazon EC2</p>
</li>
<li><p>An EC2 instance running Linux or Windows</p>
</li>
<li><p>The AWS CLI installed and configured on your EC2 instance</p>
</li>
<li><p>A text editor of your choice</p>
</li>
</ul>
<h2 id="heading-creating-and-deleting-s3-buckets">Creating and Deleting S3 Buckets</h2>
<p>An S3 bucket is a container for storing objects in Amazon S3. Each bucket has a unique name that must be globally unique across all AWS regions. You can create up to 100 buckets per AWS account by default, but you can request a limit increase if you need more.</p>
<p>To create an S3 bucket using the AWS CLI, you can use the <code>aws s3 mb</code> command. The syntax of the command is:</p>
<pre><code class="lang-bash">aws s3 mb s3://bucket-name
</code></pre>
<p>where <code>bucket-name</code> is the name of the bucket that you want to create. For example, to create a bucket named <code>ajits-bucket-2023</code>, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 mb s3://ajits-bucket-2023
</code></pre>
<p>You should see a message like this:</p>
<pre><code class="lang-bash">make_bucket: ajits-bucket-2023
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699907653764/72f2842d-9d48-499a-914e-6202e0cade66.png" alt class="image--center mx-auto" /></p>
<p>This means that the bucket has been created successfully. You can verify that the bucket exists by using the <code>aws s3 ls</code> command, which lists all the buckets in your AWS account. You should see something like this:</p>
<pre><code class="lang-bash">2023-11-14 02:03:04 ajits-bucket-2023
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699907710847/e3a7653a-d488-4abf-ab1b-7df3978ce510.png" alt class="image--center mx-auto" /></p>
<p>To delete an S3 bucket using the AWS CLI, you can use the <code>aws s3 rb</code> command. The syntax of the command is:</p>
<pre><code class="lang-bash">aws s3 rb s3://bucket-name
</code></pre>
<p>where <code>bucket-name</code> is the name of the bucket that you want to delete. For example, to delete the bucket that we just created, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 rb s3://ajits-bucket-2023
</code></pre>
<p>You should see a message like this:</p>
<pre><code class="lang-bash">remove_bucket: ajits-bucket-2023
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699907767662/35f73173-14f2-4c8e-a879-d35abea74c49.png" alt class="image--center mx-auto" /></p>
<p>This means that the bucket has been deleted successfully. You can verify that the bucket no longer exists by using the <code>aws s3 ls</code> command again. You should not see the bucket in the output.</p>
<p><strong>Note:</strong> You can only delete an empty bucket using the <code>aws s3 rb</code> command. If the bucket contains any objects, you’ll need to delete them first using the <code>aws s3 rm</code> command or the <code>--force</code> option.</p>
<h2 id="heading-uploading-and-downloading-files-to-and-from-s3-buckets">Uploading and Downloading Files to and from S3 Buckets</h2>
<p>Once you have an S3 bucket, you can upload and download files to and from it using the AWS CLI. A file in Amazon S3 is called an object, and it has a key and a value. The key is the name of the object, and the value is the content of the object. Each object can be up to 5 TB in size, and you can store an unlimited number of objects in a bucket.</p>
<p>To upload a file to an S3 bucket using the AWS CLI, you can use the <code>aws s3 cp</code> command. The syntax of the command is:</p>
<pre><code class="lang-bash">aws s3 cp <span class="hljs-built_in">source</span> destination
</code></pre>
<p>where <code>source</code> is the path of the file that you want to upload, and <code>destination</code> is the S3 URI of the bucket and the key of the object that you want to create. For example, to upload a file named <code>hello.txt</code> from your EC2 instance to a bucket named <code>ajits-bucket-2023</code> with the key <code>hello.txt</code>, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 cp hello.txt s3://ajits-bucket-2023/hello.txt
</code></pre>
<p>You should see a message like this:</p>
<pre><code class="lang-bash">upload: ./hello.txt to s3://ajits-bucket-2023/hello.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699908283451/d39b1f2d-ed32-4833-b620-bb987eedd167.png" alt class="image--center mx-auto" /></p>
<p>This means that the file has been uploaded successfully. You can verify that the object exists by using the <code>aws s3 ls</code> command with the S3 URI of the bucket. You should see something like this:</p>
<pre><code class="lang-bash">2023-11-14 02:14:00         23 hello.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699908404617/cb769ab0-317b-4ff4-b231-0ff4a9a03dd9.png" alt class="image--center mx-auto" /></p>
<p>To download a file from an S3 bucket using the AWS CLI, you can use the <code>aws s3 cp</code> command again, but with the source and destination reversed. For example, to download the file that we just uploaded from the bucket to your EC2 instance, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 cp s3://ajits-bucket-2023/hello.txt hello.txt
</code></pre>
<p>You should see a message like this:</p>
<pre><code class="lang-bash">download: s3://ajits-bucket-2023/hello.txt to ./hello.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699908649888/07dd3c2e-bd58-4025-97ad-db1ff14e8bdc.png" alt class="image--center mx-auto" /></p>
<p>This means that the file has been downloaded successfully. You can verify that the file exists by using the <code>ls</code> command on your EC2 instance. You should see something like this:</p>
<pre><code class="lang-bash">hello.txt
</code></pre>
<p><strong>Note:</strong> You can also use the <code>aws s3 mv</code> command to move files to and from S3 buckets, instead of copying them. This will delete the source file after the transfer is complete.</p>
<h2 id="heading-syncing-local-folders-with-s3-buckets">Syncing Local Folders with S3 Buckets</h2>
<p>Sometimes, you may want to sync the contents of a local folder with an S3 bucket, or vice versa. This can be useful for backup, migration, or synchronization purposes. You can use the AWS CLI to sync folders with S3 buckets using the <code>aws s3 sync</code> command. The syntax of the command is:</p>
<pre><code class="lang-bash">aws s3 sync <span class="hljs-built_in">source</span> destination
</code></pre>
<p>where <code>source</code> and <code>destination</code> are the paths of the folders or the S3 URIs of the buckets that you want to sync. For example, to sync a local folder named <code>my-folder</code> with a bucket named <code>ajits-bucket-2023</code>, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 sync my-folder s3://ajits-bucket-2023
</code></pre>
<p>This will copy any files that are in the local folder but not in the bucket, and vice versa. It will also update any files that have changed since the last sync. You should see messages like this:</p>
<pre><code class="lang-bash">upload: my-folder/file1.txt to s3://ajits-bucket-2023/file1.txt
</code></pre>
<p>This means that the sync has been completed successfully. You can verify that the folder and the bucket have the same contents by using the <code>ls</code> and <code>aws s3 ls</code> commands. You should see something like this:</p>
<pre><code class="lang-bash">my-folder:
file1.txt  hello.txt

s3://ajits-bucket-2023:
2023-11-14 02:56:40          0 file1.txt
2023-11-14 02:14:00         23 hello.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699910932680/dc31d0a9-31f9-4306-9192-b1b5e4886fbd.png" alt class="image--center mx-auto" /></p>
<p><strong>Note:</strong> You can use the <code>--delete</code> option to delete any files that are in the destination but not in the source. This will make the destination match the source exactly.</p>
<h2 id="heading-generating-pre-signed-urls-for-s3-objects">Generating Pre-Signed URLs for S3 Objects</h2>
<p>A pre-signed URL is a URL that grants temporary access to an S3 object, without requiring AWS credentials. You can use pre-signed URLs to share S3 objects with others or to allow others to upload or download S3 objects. Pre-signed URLs have an expiration time, after which they become invalid.</p>
<p>To generate a pre-signed URL for an S3 object using the AWS CLI, you can use the <code>aws s3 presign</code> command. The syntax of the command is:</p>
<pre><code class="lang-bash">aws s3 presign s3://bucket-name/object-key
</code></pre>
<p>where <code>bucket-name</code> and <code>object-key</code> are the name of the bucket and the key of the object that you want to generate a pre-signed URL for. For example, to generate a pre-signed URL for the file <code>hello.txt</code> that we uploaded earlier, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 presign s3://ajits-bucket-2023/hello.txt
</code></pre>
<p>You should see a URL like this:</p>
<pre><code class="lang-bash">https://ajits-bucket-2023.s3.ap-south-1.amazonaws.com/hello.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=AKIAYKSQYUGGDOPB6TH3%2F20231113%2Fap-south-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20231113T212920Z&amp;X-Amz-Expires=3600&amp;X-Amz-SignedHeaders=host&amp;X-Amz-Signature=21b7d769ba821701e575b57d9f4069322f6799d1e15a15f2cee3da4d3d096f8c
</code></pre>
<p>This is the pre-signed URL that you can share with others to grant them access to the file. The URL contains the following components:</p>
<ul>
<li><p>The bucket name and the object key</p>
</li>
<li><p>The AWS access key ID of the user who generated the URL</p>
</li>
<li><p>The signature of the URL, which is calculated using the AWS secret access key of the user who generated the URL</p>
</li>
<li><p>The expiration time of the URL, which is specified in Unix epoch time</p>
</li>
</ul>
<p>By default, the pre-signed URL expires in 3600 seconds (one hour) from the time it is generated. You can change the expiration time by using the <code>--expires-in</code> option with the <code>aws s3 presign</code> command. The value of the option is the number of seconds that you want the URL to be valid for. For example, to generate a pre-signed URL that expires in 10 minutes, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 presign s3://ajits-bucket-2023/hello.txt --expires-in 600
</code></pre>
<p>You should see a URL like this:</p>
<pre><code class="lang-bash">https://ajits-bucket-2023.s3.amazonaws.com/hello.txt?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&amp;Signature=Zkyj4tCckG8gCycXkz5a%2BYdl%2Fbg%3D&amp;Expires=2023-11-14T01%3A45%3A00Z
</code></pre>
<p>Notice that the <code>Expires</code> parameter has changed to reflect the new expiration time.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699911049998/1914d91b-0ba6-48e0-b543-481a764675dd.png" alt class="image--center mx-auto" /></p>
<p>You can test the pre-signed URL by opening it in a browser or using a tool like <code>curl</code>. You should be able to access the file without any authentication. However, if you try to access the URL after it has expired, you’ll get an error message like this:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Error</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">Code</span>&gt;</span>AccessDenied<span class="hljs-tag">&lt;/<span class="hljs-name">Code</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">Message</span>&gt;</span>Invalid date (should be seconds since epoch): 2023-11-14T01:45:00Z<span class="hljs-tag">&lt;/<span class="hljs-name">Message</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">RequestId</span>&gt;</span>ZS40VWNC265KCA8G<span class="hljs-tag">&lt;/<span class="hljs-name">RequestId</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">HostId</span>&gt;</span>txGSoSf4qrwtgnkFrda0IrRzYGWenxj1Za/k5L4I/m/0PIGIPLbFZW4SdwVctGoZPfwRThMHl0g=<span class="hljs-tag">&lt;/<span class="hljs-name">HostId</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Error</span>&gt;</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699911245392/0d90ad90-8d43-4ccf-98bf-6cd73114ccdd.png" alt class="image--center mx-auto" /></p>
<p>This means that the URL is no longer valid and you’ll need to generate a new one if you want to access the file again.</p>
<p><strong>Note:</strong> You can also use the <code>aws s3api get-object</code> command to generate a pre-signed URL for an S3 object, using the <code>--presigned-url</code> option. This command uses the S3 API instead of the S3 high-level commands, and it allows you to specify additional parameters for the URL, such as the HTTP method, the content type, and the response headers. For more information, see the AWS CLI documentation.</p>
<h2 id="heading-listing-s3-buckets-and-objects">Listing S3 Buckets and Objects</h2>
<p>Another useful task that you can perform with the AWS CLI is listing the S3 buckets and objects in your AWS account. This can help you to keep track of your data and manage your storage usage. You can use the <code>aws s3 ls</code> and <code>aws s3api list-buckets</code> commands to list S3 buckets and objects using the AWS CLI.</p>
<p>The <code>aws s3 ls</code> command is a high-level command that lists the S3 buckets or objects in a simple and human-readable format. The syntax of the command is:</p>
<pre><code class="lang-bash">aws s3 ls [s3://bucket-name]
</code></pre>
<p>where <code>s3://bucket-name</code> is the optional S3 URI of the bucket that you want to list the objects in. If you omit the bucket name, the command will list all the buckets in your AWS account. For example, to list all the buckets in your AWS account, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 ls
</code></pre>
<p>You should see an output like this:</p>
<pre><code class="lang-bash">2023-11-14 02:13:54 ajits-bucket-2023
</code></pre>
<p>This output shows the creation date and the name of each bucket in your AWS account.</p>
<p>To list the objects in a specific bucket, you can specify the bucket name in the command. For example, to list the objects in the bucket <code>ajits-bucket-2023</code>, you can run the following command:</p>
<pre><code class="lang-bash">aws s3 ls s3://ajits-bucket-2023
</code></pre>
<p>You should see an output like this:</p>
<pre><code class="lang-bash">2023-11-14 02:56:40          0 file1.txt
2023-11-14 02:14:00         23 hello.txt
</code></pre>
<p>This output shows the last modified date, the size, and the key of each object in the bucket.</p>
<p>The <code>aws s3api list-buckets</code> command is a low-level command that lists the S3 buckets in your AWS account using the S3 API. The syntax of the command is:</p>
<pre><code class="lang-bash">aws s3api list-buckets
</code></pre>
<p>This command does not take any parameters. When you run this command, you should see an output like this:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"Buckets"</span>: [
        {
            <span class="hljs-attr">"Name"</span>: <span class="hljs-string">"ajits-bucket-2023"</span>,
            <span class="hljs-attr">"CreationDate"</span>: <span class="hljs-string">"2023-11-13T20:43:54+00:00"</span>
        }
    ],
    <span class="hljs-attr">"Owner"</span>: {
        <span class="hljs-attr">"ID"</span>: <span class="hljs-string">"2dea46f6bb11505667678a7a8fd9b319c2113393408dbcb3b4223a5a8d14122c"</span>
    }
}
</code></pre>
<p>This output shows the name and the creation date of each bucket in your AWS account, as well as the display name and the ID of the owner of the buckets. The output is in JSON format, which is more structured and machine-readable than the output of the <code>aws s3 ls</code> command.</p>
<p>To list the objects in a specific bucket using the S3 API, you can use the <code>aws s3api list-objects</code> command. The syntax of the command is:</p>
<pre><code class="lang-bash">aws s3api list-objects --bucket bucket-name
</code></pre>
<p>where <code>bucket-name</code> is the name of the bucket that you want to list the objects in. For example, to list the objects in the bucket <code>ajits-bucket-2023</code>, you can run the following command:</p>
<pre><code class="lang-bash">aws s3api list-objects --bucket ajits-bucket-2023
</code></pre>
<p>You should see an output like this:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"Contents"</span>: [
        {
            <span class="hljs-attr">"Key"</span>: <span class="hljs-string">"file1.txt"</span>,
            <span class="hljs-attr">"LastModified"</span>: <span class="hljs-string">"2023-11-13T21:26:40+00:00"</span>,
            <span class="hljs-attr">"ETag"</span>: <span class="hljs-string">"\"d41d8cd98f00b204e9800998ecf8427e\""</span>,
            <span class="hljs-attr">"Size"</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">"StorageClass"</span>: <span class="hljs-string">"STANDARD"</span>,
            <span class="hljs-attr">"Owner"</span>: {
                <span class="hljs-attr">"ID"</span>: <span class="hljs-string">"2dea46f6bb11505667678a7a8fd9b319c2113393408dbcb3b4223a5a8d14122c"</span>
            }
        },
        {
            <span class="hljs-attr">"Key"</span>: <span class="hljs-string">"hello.txt"</span>,
            <span class="hljs-attr">"LastModified"</span>: <span class="hljs-string">"2023-11-13T20:44:00+00:00"</span>,
            <span class="hljs-attr">"ETag"</span>: <span class="hljs-string">"\"a9e77f60fb986b347e8b65d5e3dc2e00\""</span>,
            <span class="hljs-attr">"Size"</span>: <span class="hljs-number">23</span>,
            <span class="hljs-attr">"StorageClass"</span>: <span class="hljs-string">"STANDARD"</span>,
            <span class="hljs-attr">"Owner"</span>: {
                <span class="hljs-attr">"ID"</span>: <span class="hljs-string">"2dea46f6bb11505667678a7a8fd9b319c2113393408dbcb3b4223a5a8d14122c"</span>
            }
        }
    ],
    <span class="hljs-attr">"RequestCharged"</span>: <span class="hljs-literal">null</span>
}
</code></pre>
<p>This output shows the key, the last modified date, the ETag, the size, the storage class, and the owner of each object in the bucket. The output is also in JSON format, which is more structured and machine-readable than the output of the <code>aws s3 ls</code> command.</p>
<p><strong>Note:</strong> You can use the <code>--output</code> option with the <code>aws s3api</code> commands to change the format of the output. The supported formats are <code>JSON</code>, <code>text</code>, and <code>table</code>. For more information, see the AWS CLI documentation.</p>
<p>That’s it for this section. In this section, I showed you how to list S3 buckets and objects using the AWS CLI. You learned how to use the <code>aws s3 ls</code> and <code>aws s3api list-buckets</code> commands to list the buckets in your AWS account, how to use the <code>aws s3 ls</code> and <code>aws s3api list-objects</code> commands to list the objects in a specific bucket. You also learned how to change the output format of the commands using the <code>--output</code> option.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, I showed you how to use the AWS CLI to manage data in Amazon S3. You learned how to perform the following tasks:</p>
<ul>
<li><p>Creating and deleting S3 buckets</p>
</li>
<li><p>Uploading and downloading files to and from S3 buckets</p>
</li>
<li><p>Syncing local folders with S3 buckets</p>
</li>
<li><p>Generating pre-signed URLs for S3 objects</p>
</li>
<li><p>Listing S3 buckets and objects</p>
</li>
</ul>
<p>By using the AWS CLI, you can automate tasks, manage resources, and perform operations that are not available in the AWS Management Console. You can also use the AWS CLI to interact with other AWS services, such as Amazon EC2, Amazon DynamoDB, and Amazon Lambda. The AWS CLI is a powerful and versatile tool that can help you work with AWS more efficiently and effectively.</p>
<p>I hope you enjoyed this blog post and learned something new. If you have any questions or feedback, please feel free to leave a comment below. I’d love to hear from you.</p>
<p>Thank you for reading and happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[IAM and AWS CLI: A Guide to Accessing AWS Services from the Command Line : Day 42 of 90 Days of DevOps]]></title><description><![CDATA[Are you a DevOps learner who wants to access AWS services from the command line using IAM programmatic access and AWS CLI? If yes, then this blog post is for you.
In this post, I’ll explain what IAM programmatic access is and how to use AWS CLI, a un...]]></description><link>https://blog.ajitfawade.com/how-to-access-aws-services-from-the-command-line-using-iam-programmatic-access-and-aws-cli</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-access-aws-services-from-the-command-line-using-iam-programmatic-access-and-aws-cli</guid><category><![CDATA[Devops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[IAM]]></category><category><![CDATA[aws cli]]></category><category><![CDATA[#90daysofdevops]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Wed, 08 Nov 2023 00:34:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699399893566/0ca61a9d-3505-48a1-9f7f-28fab2cd14c8.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a DevOps learner who wants to access AWS services from the command line using IAM programmatic access and AWS CLI? If yes, then this blog post is for you.</p>
<p>In this post, I’ll explain what IAM programmatic access is and how to use AWS CLI, a unified tool to manage your AWS services from the command line.</p>
<p>By the end of this post, you’ll be able to:</p>
<ul>
<li><p>Understand what IAM programmatic access is and why it is useful for your AWS account</p>
</li>
<li><p>Understand what AWS CLI is and how it works with AWS services</p>
</li>
<li><p>Create AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from AWS Console</p>
</li>
<li><p>Setup and install AWS CLI and configure your account credentials</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-what-is-iam-programmatic-access">What is IAM Programmatic Access?</h2>
<p>IAM programmatic access is a way to allow users or services to interact with AWS resources through APIs, SDKs, or command-line tools, such as AWS CLI, instead of the AWS Management Console. With programmatic access, users or services can perform automated tasks, manage resources, and access data in AWS without manual intervention.</p>
<p>To use programmatic access, you need to create access keys for your IAM user or role. Access keys consist of two parts:</p>
<ul>
<li><p>AWS_ACCESS_KEY_ID: A unique identifier for your access key</p>
</li>
<li><p>AWS_SECRET_ACCESS_KEY: A secret key that you use to sign requests to AWS</p>
</li>
</ul>
<p>You can use these access keys to authenticate your requests to AWS and authorize your actions on AWS resources. You can also rotate or delete your access keys as needed to maintain the security of your AWS account.</p>
<h2 id="heading-what-is-aws-cli">What is AWS CLI?</h2>
<p>AWS CLI (Command Line Interface) is a unified tool that provides a command-line interface for interacting with AWS services. It allows users to manage AWS resources using commands in the terminal or scripts, making it easier to automate tasks and manage large-scale deployments. The AWS CLI supports a wide range of AWS services, including EC2, S3, Lambda, and more, and can be installed on Windows, macOS, and Linux.</p>
<p>The AWS CLI v2 offers several new features including improved installers, new configuration options such as AWS IAM Identity Center (successor to AWS SSO), and various interactive features.</p>
<p>To use the AWS CLI, you need to configure your AWS credentials and region. You can do this by using the aws configure command or by setting environment variables or configuration files. You can also use profiles to manage multiple sets of credentials and configurations.</p>
<h2 id="heading-how-to-create-awsaccesskeyid-and-awssecretaccesskey-from-aws-console">How to Create AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from AWS Console</h2>
<p>To create AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from AWS Console, we’ll use the following steps:</p>
<ol>
<li><p><strong>Navigate to the IAM Console:</strong> Sign in to your AWS account and open the AWS Management Console. In the search bar at the top of the console, type "IAM" and select "IAM" from the search results.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699402396997/3076bdb7-780a-48e2-9a69-482a6cc6a9d2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>Access Users and Groups:</strong> In the IAM console's left navigation pane, choose "Users" under the "Access Management" section.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699402452950/1ae21b24-c702-47da-a358-364587f30160.png" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>Select the User:</strong> Locate the user for whom you want to create an access key and click on their username.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699402521478/b260cb1d-97ff-4129-a61f-d397d5d970db.png" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>Expand Security Credentials:</strong> In the user's details page, click on the "Security credentials" tab.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699402670240/2bad4a53-32ef-4da0-b00f-7dae8e6a3979.png" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>Create New Access Key:</strong> Under the "Access keys" section, click on the "Create access key" button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699402694133/0fae148c-de23-460f-9682-8ac9101cfc62.png" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>Review Access Key Details:</strong> A pop-up window will appear displaying your new access key ID and secret access key. Ensure you copy and paste these keys securely as they will be used to configure your AWS CLI later.</p>
</li>
<li><p><strong>Download Key File (Optional):</strong> If preferred, you can download the key file containing both the access key ID and secret access key.</p>
</li>
<li><p><strong>Click "Done":</strong> Once you have copied or downloaded the keys, click on the "Done" button to exit the Create access key section.</p>
</li>
<li><p><strong>Verify Access Key Creation:</strong> Your newly created access key will now appear in the list of access keys under the "Security credentials" tab. You can view the status, creation date, and last used date of the access key. You can also delete or deactivate the access key as needed.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699402290946/28d95653-a1fd-4fdc-8de5-5ad49170503f.png" alt class="image--center mx-auto" /></p>
<p> You have successfully created AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from the AWS Console.</p>
</li>
</ol>
<h2 id="heading-how-to-setup-and-install-aws-cli-and-configure-your-account-credentials">How to Setup and Install AWS CLI and Configure Your Account Credentials</h2>
<p>To setup and install AWS CLI and configure your account credentials, we’ll use the following steps:</p>
<ol>
<li><p>Go to the AWS CLI [download page] and choose the installer for your operating system. For example, you can choose <strong>Windows,</strong> <strong>Linux,</strong> or <strong>macOS</strong>.</p>
</li>
<li><p>Follow the instructions on the download page to install the AWS CLI on your system. For example, you can run the installer file or use the package manager to install the AWS CLI.</p>
</li>
<li><p>To verify that the AWS CLI is installed correctly, open a terminal or command prompt and run the following command:</p>
</li>
</ol>
<pre><code class="lang-bash">aws --version
</code></pre>
<p>This command will display the AWS CLI version and some other information. You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699403022785/10c2abcf-1030-4b4a-b7b5-13264259cdae.png" alt class="image--center mx-auto" /></p>
<ol>
<li>To configure your AWS credentials and region, run the following command:</li>
</ol>
<pre><code class="lang-bash">aws configure
</code></pre>
<p>This command will prompt you to enter your AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, default region, and default output format. You can enter the values that you obtained or prefer, or press Enter to skip the prompt. For example, you can enter something like this:</p>
<pre><code class="lang-bash">AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: json
</code></pre>
<p>This will create a default profile with the specified credentials and configuration in the ~/.aws/credentials and ~/.aws/config files. You can also use the --profile option to create or use a different profile. For example, you can run the following command to create a profile named dev:</p>
<pre><code class="lang-bash">aws configure --profile dev
</code></pre>
<ol>
<li>To verify that your AWS credentials and region are configured correctly, run the following command:</li>
</ol>
<pre><code class="lang-bash">aws sts get-caller-identity
</code></pre>
<p>This command will display the user ID, account ID, and ARN of the user or role that is making the request. You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699403145283/3b87e2be-82d4-4649-b745-1eb2ce51ba73.png" alt class="image--center mx-auto" /></p>
<p>You have successfully set up and installed AWS CLI and configured your account credentials.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this blog post, I have explained what IAM programmatic access is and how to use AWS CLI, a unified tool to manage your AWS services from the command line. I have also shown you how to create AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from AWS Console, set up and install AWS CLI, and configure your account credentials.</p>
<p>I hope you found this blog post informative and engaging.</p>
<p>This is the end of the blog post for Day 42 of 90 Days of DevOps.</p>
<p>Thank you for reading and stay tuned for more posts in this series! 😊</p>
]]></content:encoded></item><item><title><![CDATA[How to Set Up an Application Load Balancer with AWS EC2: Day 41 of 90 Days of DevOps]]></title><description><![CDATA[Are you a DevOps learner who wants to set up an application load balancer with AWS EC2? If yes, then this blog post is for you.

In this post, I’ll explain what load balancing is and how to use Elastic Load Balancing (ELB) in AWS EC2, a service that ...]]></description><link>https://blog.ajitfawade.com/how-to-set-up-an-application-load-balancer-with-aws-ec2</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-set-up-an-application-load-balancer-with-aws-ec2</guid><category><![CDATA[Devops]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[ec2]]></category><category><![CDATA[Load Balancing]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Tue, 07 Nov 2023 03:37:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699327392928/ab62c92b-d014-4016-9817-0da932f26ebc.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a DevOps learner who wants to set up an application load balancer with AWS EC2? If yes, then this blog post is for you.</p>
<blockquote>
<p><mark>In this post, I’ll explain what load balancing is and how to use Elastic Load Balancing (ELB) in AWS EC2, a service that automatically distributes incoming traffic across multiple EC2 instances.</mark></p>
</blockquote>
<p>By the end of this post, you’ll be able to:</p>
<ul>
<li><p>Understand what load balancing is and why it is important for your applications</p>
</li>
<li><p>Understand what ELB is and how it works in AWS EC2</p>
</li>
<li><p>Launch two EC2 instances with an Ubuntu AMI and use User Data to install the Apache Web Server</p>
</li>
<li><p>Modify the index.html file to include your name and a message</p>
</li>
<li><p>Create an Application Load Balancer (ALB) in EC2 using the AWS Management Console</p>
</li>
<li><p>Add EC2 instances to the ALB as target groups</p>
</li>
<li><p>Verify that the ALB is working properly by checking the health status of the target instances and testing the load balancing capabilities</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-what-is-load-balancing">What is Load Balancing?</h2>
<p>Load balancing is the distribution of workloads across multiple servers to ensure consistent and optimal resource utilization. It is an essential aspect of any large-scale and scalable computing system, as it helps you to improve the reliability and performance of your applications.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699321913680/cd60ac9c-3f5a-4629-a715-5a0112af6da4.png" alt class="image--center mx-auto" /></p>
<p>Load balancing can help you to achieve the following benefits:</p>
<ul>
<li><p>High availability: Load balancing can prevent your applications from becoming unavailable due to server failures or overloading. By distributing the traffic across multiple servers, load balancing can ensure that your applications can handle the requests even if one or more servers go down or become slow.</p>
</li>
<li><p>Fault tolerance: Load balancing can also help you to recover from server failures or errors. By detecting the unhealthy or unresponsive servers, load balancing can automatically redirect the traffic to the healthy or available servers, minimizing the impact on your applications and users.</p>
</li>
<li><p>Scalability: Load balancing can also help you to scale your applications according to the demand or traffic. By adding or removing servers from the load balancing pool, you can adjust the capacity and performance of your applications without affecting the user experience.</p>
</li>
</ul>
<h2 id="heading-what-is-elastic-load-balancing">What is Elastic Load Balancing?</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699321987708/e95048ef-da11-46be-a588-f8174f63bf91.png" alt class="image--center mx-auto" /></p>
<p>Elastic Load Balancing (ELB) is a service provided by Amazon Web Services (AWS) that automatically distributes incoming traffic across multiple EC2 instances. ELB provides three types of load balancers:</p>
<ul>
<li><p>Application Load Balancer (ALB): ALB operates at layer 7 of the OSI model and is ideal for applications that require advanced routing and microservices. ALB can route the traffic based on the content of the request, such as the URL path, the host header, the query parameters, etc. ALB can also support multiple protocols, such as HTTP, HTTPS, HTTP/2, WebSocket, and gRPC. ALB can also integrate with other AWS services, such as Amazon ECS, Amazon EKS, AWS Lambda, AWS WAF, etc.</p>
</li>
<li><p>Network Load Balancer (NLB): NLB operates at layer 4 of the OSI model and is ideal for applications that require high throughput and low latency. NLB can route the traffic based on the TCP or UDP port and the IP address of the destination. NLB can also support static or elastic IP addresses, long-lived TCP connections, and TLS termination. NLB can also integrate with other AWS services, such as Amazon VPC, Amazon EC2, AWS CloudFormation, etc.</p>
</li>
<li><p>Classic Load Balancer (CLB): CLB operates at layer 4 of the OSI model and is ideal for applications that require basic load balancing features. CLB can route the traffic based on the TCP or SSL port and the IP address of the destination. CLB can also support HTTP, HTTPS, SSL, and TCP protocols, health checks, sticky sessions, and cross-zone load balancing. CLB can also integrate with other AWS services, such as Amazon EC2, Amazon CloudWatch, etc.</p>
</li>
</ul>
<p>To illustrate how to use ELB in AWS EC2, we’ll use an example of setting up an ALB with two EC2 instances that run the Apache Web Server.</p>
<h2 id="heading-how-to-launch-two-ec2-instances-with-an-ubuntu-ami-and-use-user-data-to-install-the-apache-web-server">How to Launch Two EC2 Instances with an Ubuntu AMI and Use User Data to Install the Apache Web Server</h2>
<p>To launch two EC2 instances with an Ubuntu AMI and use User Data to install the Apache Web Server, we’ll use the following steps:</p>
<ol>
<li><p>Go to the AWS console and navigate to the EC2 service.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699323944555/a8d1836d-6f1e-435f-ae30-b8db85b5444e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on <strong>Launch Instance</strong> button and select <strong>Ubuntu Server 22.04 LTS (HVM), SSD Volume Type</strong> from the list of available AMIs.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699324022616/d4c30bb9-e9d6-4610-9bfd-889b152ff412.avif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose <strong>t2.micro</strong> from the list of available instance types.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699324084962/396ef701-8fdf-43f4-afe6-9a3ca97276ee.avif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose an existing key pair or create a new one if you don’t have one already. You’ll need this key pair to SSH into your instance later.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699324554410/c8ff1b35-053d-4551-a0ac-ec07e7ccac10.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>Configure Instance Details</strong> page, scroll down to the <strong>Advanced Details</strong> section and expand the <strong>User data</strong> field.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699324700254/ac277328-084a-4114-a5b1-195c9a200d6e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>User data</strong> field, enter the following commands to install and start the Apache Web Server:</p>
</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># Update packages</span>
sudo apt-get update -y
<span class="hljs-comment"># Install Apache</span>
sudo apt-get install -y apache2
<span class="hljs-comment"># Start Apache service</span>
sudo systemctl start apache2
<span class="hljs-comment"># Enable Apache service</span>
sudo systemctl <span class="hljs-built_in">enable</span> apache2
<span class="hljs-comment"># Modify index.html file</span>
sudo <span class="hljs-built_in">echo</span> <span class="hljs-string">"&lt;h1&gt;Welcome to AWS EC2&lt;/h1&gt;"</span> &gt; /var/www/html/index.html
sudo <span class="hljs-built_in">echo</span> <span class="hljs-string">"&lt;p&gt;My name is Ajit&lt;/p&gt;"</span> &gt;&gt; /var/www/html/index.html
</code></pre>
<ol>
<li><p>Expand Network settings<strong>:</strong> Create a new security group or select an existing one. Make sure to allow inbound traffic on port 80 for HTTP protocol from anywhere. This will allow us to access the Apache web page from our browser.</p>
</li>
<li><p>Click on the <strong>Launch instance</strong> button and wait for your instance to launch.</p>
</li>
<li><p>Repeat step 2-8 to launch another instance with the same configuration, but modify the user data script as follows:</p>
</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># Update packages</span>
sudo apt-get update -y
<span class="hljs-comment"># Install Apache</span>
sudo apt-get install -y apache2
<span class="hljs-comment"># Start Apache service</span>
sudo systemctl start apache2
<span class="hljs-comment"># Enable Apache service</span>
sudo systemctl <span class="hljs-built_in">enable</span> apache2
<span class="hljs-comment"># Modify index.html file</span>
sudo <span class="hljs-built_in">echo</span> <span class="hljs-string">"&lt;h1&gt;Welcome to AWS EC2&lt;/h1&gt;"</span> &gt; /var/www/html/index.html
sudo <span class="hljs-built_in">echo</span> <span class="hljs-string">"&lt;p&gt;TrainWithShubham Community is Super Awesome :)&lt;/p&gt;"</span> &gt;&gt; /var/www/html/index.html
</code></pre>
<p>This will change the message in the index.html file for the second instance.</p>
<p>You have successfully launched two EC2 instances with an Ubuntu AMI and used User Data to install the Apache Web Server.</p>
<h2 id="heading-how-to-create-an-application-load-balancer-alb-in-ec2-using-the-aws-management-console-and-add-the-ec2-instances-to-the-alb-as-target-groups">How to Create an Application Load Balancer (ALB) in EC2 using the AWS Management Console and Add the EC2 Instances to the ALB as Target Groups</h2>
<p>An Application Load Balancer (ALB) is a type of load balancer that operates at layer 7 of the OSI model and is ideal for applications that require advanced routing and microservices. ALB can route the traffic based on the content of the request, such as the URL path, the host header, the query parameters, etc. ALB can also support multiple protocols, such as HTTP, HTTPS, HTTP/2, WebSocket, and gRPC. ALB can also integrate with other AWS services, such as Amazon ECS, Amazon EKS, AWS Lambda, AWS WAF, etc.</p>
<p>To create an ALB in EC2 using the AWS Management Console and add the EC2 instances to the ALB as target groups, we’ll use the following steps:</p>
<ol>
<li><p>Go to the AWS console and navigate to the EC2 service.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699324810544/146b0228-4ec0-4e21-a920-d9d66eb3fb15.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on <strong>Load Balancers</strong> in the left navigation pane and then click the <strong>Create Load Balancer</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699325194866/101e30a5-641a-4864-a701-7e1bdfa12030.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>Create Application Load Balancer</strong> as the load balancer type.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699325266659/1ebd8b11-fc15-4ae9-ba6c-2ab6d451f542.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>Basic Configuration</strong> section, enter a name for your load balancer, such as <strong>ALB-Demo</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699325392374/54bf1712-e7b2-4db0-aad7-03b6a4e93548.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the Network mapping section, review VPC and subnet.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699325678161/43715ec4-c2b0-40d7-9d3b-e65225664b0a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>Security Groups</strong> section, create a new security group or select an existing one for your load balancer. Make sure to allow inbound traffic on port 80 for HTTP protocol from anywhere. This will allow us to access the load balancer from our browser.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699325831922/559f31c3-ff75-41c5-aec3-0e727fed0f9d.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>Listners and Routing</strong> section, create a new target group or select an existing one for your load balancer. A target group is a group of targets, such as EC2 instances, that receive the traffic from the load balancer. For example, you can create a new target group with the following settings:</p>
<ul>
<li><p>For <strong>Name</strong>, enter a name for your target group, such as <strong>ALB-Demo-TG</strong>.</p>
</li>
<li><p>For <strong>Target type</strong>, select <strong>instance</strong> to specify targets by instance ID.</p>
</li>
<li><p>For <strong>Protocol</strong>, select <strong>HTTP</strong>.</p>
</li>
<li><p>For <strong>Port</strong>, enter <strong>80</strong>.</p>
</li>
<li><p>For <strong>Health checks</strong>, modify the default settings as needed. For example, you can change the <strong>Path</strong> to <strong>/index.html</strong> to check the index.html file on each target.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326100961/a4f90b59-3dc7-4026-9027-0ff6c6dd9292.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
</li>
<li><p>Click on the <strong>Create load balancer</strong> button and wait for your load balancer to be created.</p>
</li>
</ol>
<p>You have successfully created an ALB in EC2 using the AWS Management Console and added the EC2 instances to the ALB as target groups.</p>
<h2 id="heading-how-to-verify-that-the-alb-is-working-properly-by-checking-the-health-status-of-the-target-instances-and-testing-the-load-balancing-capabilities">How to Verify that the ALB is Working Properly by Checking the Health Status of the Target Instances and Testing the Load Balancing Capabilities</h2>
<p>To verify that the ALB is working properly, we’ll use the following steps:</p>
<ol>
<li><p>Go to the AWS console and navigate to the EC2 service.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326214602/eccbfbf3-4618-4286-ae3f-909967496aac.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on <strong>Load Balancers</strong> in the left navigation pane and select your load balancer, such as <strong>ALB-Demo</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326284464/d7f20709-9b3d-42bd-b5a0-3c8d1be04195.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Copy the DNS name of your load balancer from the details panel. This is the address that you can use to access your load balancer from your browser.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326400834/8ebc95e0-a457-46c2-bad4-c8d24d3c71c2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Open a web browser and paste the DNS name into the address bar. You should see a webpage displaying information about your apache2 installation and your name or message, such as “Welcome to AWS EC2” and “My name is Ajit”.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326728478/7f5a6df5-fd39-44b2-9cd0-fde8c5226a19.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Refresh the web page several times and observe the changes. You should see different names or messages on each refresh, such as “Welcome to AWS EC2” and “TrainWithShubham Community is Super Awesome :)”. This means that the load balancer is distributing the traffic across your two EC2 instances and displaying the index.html file from each instance.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326771366/b9b23248-a295-4035-9670-d455db09389b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Go back to the AWS console and navigate to the EC2 service.</p>
</li>
<li><p>Click on <strong>Target Groups</strong> in the left navigation pane and select your target group, such as <strong>ALB-Demo-TG</strong>.</p>
</li>
<li><p>Click on the <strong>Targets</strong> tab and observe the health status of your target instances. You should see that both instances are healthy and in service. This means that the load balancer is able to communicate with your instances and perform health checks on them.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326844289/b3490b30-792d-4ea2-9fc7-7a681f2a120e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>To test the fault tolerance of your load balancer, you can stop or terminate one of your instances and see how the load balancer handles the situation. For example, you can select one of your instances, such as <strong>ALB-Demo-1</strong>, and click on <strong>Actions</strong> button and choose <strong>Instance State</strong> and then <strong>Stop</strong> or <strong>Terminate</strong> option from the drop-down menu.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326934012/232c2dfd-9cd8-44f4-b09f-b7a84db3417f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Wait for the instance to stop or terminate and then refresh the web page in your browser. You should see that the web page is still accessible and displaying the name or message from the other instance, such as “Welcome to AWS EC2” and “TrainWithShubham Community is Super Awesome :)”. This means that the load balancer is able to detect the unhealthy or unavailable instance and redirect the traffic to the healthy or available instance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1699326987013/7146f04c-7e40-437b-95eb-fc171cacb697.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>You have successfully verified that the ALB is working properly by checking the health status of the target instances and testing the load balancing capabilities.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this blog post, I have explained what load balancing is and how to use Elastic Load Balancing (ELB) in AWS EC2, a service that automatically distributes incoming traffic across multiple EC2 instances. I have also shown you how to create and use an Application Load Balancer (ALB) in EC2 using the AWS Management Console and add the EC2 instances to the ALB as target groups. I have also shown you how to verify that the ALB is working properly by checking the health status of the target instances and testing the load balancing capabilities.</p>
<p>I hope you found this blog post informative and engaging.</p>
<p>This is the end of the blog post for Day 41 of 90 Days of DevOps.</p>
<p>Thank you for reading and stay tuned for more posts in this series!</p>
]]></content:encoded></item><item><title><![CDATA[AWS EC2 Automation Made Easy with Launch Templates and AMIs]]></title><description><![CDATA[Are you a DevOps learner who wants to automate your AWS EC2 instances? If yes, then this blog post is for you.

In this post, I’ll explain how to use launch templates and AMI in AWS EC2, two important concepts that can help you automate your EC2 conf...]]></description><link>https://blog.ajitfawade.com/aws-ec2-automation-made-easy-with-launch-templates-and-amis</link><guid isPermaLink="true">https://blog.ajitfawade.com/aws-ec2-automation-made-easy-with-launch-templates-and-amis</guid><category><![CDATA[Devops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[automation]]></category><category><![CDATA[autoscaling]]></category><category><![CDATA[Jenkins]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Wed, 25 Oct 2023 08:40:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1698202873837/a45fa042-c7e9-4f0c-8463-94074ec220b7.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a DevOps learner who wants to automate your AWS EC2 instances? If yes, then this blog post is for you.</p>
<blockquote>
<p>In this post, I’ll explain how to use launch templates and AMI in AWS EC2, two important concepts that can help you automate your EC2 configuration and performance.</p>
</blockquote>
<p>By the end of this post, you’ll be able to:</p>
<ul>
<li><p>Understand what launch templates and EC2 instance types are and how they work in AWS EC2</p>
</li>
<li><p>Understand what AMI is and how to choose one for your instances</p>
</li>
<li><p>Create a launch template with Amazon Linux 2 AMI and t2.micro instance type with Jenkins and Docker setup</p>
</li>
<li><p>Create three instances using the launch template and an auto-scaling group</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-what-are-launch-templates-and-different-ec2-instance-types-available-in-aws-ec2">What are Launch Templates and different EC2 Instance Types available in AWS EC2?</h2>
<p>Launch templates are a feature of AWS EC2 that can help you automate your EC2 configuration and performance.</p>
<h3 id="heading-launch-templates">Launch Templates</h3>
<p>A launch template is a template that contains the configuration information that you need to start an instance. You can save launch parameters in launch templates so you don’t have to type them in every time you start a new instance. For example, a launch template can have the AMI ID, instance type, network settings, user data, security groups, tags, etc. that you usually use to launch instances.</p>
<p>You can tell the Amazon EC2 console or the AWS CLI to use a certain launch template when you start an instance. You can also use launch templates with other AWS services such as auto-scaling groups, spot fleets, or EC2 Fleet.</p>
<p>Launch templates can help you simplify and standardize your EC2 configuration and reduce errors. You can also create different versions of launch templates to keep track of changes or test different configurations.</p>
<h3 id="heading-ec2-instance-types">EC2 Instance Types</h3>
<p>EC2 instance types are different combinations of CPU, memory, storage, and networking capacity that you can choose for your instances. The different instance types are optimized for different use cases such as general purpose, compute-optimized, memory-optimized, storage-optimized, etc.</p>
<p>Each instance type comes with one or more instance sizes, so you can adjust your resources to meet the needs of the workload you want to run. For example, t2.micro is an instance type that belongs to the general purpose family and has 1 vCPU and 1 GiB of memory. You can choose a larger or smaller size within the same family or switch to a different family depending on your requirements.</p>
<p>You can also choose between on-demand instances, reserved instances, spot instances, or dedicated instances depending on your pricing and availability preferences.</p>
<p>EC2 instance types can help you optimize your EC2 performance and cost by choosing the right mix of resources for your applications.</p>
<h2 id="heading-what-is-ami-and-how-to-choose-one-for-your-instances">What is AMI and How to Choose One for Your Instances?</h2>
<p>An AMI or Amazon Machine Image is an image that AWS supports and keeps up to date. It contains the information needed to start an instance, such as the operating system, the applications, and the configuration settings. When you launch an instance, you must choose an AMI that suits your needs and preferences.</p>
<p>There are different types of AMIs that you can choose from, such as:</p>
<ul>
<li><p>AWS-provided AMIs: These are AMIs that AWS creates and maintains for common operating systems and platforms, such as Amazon Linux, Ubuntu, Windows, etc. You can use these AMIs for free or pay a small fee depending on the AMI type and usage.</p>
</li>
<li><p>AWS Marketplace AMIs: These are AMIs that third-party vendors create and sell on the AWS Marketplace. You can use these AMIs to access pre-configured software and services, such as databases, web servers, security tools, etc. You can pay for these AMIs per hour or per month depending on the vendor’s pricing model.</p>
</li>
<li><p>Community AMIs: These are AMIs that other AWS users create and share for free or for a fee. You can use these AMIs to access custom software and configurations that other users have created and tested. You can also create and share your own community AMIs if you want.</p>
</li>
<li><p>Your own AMIs: These are AMIs that you create from your own instances or snapshots. You can use these AMIs to launch instances with the same configuration and state as your original instance or snapshot. You can also copy or share your own AMIs with other AWS accounts or regions if you want.</p>
</li>
</ul>
<p>To choose an AMI for your instances, you need to consider several factors, such as:</p>
<ul>
<li><p>The operating system and platform that you want to run on your instances</p>
</li>
<li><p>The software and applications that you want to install or use on your instances</p>
</li>
<li><p>The security and compliance requirements that you need to meet for your instances</p>
</li>
<li><p>The performance and cost implications of using different types of AMIs</p>
</li>
<li><p>The availability and support of the AMIs in different AWS regions and accounts</p>
</li>
</ul>
<p>You can browse and search for different types of AMIs in the AWS console or the AWS CLI. You can also filter and compare the AMIs based on various criteria, such as name, description, owner, platform, etc.</p>
<p>You can also use launch templates to save your preferred AMI and other launch parameters in a template that you can reuse when launching instances.</p>
<p>To illustrate how launch templates and EC2 instance types work, let’s see an example of creating and using them in AWS EC2.</p>
<h2 id="heading-how-to-create-and-use-launch-templates-in-aws-ec2">How to Create and Use Launch Templates in AWS EC2</h2>
<p>In this section, I’ll show you how to create and use launch templates and EC2 instance types in AWS EC2. We’ll use a scenario where we want to run Jenkins on three EC2 instances with a Docker setup. Jenkins is a popular open-source tool for continuous integration and continuous delivery (CI/CD) that allows you to automate the building, testing, and deployment of your software projects. Docker is a software platform that allows you to build, run, and share applications using containers.</p>
<p>To do this, we’ll use the following steps:</p>
<ol>
<li><p>Create a launch template with Amazon Linux 2 AMI and t2.micro instance type with Jenkins and Docker setup</p>
</li>
<li><p>Create three instances using the launch template and an auto-scaling group</p>
</li>
</ol>
<p>Let’s see each step in detail.</p>
<h3 id="heading-step-1-create-a-launch-template-with-amazon-linux-2-ami-and-t2micro-instance-type-with-jenkins-and-docker-setup">Step 1: Create a Launch Template with Amazon Linux 2 AMI and t2.micro Instance Type with Jenkins and Docker Setup</h3>
<p>To create a launch template, we’ll use the same user data script that we used in the previous blog post to install Jenkins and Docker on the instance. Here is the script:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># Add Jenkins repository key and source</span>
sudo wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo

sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
<span class="hljs-comment"># Update packages</span>
sudo yum upgrade -y
<span class="hljs-comment"># Add required dependencies for the jenkins package</span>
sudo yum install fontconfig java-17-amazon-corretto -y
<span class="hljs-comment"># Install Jenkins</span>
sudo yum install jenkins -y
<span class="hljs-comment"># Reload the daemon</span>
sudo systemctl daemon-reload
<span class="hljs-comment"># Start Jenkins service</span>
sudo systemctl start jenkins
<span class="hljs-comment"># Enable Jenkins service</span>
sudo systemctl <span class="hljs-built_in">enable</span> jenkins
<span class="hljs-comment"># Install Docker</span>
sudo amazon-linux-extras install docker
<span class="hljs-comment"># Start Docker service</span>
sudo service docker start
<span class="hljs-comment"># Enable Docker service</span>
sudo systemctl <span class="hljs-built_in">enable</span> docker
<span class="hljs-comment"># Add ec2-user to docker group</span>
sudo usermod -a -G docker ec2-user
<span class="hljs-comment"># Restart the docker service</span>
sudo systemctl restart docker
</code></pre>
<p>To create a launch template using this script, we’ll use the following steps:</p>
<ol>
<li><p>Go to the AWS console and navigate to the EC2 service.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698210700067/4511f81d-e862-416e-af50-e231d1cc6113.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on <strong>Launch Templates</strong> in the left navigation pane.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698210757085/807ce7ba-1d38-4230-87e4-1c90699dd15a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Create Launch template</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698210806120/720414ef-8f32-41f0-8466-95f06ebcfc89.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter a name and an optional description for your launch template, such as <strong>Jenkins-Docker-LT</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698211030374/e5b84155-85cc-477b-830d-0c54138562e6.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose <strong>Amazon Linux 2 AMI (HVM), SSD Volume Type</strong> from the list of available AMIs.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698211038101/9a0188f9-2dab-4536-8cf0-5bc701336ebb.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose <strong>t2.micro</strong> from the list of available instance types.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698211127694/64ee0950-0b63-4ff7-81b8-ebc811866580.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>User data</strong> section, paste the user data script that we created earlier.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698219604110/e4b243f9-82e8-4b10-8835-2263335ac2cb.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>Network settings</strong> section, select <strong>Create New Security Group</strong> from the drop-down menu and enter a name and an optional description for your security group, such as <strong>Jenkins-Docker-SG</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698211306295/1dfc59f9-d03a-4206-9734-cabf8ea017a4.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Add security group rule</strong> button and add a rule to allow inbound traffic on port 8080 for HTTP protocol from anywhere. This will allow us to access the Jenkins web page from our browser.</p>
</li>
<li><p>Click on the <strong>Add rule</strong> button again and add a rule to allow inbound traffic on port 22 for SSH protocol from anywhere. This will allow us to SSH into our instances.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698211690830/666fd6b4-943d-45ea-80bd-192aa4610594.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>Key pair (login) information</strong> section, select <strong>Choose an existing key pair</strong> from the drop-down menu and choose a key pair that you have access to or create a new one if you don’t have one already.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698211761444/cb2147c5-2186-4800-a882-a7998e2eee65.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>Resource tags</strong> section, click on the <strong>Add tag</strong> button and add any tags that you want to assign to your launch template and your instances, such as Name, Project, etc.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698211923257/737fa25c-1754-4dfc-95b3-3a3a08758bf2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Create Launch Template</strong> button and wait for your launch template to be created.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698211981202/2ce0256d-f8d1-41af-9b54-4d5f9d6d4a4d.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>You have successfully created a launch template with Amazon Linux 2 AMI and t2.micro instance type with Jenkins and Docker setup.</p>
<h3 id="heading-step-2-create-three-instances-using-the-launch-template-and-an-auto-scaling-group">Step 2: Create Three Instances Using the Launch Template and an Auto-Scaling Group</h3>
<p>To create three instances using the launch template, we’ll use an auto-scaling group that will automatically launch and manage the instances for us. An auto-scaling group is a group of EC2 instances that can automatically scale up or down based on demand or predefined rules. We’ll use an auto-scaling group to ensure that we always have three instances running with the same configuration and settings.</p>
<p>To create an auto-scaling group using the launch template, we’ll use the following steps:</p>
<ol>
<li><p>Go to the AWS console and navigate to the EC2 service.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698221366172/fad67ebd-df28-4d61-8ee8-6cf2b727d89a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on <strong>Auto Scaling Groups</strong> in the left navigation pane.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698219840442/c838668e-d04f-4980-b1f1-e55bb06db046.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Create Auto Scaling group</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698220701250/eb224e31-3bb3-486e-9c3e-3fba10755f31.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter a name for your auto-scaling group, such as <strong>Jenkins-Docker-ASG</strong>.</p>
</li>
<li><p>Choose <strong>Launch Template</strong> as the source for your auto-scaling group and select the launch template that you created in the previous section, such as <strong>Jenkins-Docker-LT</strong>.</p>
</li>
<li><p>Click on the <strong>Next</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698220885464/8bef215e-8f45-4d2d-83c1-90cccb7f1a3d.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose <strong>VPC</strong> as the network for your auto-scaling group and select one or more subnets from different availability zones. This will ensure high availability and fault tolerance for your instances.</p>
</li>
<li><p>Click on the <strong>Next</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698220987078/c3502b32-18a6-4489-b627-f5fa9d7f8d0c.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter <strong>3</strong> in the <strong>Desired capacity</strong> field. This will tell the auto-scaling group to launch three instances using the launch template.</p>
</li>
<li><p>Enter <strong>3</strong> in the <strong>Minimum capacity</strong> field. This will tell the auto-scaling group to keep at least three instances running at all times.</p>
</li>
<li><p>Enter <strong>3</strong> in the <strong>Maximum capacity</strong> field. This will tell the auto-scaling group to not launch more than three instances at any time.</p>
</li>
<li><p>Choose <strong>None</strong> as the scaling policy for your auto-scaling group. This will tell the auto-scaling group to not scale up or down based on any metrics or alarms.</p>
</li>
<li><p>Click on the <strong>Next</strong> button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698221217849/c2259ad9-64ec-44fd-9014-79d80655410a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Add any notifications or tags that you want to assign to your auto-scaling group.</p>
</li>
<li><p>Click on the <strong>Next</strong> button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698221276466/0b8f6dda-1735-4cd5-9aa8-42a99f8fb785.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Review your auto-scaling group details and click on the <strong>Create Auto-Scaling group</strong> button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698221340300/c2bb2178-e34d-44f2-97f4-76d4fb440d12.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Wait for your auto-scaling group to be created.</p>
</li>
</ol>
<p>You have successfully created an auto-scaling group using the launch template.</p>
<h2 id="heading-how-to-access-jenkins-web-page-on-each-instance-and-how-to-test-docker-setup-on-each-instance">How to Access Jenkins Web Page on Each Instance and How to Test Docker Setup on Each Instance</h2>
<p>In this section, I’ll show you how to access the Jenkins web page on each instance and how to test the Docker setup on each instance. We’ll use a tool called curl that can send HTTP requests and display the response in the terminal. We’ll also use a command called docker run that can run a container from a Docker image.</p>
<p>To do this, we’ll use the following steps:</p>
<ol>
<li><p>Go to the AWS console and navigate to the EC2 service.</p>
</li>
<li><p>Click on <strong>Instances</strong> in the left navigation pane and select one of the instances that belong to your auto-scaling group, such as <strong>Jenkins-Docker-ASG-1</strong>.</p>
</li>
<li><p>Copy the public IP address of the instance from the details panel.</p>
</li>
<li><p>SSH into the instance using your key pair and the ec2-user username.</p>
</li>
<li><p>Run curl by running the following command:</p>
</li>
</ol>
<pre><code class="lang-bash">curl http://localhost:8080/
</code></pre>
<p>This command will send a GET request to the Jenkins web page on port 8080 and display the HTML response in the terminal.</p>
<ol>
<li><p>You should see some HTML code that contains the text “Unlock Jenkins”. This means that Jenkins is running on your instance and you need to unlock it using an initial password.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698222243129/31001fc9-3305-4f2f-912a-1c63f16295cb.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>To get the password, run the following command:</p>
</li>
</ol>
<pre><code class="lang-bash">sudo cat /var/lib/jenkins/secrets/initialAdminPassword
</code></pre>
<p>This command will display the password that you need to enter on the Jenkins web page.</p>
<ol>
<li><p>Copy the password and paste it into your browser’s address bar after the instance’s public IP address and port 8080. For example, http://&lt;instance-public-ip&gt;:8080/&lt;password&gt;. You should see the Jenkins welcome page that asks you to customize Jenkins or install suggested plugins.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698222219107/0d54c889-296e-452b-9142-c37f42123965.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Follow the instructions to complete the Jenkins setup.</p>
</li>
<li><p>To test the Docker setup on your instance, run the following command:</p>
</li>
</ol>
<pre><code class="lang-bash">docker run hello-world
</code></pre>
<p>This command will pull and run a Docker image called hello-world that prints a message in the terminal.</p>
<ol>
<li><p>You should see a message that says “Hello from Docker!” and some details about the Docker version and image ID. This means that Docker is running on your instance and you can run containers from Docker images.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698222201511/180a087b-b0f6-4e30-b1f0-9d3fb713e152.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Repeat steps 2-11 for each of your instances that belong to your auto-scaling group.</p>
</li>
</ol>
<p>You have successfully accessed the Jenkins web page on each instance and tested the Docker setup on each instance.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this blog post, I have explained how to use launch templates and auto-scaling groups in AWS EC2, two powerful tools that can help you automate your EC2 configuration and scaling. I have also shown you how to create and use them in practice by launching three EC2 instances with Jenkins and Docker setup using a launch template and an auto-scaling group.</p>
<p>I have also shown you how to access the Jenkins web page on each instance and how to test the Docker setup on each instance.</p>
<p>I hope you found this blog post informative and engaging. If you want to learn more about AWS and DevOps, here are some links to additional resources:</p>
<ul>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/">AWS Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://aws.amazon.com/training/">AWS Training and Certification</a></p>
</li>
<li><p><a target="_blank" href="https://www.jenkins.io/doc/">Jenkins Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://docs.docker.com/">Docker Documentation</a></p>
</li>
</ul>
<p>This is the end of the blog post for Day 40.</p>
<p>Thank you for reading and stay tuned for more posts in this series! 😊</p>
]]></content:encoded></item><item><title><![CDATA[AWS Basics for DevOps Learners: How to Use User Data and IAM Roles]]></title><description><![CDATA[Are you a DevOps learner who wants to get started with AWS? If yes, then this blog post is for you.
In this post, I’ll explain two important concepts that you need to know when working with AWS: user data and IAM roles.

User data is a way of passing...]]></description><link>https://blog.ajitfawade.com/aws-basics-for-devops-learners-how-to-use-user-data-and-iam-roles</link><guid isPermaLink="true">https://blog.ajitfawade.com/aws-basics-for-devops-learners-how-to-use-user-data-and-iam-roles</guid><category><![CDATA[Devops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[ec2]]></category><category><![CDATA[IAM]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Mon, 23 Oct 2023 03:32:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1698001166218/5314e968-f540-4adb-8418-58496cc56320.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a DevOps learner who wants to get started with AWS? If yes, then this blog post is for you.</p>
<p>In this post, I’ll explain two important concepts that you need to know when working with AWS: user data and IAM roles.</p>
<blockquote>
<p>User data is a way of passing custom configuration and commands to your EC2 instances, while IAM roles are a way of granting permissions and access to your AWS resources.</p>
</blockquote>
<p>By the end of this post, you’ll be able to:</p>
<ul>
<li><p>Understand what user data is and how to use it in AWS</p>
</li>
<li><p>Launch an EC2 instance with Jenkins pre-installed using user data</p>
</li>
<li><p>Understand what IAM roles are and how to use them in AWS</p>
</li>
<li><p>Create and assign IAM roles for different types of users</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-what-is-user-data-in-aws">What is User Data in AWS?</h2>
<p>User data is a feature of Amazon EC2 that allows you to pass custom configuration and commands to your EC2 instances when you launch them. You can use user data to perform common automated tasks such as installing software, configuring settings, running scripts, etc. User data can be very useful for DevOps learners who want to save time and manual effort every time they launch an instance and want to install any application on it like apache, docker, Jenkins, etc.</p>
<p>You can pass two types of user data to Amazon EC2: shell scripts and cloud-init directives. Shell scripts are executable commands that run on the instance’s operating system, while cloud-init directives are instructions that are processed by a tool called cloud-init that runs on the instance during boot. Cloud-init can perform more advanced tasks such as setting up users, mounting volumes, writing files, etc.</p>
<p>You can also pass user data in different formats: as plain text, as a file, or as base64-encoded text. Plain text is the simplest format that you can enter directly into the launch instance wizard or the command line tools. File format is useful when you have a script or a file that you want to upload from your local machine. Base64-encoded text is required when you use the API calls to launch instances.</p>
<p>To illustrate how user data works, let’s see an example of launching an EC2 instance with Jenkins pre-installed using user data.</p>
<h2 id="heading-how-to-launch-an-ec2-instance-with-jenkins-pre-installed-using-user-data">How to Launch an EC2 Instance with Jenkins Pre-Installed Using User Data</h2>
<p>Jenkins is a popular open-source tool for continuous integration and continuous delivery (CI/CD) that allows you to automate the building, testing, and deployment of your software projects. Jenkins can be installed on various platforms, including AWS EC2 instances. In this section, I’ll show you how to launch an EC2 instance with Jenkins pre-installed using user data.</p>
<p>To do this, we’ll use a shell script that will install Jenkins and its dependencies on the instance using apt-get commands. We’ll also configure Jenkins to run on port 8080 and set up a firewall rule to allow inbound traffic on that port. Here is the shell script that we’ll use:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Update the package manager</span>
sudo apt update

<span class="hljs-comment"># Install Java</span>
sudo apt install fontconfig openjdk-17-jre -y

<span class="hljs-comment"># Add Jenkins repository key and source</span>
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
  https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key

<span class="hljs-built_in">echo</span> deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list &gt; /dev/null

<span class="hljs-comment"># Update packages again</span>
sudo apt update

<span class="hljs-comment"># Install Jenkins</span>
sudo apt install jenkins -y

<span class="hljs-comment"># Start the Jenkins service</span>
sudo systemctl start jenkins

<span class="hljs-comment"># Enable the Jenkins service to start at boot</span>
sudo systemctl <span class="hljs-built_in">enable</span> jenkins
</code></pre>
<p>To pass this script as user data, we’ll use the file format option in the launch instance wizard. Here are the steps:</p>
<ol>
<li><p>Open the AWS Management Console and go to the EC2 service.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698026425119/eaa79665-7e56-47ea-9e42-b784f22cba8f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Launch Instance</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698026475012/2a4f8de4-be83-4790-b4e4-0f41a7626f51.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select the <strong>Ubuntu Server 22.04 LTS (HVM)</strong> AMI.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698026596233/b03a6426-5cec-45e0-b042-ffa371c32cc5.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose an instance type.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698026674428/81be4544-2f17-4148-9f2d-d4bc45df2b79.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Configure the instance details.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698026755341/57c347ca-4746-458b-b575-e14fd7b19cc4.png" alt class="image--center mx-auto" /></p>
<p> <strong>Configure security group</strong></p>
<ol>
<li><p>Click on the <strong>Security Groups</strong> tab.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698027348829/6b6fa9cb-8300-4b87-82e1-337f1ea28c04.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Edit</strong> button for the security group that you want to configure.</p>
</li>
<li><p>Click on the <strong>Add Security Rule</strong> button.</p>
</li>
<li><p>Select the <strong>Type</strong> as <strong>Custom TCP Rule</strong>.</p>
</li>
<li><p>Select the <strong>Protocol</strong> as <strong>TCP</strong>.</p>
</li>
<li><p>Enter the <strong>Port Range</strong> as <strong>8080</strong>.</p>
</li>
<li><p>Select the <strong>Source</strong> as <strong>Anywhere</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698027582936/3b08c2e6-821f-440d-8207-b1dfe5557ca0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Save</strong> button.</p>
</li>
</ol>
</li>
</ol>
<p>    <strong>Configure user data</strong></p>
<ol>
<li><p>Under the <strong>Advanced Details</strong> section, expand the <strong>User data</strong> field.</p>
</li>
<li><p>In the User data section, select File from the drop-down menu and click on the Choose File button.</p>
</li>
<li><p>Browse to the location of the shell script that we created earlier and select it.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698027783612/7b576807-794c-40b8-baba-5313c8cbf149.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Launch Instance</strong> button.</p>
</li>
</ol>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698029464323/6592a451-3ada-49e5-91b7-fc77e5c8caf4.png" alt class="image--center mx-auto" /></p>
<p>Once your instance is up and running, you can access Jenkins by entering the instance’s public IP address followed by port 8080 in your browser. For example, http://&lt;instance-public-ip&gt;:8080. You should see the Jenkins welcome page that asks you to unlock Jenkins using an initial password.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698029848801/bfd2a373-2686-427f-9f2a-f4dac87423c3.png" alt class="image--center mx-auto" /></p>
<p>To get the password, you can SSH into your instance and run the following command:</p>
<pre><code class="lang-bash">sudo cat /var/lib/jenkins/secrets/initialAdminPassword
</code></pre>
<p>Copy the password and paste it into the Jenkins web page. Then, follow the instructions to complete the Jenkins setup.</p>
<p>To verify that user data was executed successfully, you can also check the user data logs in your instance by running the following command:</p>
<pre><code class="lang-bash">sudo cat /var/<span class="hljs-built_in">log</span>/cloud-init-output.log
</code></pre>
<p>You should see the output of the user data script that we passed, along with any errors or warnings if any.</p>
<p>Congratulations! You have successfully launched an EC2 instance with Jenkins pre-installed using user data.</p>
<h2 id="heading-what-are-iam-roles-in-aws">What are IAM Roles in AWS?</h2>
<p>IAM roles are another type of IAM identity that you can create in your AWS account that has specific permissions. IAM roles are similar to IAM users, in that they are AWS identities with permission policies that determine what they can and cannot do in AWS. However, unlike IAM users, IAM roles do not have permanent credentials such as passwords or access keys associated with them. Instead, IAM roles provide temporary security credentials to whoever has the ability to assume that role.</p>
<p>You can use IAM roles to delegate access to users, applications, or services that don’t normally have access to your AWS resources. For example, you might want to grant users in your AWS account access to resources they don’t usually have, or grant users in one AWS account access to resources in another account. Or you might want to allow a mobile app to use AWS resources, but not want to embed AWS keys within the app (where they can be difficult to update and where users can potentially extract them). Sometimes you want to give AWS access to users who already have identities defined outside of AWS, such as in your corporate directory. Or, you might want to grant access to your account to third parties so that they can perform an audit on your resources. For these scenarios, you can delegate access to AWS resources using an IAM role.</p>
<p>To create an IAM role, you need to specify two things: the trusted entity and the permission policy. The trusted entity is the user, application, or service that is allowed to assume the role. The permission policy is the set of permissions that the role grants when it is assumed. You can also optionally specify a session policy that further restricts the permissions for a specific role session.</p>
<p>To assume an IAM role, you need to have permission to do so. You can use the AWS Management Console, the AWS CLI, the AWS SDKs, or the AWS APIs to assume a role. When you assume a role, you get a set of temporary security credentials that include an access key ID, a secret access key, and a security token. You can use these credentials to make API requests or access AWS resources that the role allows. The credentials are valid for a limited time period and you can specify when you create or assume the role.</p>
<p>To illustrate how IAM roles work, let’s see an example of creating and assigning IAM roles for different types of users.</p>
<h2 id="heading-how-to-create-and-assign-iam-roles-for-different-types-of-users">How to Create and Assign IAM Roles for Different Types of Users</h2>
<p>In this section, I’ll show you how to create and assign IAM roles for three types of users: DevOps-User, Test-User, and Admin. These users represent different roles in a DevOps team that need different levels of access to AWS resources.</p>
<ul>
<li><p>DevOps-User: This user needs read-only access to EC2 instances and S3 buckets.</p>
</li>
<li><p>Test-User: This user needs read-write access to EC2 instances and S3 buckets.</p>
</li>
<li><p>Admin: This user needs full access to all AWS services and resources.</p>
</li>
</ul>
<p>To create and assign these roles, we’ll use the following steps:</p>
<ol>
<li><p>Open the AWS Management Console and go to the IAM service.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698030598217/a6f01293-a7b3-48f6-8af0-b20319c5d9b5.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Roles</strong> tab.</p>
</li>
<li><p>Click on the <strong>Create role</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698030609122/1f9f5de1-f2ce-4b64-a66b-4cdd9ad10b3c.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select the <strong>Select role type</strong> option and choose <strong>AWS Service</strong>.</p>
</li>
<li><p>Select the <strong>EC2</strong> service and click on the <strong>Next: Permissions</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698030711850/7ee8fb43-441a-4689-93ed-8fcba65760ed.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select the <strong>Attach existing policies directly</strong> option and choose the following policies:</p>
</li>
</ol>
<ul>
<li><p>For the DevOps-User role, choose the <strong>AmazonEC2FullAccess</strong> policy.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698030769407/28715de2-5fb6-443e-afae-4dc941200de1.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>For the Test-User role, choose the <strong>AmazonEC2ReadOnlyAccess</strong> policy.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698030920389/f8a8a57c-39f7-4df1-afd8-481afc1e6c5b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>For the Admin role, choose the <strong>AdministratorAccess</strong> policy.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698030978581/d4b057a6-fc2f-43bc-b6d3-343c383d0a28.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<ol>
<li><p>Click on the <strong>Next: Tags</strong> button.</p>
</li>
<li><p>Click on the <strong>Next: Review</strong> button.</p>
</li>
<li><p>Review the information for your new role and click on the <strong>Create role</strong> button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698031040527/b06c25f7-e01d-4815-a8df-b55364062172.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>Congratulations! You have successfully created IAM roles for different types of users.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this blog post, I have explained two important concepts that you need to know when working with AWS: user data and IAM roles. User data is a way of passing custom configuration and commands to your EC2 instances when you launch them, while IAM roles are a way of granting permissions and access to your AWS resources. I have also shown you how to use these concepts in practice by launching an EC2 instance with Jenkins pre-installed using user data and creating and assigning IAM roles for different types of users.</p>
<p>I hope you found this blog post informative and engaging.</p>
<p>This is the end of the blog post for Day 39 of 90 Days of DevOps.</p>
<p>Thank you for reading and stay tuned for more posts in this series!</p>
]]></content:encoded></item><item><title><![CDATA[How to Master AWS Basics for DevOps Learners - A Step-by-Step Guide: Day 38 of 90 Days of DevOps]]></title><description><![CDATA[Introduction
AWS stands for Amazon Web Services, which is a cloud computing platform that provides a wide range of services and features for various use cases. AWS allows you to create, manage, and scale your applications and infrastructure on demand...]]></description><link>https://blog.ajitfawade.com/how-to-master-aws-basics-for-devops-learners-a-step-by-step-guide</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-master-aws-basics-for-devops-learners-a-step-by-step-guide</guid><category><![CDATA[Devops]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[ec2]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Sat, 21 Oct 2023 18:06:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697770819655/d7d88f3e-f59c-4d3d-bf58-1cdc8c0f320a.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p><strong>AWS</strong> stands for Amazon Web Services, which is a cloud computing platform that provides a wide range of services and features for various use cases. AWS allows you to create, manage, and scale your applications and infrastructure on demand, without having to worry about the underlying hardware or software.</p>
<p>Some of the benefits of using AWS are:</p>
<ul>
<li><p>Cost-effectiveness: You only pay for what you use, and you can choose from different pricing models and options.</p>
</li>
<li><p>Scalability: You can easily scale up or down your resources according to your needs, and you can leverage the global network of AWS regions and availability zones.</p>
</li>
<li><p>Reliability: You can rely on the high availability and durability of AWS services, and you can use various tools and best practices to ensure your application’s performance and security.</p>
</li>
<li><p>Innovation: You can access the latest technologies and features that AWS offers, and you can experiment with different solutions and architectures.</p>
</li>
</ul>
<p><strong>IAM</strong> stands for Identity and Access Management, which is a service that allows you to manage users, groups, roles, policies, and permissions in AWS. IAM enables you to control who can access your AWS resources and what actions they can perform.</p>
<p>Some of the benefits of using IAM are:</p>
<ul>
<li><p>Security: You can enforce strong authentication methods, such as passwords, multi-factor authentication, or access keys, for your users. You can also use encryption and auditing features to protect your data and monitor your activities.</p>
</li>
<li><p>Granularity: You can assign fine-grained permissions to your users, groups, roles, or resources, based on the principle of least privilege. You can also use conditions and tags to further restrict or allow access.</p>
</li>
<li><p>Flexibility: You can create custom policies that suit your specific needs, or use predefined policies that AWS provides. You can also use roles to delegate permissions to other users or services, without sharing your credentials.</p>
</li>
</ul>
<p>In this blog post, we will learn how to use AWS and IAM for DevOps purposes. We will cover the following tasks:</p>
<ul>
<li><p>Creating an IAM user and granting EC2 access.</p>
</li>
<li><p>Launching an EC2 instance and installing Jenkins and Docker.</p>
</li>
<li><p>Preparing a DevOps team of Avengers.</p>
</li>
</ul>
<blockquote>
<p><mark>By the end of this blog post, you will have a better understanding of AWS and IAM basics, and you will be able to perform some common DevOps tasks on AWS.</mark></p>
</blockquote>
<p>Let’s get started!</p>
<h2 id="heading-creating-an-iam-user-and-granting-ec2-access">Creating an IAM User and Granting EC2 Access</h2>
<p>The first task is to create an IAM user and grant EC2 access. An IAM user is an entity that represents a person or an application that interacts with AWS. EC2 stands for Elastic Compute Cloud, which is a service that allows you to launch virtual servers on AWS.</p>
<p>To create an IAM user and grant EC2 access, follow these steps:</p>
<h3 id="heading-step-1-sign-in-to-the-aws-management-console">Step 1: Sign in to the AWS Management Console</h3>
<p>The AWS Management Console is a web-based interface that allows you to access and manage your AWS resources.</p>
<p>To sign in to the AWS Management Console, go to <a target="_blank" href="https://aws.amazon.com/console/">https://aws.amazon.com/console/</a> and enter your email address and password. If you don’t have an account yet, you can create one for free by clicking on Create a new AWS account.</p>
<h3 id="heading-step-2-go-to-the-iam-dashboard">Step 2: Go to the IAM Dashboard</h3>
<p>The IAM Dashboard is where you can view and manage your IAM users, groups, roles, policies, and permissions.</p>
<p>To go to the IAM Dashboard, click on Services at the top left corner of the console, and then select IAM under Security, Identity, &amp; Compliance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697771124167/ba544a94-56bc-45f0-94be-b9d82cbbc1e6.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-3-create-a-new-user">Step 3: Create a New User</h3>
<p>To create a new user, click on Users in the left navigation pane, and then click on Create User.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697771265785/359e79ab-7c69-417b-9a48-361d4322bdc5.png" alt class="image--center mx-auto" /></p>
<p>Enter a user name of your choice. For example, you can use your own name or a nickname. In this blog post, we will use <code>devops-learner</code> as the user name.</p>
<p>Select the access type for the user. You can choose between Programmatic access and AWS Management Console access. Programmatic access means that the user can access AWS using an access key ID and a secret access key, which are credentials that can be used by applications or scripts. AWS Management Console access means that the user can access AWS using a username and a password, which are credentials that can be used by humans.</p>
<p>In this blog post, we will select both Programmatic access and AWS Management Console access, as we will need both types of access for our tasks.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697891856870/489c08e0-4c3b-4b61-ba6b-bc3edd3416bc.png" alt class="image--center mx-auto" /></p>
<p>Click on Next: Permissions.</p>
<h3 id="heading-step-4-attach-the-amazonec2fullaccess-policy">Step 4: Attach the AmazonEC2FullAccess Policy</h3>
<p>To attach a policy to the user, you can either add the user to an existing group, copy permissions from an existing user or attach existing policies directly. A policy is a document that defines the permissions that are allowed or denied for a user, group, role, or resource.</p>
<p>In this blog post, we will attach an existing policy directly to the user. An existing policy is a policy that AWS provides for common use cases. You can also create your own custom policies if you need more specific permissions.</p>
<p>To attach an existing policy directly to the user, click on Attach existing policies directly, and then search for AmazonEC2FullAccess in the search box. Select the checkbox next to AmazonEC2FullAccess, which is a policy that grants full access to EC2.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697892013629/8558080c-7d55-4e19-934f-f12baa9a689d.png" alt class="image--center mx-auto" /></p>
<p>Click on Next: Tags.</p>
<h3 id="heading-step-5-download-the-user-credentials">Step 5: Download the User Credentials</h3>
<p>To download the user credentials, you can either add tags to the user or skip this step. Tags are key-value pairs that you can use to organize and identify your resources.</p>
<p>In this blog post, we will skip this step and click on Next: Review.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697892079090/61b062ba-5b0f-402e-9c56-871e9a08c828.png" alt class="image--center mx-auto" /></p>
<p>Review the user details and click on Create user.</p>
<p>You will see a success message and a table with the user credentials. You will need these credentials later for accessing AWS programmatically or through the console.</p>
<p>Click on Download .csv to download a file with the user credentials. Save this file in a secure location, as you will not be able to access these credentials again from the console.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697892127503/573a07e2-51e4-44c9-a0ee-eeb4e3a11ea7.png" alt class="image--center mx-auto" /></p>
<p>Click on Close to return to the Users page.</p>
<p>You have successfully created an IAM user and granted EC2 access.</p>
<h2 id="heading-launching-an-ec2-instance-and-installing-jenkins-and-docker">Launching an EC2 Instance and Installing Jenkins and Docker</h2>
<p>The second task is to launch an EC2 instance and install Jenkins and Docker on it. An EC2 instance is a virtual server that runs on AWS. Jenkins is a tool that automates the software development process, such as building, testing, and deploying. Docker is a tool that allows you to create, run, and share containers that contain your application and its dependencies.</p>
<p>To launch an EC2 instance and install Jenkins and Docker on it, follow these steps:</p>
<h3 id="heading-step-1-go-to-the-ec2-dashboard">Step 1: Go to the EC2 Dashboard</h3>
<p>The EC2 Dashboard is where you can view and manage your EC2 instances and other related resources.</p>
<p>To go to the EC2 Dashboard, click on Services at the top left corner of the console, and then select EC2 under Compute.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697894894674/cb8dc8f9-44ad-458a-8722-e593d2268ee4.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-2-launch-a-new-instance">Step 2: Launch a New Instance</h3>
<p>To launch a new instance, click on Launch Instance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697894950038/4f2bef86-ddee-4710-877e-01fb57ef7e88.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-3-choose-an-ami">Step 3: Choose an AMI</h3>
<p>An AMI stands for Amazon Machine Image, which is a template that contains the operating system and software configuration for your instance.</p>
<p>To choose an AMI, select Ubuntu Server 22.04 LTS (HVM), SSD Volume Type as the AMI. This is a free tier eligible AMI that comes with Ubuntu Linux and some pre-installed packages.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697895108095/24719e2f-af58-421b-a712-e9485a371956.png" alt class="image--center mx-auto" /></p>
<p>Click on Select.</p>
<h3 id="heading-step-4-choose-an-instance-type">Step 4: Choose an Instance Type</h3>
<p>An instance type determines the hardware specifications of your instance, such as CPU, memory, storage, and network performance.</p>
<p>To choose an instance type, select t2.micro as the instance type. This is a free tier eligible instance type that provides 1 vCPU and 1 GB of memory.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697907631966/eef19a6c-b7c1-40f0-9951-c4f201aee240.png" alt class="image--center mx-auto" /></p>
<p>Click on Next: Configure Instance Details.</p>
<h3 id="heading-step-5-configure-instance-details">Step 5: Configure Instance Details</h3>
<p>To configure instance details, you can modify various settings for your instance, such as the number of instances, the network, the subnet, the IAM role, etc.</p>
<p>In this blog post, we will leave everything as default except for two settings:</p>
<ul>
<li><p>User data: This is a script that runs when your instance launches. You can use user data to perform common tasks such as installing software or configuring settings.</p>
</li>
<li><p>IAM role: This is a role that grants permissions to your instance to access other AWS services or resources.</p>
</li>
</ul>
<p>To configure user data, click on Advanced Details and enter the following script in the text box:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
sudo apt update
sudo apt install openjdk-11-jdk -y
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c <span class="hljs-string">'echo deb https://pkg.jenkins.io/debian-stable binary/ &gt; /etc/apt/sources.list.d/jenkins.list'</span>
sudo apt update
sudo apt install jenkins -y
sudo systemctl start jenkins
sudo apt install docker.io -y
sudo usermod -aG docker <span class="hljs-variable">$USER</span> &amp;&amp; newgrp docker
</code></pre>
<p>This script will do the following:</p>
<ul>
<li><p>Update the package list</p>
</li>
<li><p>Install Java 11 JDK</p>
</li>
<li><p>Add the Jenkins repository key and source list</p>
</li>
<li><p>Install Jenkins</p>
</li>
<li><p>Start Jenkins service</p>
</li>
<li><p>Install Docker</p>
</li>
<li><p>Add the current user to the docker group</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697907896653/d9a93c3b-0e8a-4907-85b6-5a9e6b65cf25.png" alt class="image--center mx-auto" /></p>
<p>To configure the IAM role, click on Create new IAM role and enter a role name of your choice. For example, you can use ec2-jenkins-docker-role as the role name.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697908132966/7e38a36a-90ae-441c-bb2c-2911fa86a040.png" alt class="image--center mx-auto" /></p>
<p>Click on Next: Permissions.</p>
<p>Select AmazonEC2ContainerRegistryFullAccess as the policy to attach to the role. This policy grants full access to Amazon Elastic Container Registry (ECR), which is a service that allows you to store and manage your Docker images.</p>
<p>Click on Next: Tags.</p>
<p>Click on Create role.</p>
<p>You will see a success message and a table with the role details. Click on Close.</p>
<p>You will be redirected back to the Configure Instance Details page. Select the role that you just created from the IAM role dropdown menu.</p>
<p>Click on Next: Add Storage.</p>
<h3 id="heading-step-6-add-storage">Step 6: Add Storage</h3>
<p>To add storage, you can modify the size and type of the storage volume for your instance. A storage volume is a block device that provides persistent storage for your instance.</p>
<p>In this blog post, we will leave everything as default and click on Next: Add Tags.</p>
<h3 id="heading-step-7-add-tags">Step 7: Add Tags</h3>
<p>To add tags, you can add key-value pairs that help you organize and identify your resources.</p>
<p>In this blog post, we will add one tag with Key as Name and Value as ec2-jenkins-docker-instance. This will help us recognize our instance later.</p>
<p>Click on Next: Configure Security Group.</p>
<h3 id="heading-step-8-configure-security-group">Step 8: Configure Security Group</h3>
<p>To configure the security group, you can define the inbound and outbound rules that control the traffic to and from your instance. A security group acts as a virtual firewall for your instance.</p>
<p>In this blog post, we will create a new security group with two rules:</p>
<ul>
<li><p>Type: SSH, Protocol: TCP, Port Range: 22, Source: Anywhere (0.0.0.0/0), Description: SSH access</p>
</li>
<li><p>Type: Custom TCP Rule, Protocol: TCP, Port Range: 8080, Source: Anywhere (0.0.0.0/0), Description: Jenkins access</p>
</li>
</ul>
<p>These rules will allow us to access our instance via SSH and Jenkins via port 8080.</p>
<p>Enter a security group name and description of your choice. For example, you can use ec2-jenkins-docker-sg as the name and Jenkins and Docker security group as the description.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697909171473/8eb2a4b1-d94f-4cf9-809f-e2b49f334154.png" alt class="image--center mx-auto" /></p>
<p>Click on Review and Launch.</p>
<h3 id="heading-step-9-review-and-launch">Step 9: Review and Launch</h3>
<p>To review and launch, you can review your instance details and launch it.</p>
<p>Click on Launch.</p>
<p>Select an existing key pair or create a new one. A key pair consists of a public key and a private key that is used to encrypt and decrypt the login information for your instance. You will need the private key to connect to your instance via SSH.</p>
<p>Check the acknowledgment box and click on Launch Instances.</p>
<p>Wait for your instance to launch and note down its public IP address.</p>
<h3 id="heading-step-10-connect-to-the-instance">Step 10: Connect to the Instance</h3>
<p>To connect to the instance, you can use SSH to establish a secure connection with your instance.</p>
<p>Open a terminal window and enter the following command:</p>
<pre><code class="lang-bash">ssh -i &lt;keypair.pem&gt; ubuntu@&lt;public-ip-address&gt;
</code></pre>
<p>Replace &lt;keypair.pem&gt; with the path to your private key file and &lt;public-ip-address&gt; with the public IP address of your instance.</p>
<p>For example, if your key pair file is called ec2-jenkins-docker-key.pem and your public IP address is 54.173.12.34, use:</p>
<pre><code class="lang-bash">ssh -i docker-advanced.pem ubuntu@54.173.12.34
</code></pre>
<p>You will see a message like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697909572375/0e778b52-8e38-454c-8c2f-5ba08ac07e7d.png" alt class="image--center mx-auto" /></p>
<p>Type yes and press Enter.</p>
<p>You will see a message like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697909652402/d551598c-5e02-4d3d-94a8-eab2100007c2.png" alt class="image--center mx-auto" /></p>
<p>You have successfully connected to your instance.</p>
<h3 id="heading-step-11-create-a-shell-script">Step 11: Create a Shell Script</h3>
<p>To create a shell script, you can use a text editor to write a series of commands that can be executed as a single file.</p>
<p>In this blog post, we will create a shell script that will install Jenkins and Docker on our instance.</p>
<p>On your terminal window, enter the following command:</p>
<pre><code class="lang-bash">nano install.sh
</code></pre>
<p>This will open a text editor called <code>nano</code>.</p>
<p>Enter the following code in the text editor:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
sudo apt update
sudo apt install openjdk-11-jdk -y
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c <span class="hljs-string">'echo deb https://pkg.jenkins.io/debian-stable binary/ &gt; /etc/apt/sources.list.d/jenkins.list'</span>
sudo apt update
sudo apt install jenkins -y
sudo systemctl start jenkins
</code></pre>
<h3 id="heading-step-12-run-the-shell-script">Step 12: Run the Shell Script</h3>
<p>To run the shell script, you need to make it executable and then execute it.</p>
<p>On your terminal window, enter the following commands:</p>
<pre><code class="lang-bash">chmod +x install.sh
./install.sh
</code></pre>
<p>These commands will make the shell script executable and then run it.</p>
<p>You will see some output on the terminal window as the script installs Jenkins and Docker on your instance.</p>
<p>Wait for the script to finish and then check the status of Jenkins and Docker using the following commands:</p>
<pre><code class="lang-bash">sudo systemctl status jenkins
sudo docker version
</code></pre>
<p>These commands will show you the status of the Jenkins service and the version of Docker installed.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697910434776/2c2023ba-81e7-4e4d-bf05-cdee79222b11.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697910465364/7aabebfd-e635-4fde-a52a-7092e2ec6fc1.png" alt class="image--center mx-auto" /></p>
<p>This means that Jenkins and Docker are installed and running on your instance.</p>
<p>You have successfully launched an EC2 instance and installed Jenkins and Docker on it.</p>
<h2 id="heading-preparing-a-devops-team-of-avengers">Preparing a DevOps Team of Avengers</h2>
<p>The third task is to prepare a DevOps team of Avengers. We will create three IAM users for three Avengers and assign them to a DevOps group with the IAMFullAccess policy.</p>
<p>To prepare a DevOps team of Avengers, follow these steps:</p>
<h3 id="heading-step-1-create-three-new-users">Step 1: Create Three New Users</h3>
<p>To create three new users, go back to the IAM Dashboard and click on Users in the left navigation pane. Then click on Add user.</p>
<p>Enter the user names for the three Avengers. For example, you can use <strong>ironman</strong>, <strong>captainamerica</strong>, and <strong>blackwidow</strong> as the user names.</p>
<p>Select the access type for the users. In this blog post, we will select Programmatic access only, as we will assume that these users will access AWS using applications or scripts.</p>
<p>Click on Next: Permissions.</p>
<h3 id="heading-step-2-create-a-devops-group">Step 2: Create a DevOps Group</h3>
<p>To create a DevOps group, click on Create group.</p>
<p>Enter a group name of your choice. For example, you can use <code>avengers-devops</code> as the group name.</p>
<p>Search for IAMFullAccess in the search box and select the checkbox next to it. This is a policy that grants full access to IAM.</p>
<p>Click on Create group.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697910664765/2f42962c-292e-4495-9721-95b2e1263c4a.png" alt class="image--center mx-auto" /></p>
<p>You will see a success message and a table with the group details. Click on Next: Tags.</p>
<h3 id="heading-step-3-attach-the-iamfullaccess-policy">Step 3: Attach the IAMFullAccess Policy</h3>
<p>To attach the IAMFullAccess policy to the group, you can either add tags to the group or skip this step. Tags are key-value pairs that you can use to organize and identify your resources.</p>
<p>In this blog post, we will skip this step and click on Next: Review.</p>
<p>Review the user details and click on Create user.</p>
<p>You will see a success message and a table with the user credentials. You can download or email these credentials to the users, or ask them to generate their own credentials later.</p>
<p>Click on Close to return to the Users page.</p>
<h3 id="heading-step-4-add-the-users-to-the-group">Step 4: Add the Users to the Group</h3>
<p>To add the users to the group, select the checkbox next to each user name and click on Add user to groups.</p>
<p>Select the checkbox next to <code>avengers-devops</code> and click on Add to groups.</p>
<p>You will see a success message and a table with the user details. Click on Close.</p>
<p>You have successfully prepared a DevOps team of Avengers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697910872902/a6243299-1b28-4833-910b-ab66726bfd37.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697910891057/d1f0d1d6-9e47-4dd7-93cc-fc0620e853d3.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697910899196/3b7f0cbb-1e3b-423d-b256-561d8668a44f.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, we have learned how to get started with AWS basics for DevOps learners. We have covered the following tasks:</p>
<ul>
<li><p>Creating an IAM user and granting EC2 access.</p>
</li>
<li><p>Launching an EC2 instance and installing Jenkins and Docker.</p>
</li>
<li><p>Preparing a DevOps team of Avengers.</p>
</li>
</ul>
<p>By completing these tasks, we have gained a better understanding of AWS and IAM basics, and we have performed some common DevOps tasks on AWS.</p>
<p>We hope you enjoyed this blog post and learned something new from it. If you want to learn more about AWS and DevOps, you can check out these resources:</p>
<ul>
<li><p><a target="_blank" href="https://aws.amazon.com/training/learn-about/devops/">AWS Training and Certification</a>: This is where you can find various courses, certifications, and learning paths for AWS.</p>
</li>
<li><p><a target="_blank" href="https://www.coursera.org/learn/getting-started-with-aws-devops">AWS Ramp-Up Guide: Developer</a>: This is where you can find a curated list of resources for developers who want to learn more about AWS.</p>
</li>
<li><p><a target="_blank" href="https://www.w3schools.com/training/aws/getting-started-with-devops-on-aws.php">AWS DevOps Blog</a>: This is where you can find articles, tutorials, and best practices for DevOps on AWS.</p>
</li>
<li><p><a target="_blank" href="https://skillbuilder.aws/roles">AWS Whitepapers</a>: This is where you can find technical guides and overviews for various AWS topics and services.</p>
</li>
</ul>
<p>Thank you for reading this blog post. Please feel free to share your feedback or questions in the comments section below.</p>
<p>Happy learning! 😊</p>
]]></content:encoded></item><item><title><![CDATA[How to Deploy a Reddit Clone App on Kubernetes with Ingress - A Complete Guide for DevOps Learners]]></title><description><![CDATA[Introduction
Reddit is one of the most popular social media platforms that allows users to create and join communities, post and vote on content, and comment and interact with other users. Reddit is also known for its open-source culture and its use ...]]></description><link>https://blog.ajitfawade.com/how-to-deploy-a-reddit-clone-app-on-kubernetes-with-ingress</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-deploy-a-reddit-clone-app-on-kubernetes-with-ingress</guid><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[ingress]]></category><category><![CDATA[Learning Journey]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Wed, 18 Oct 2023 19:23:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697650717128/49acfa30-378a-48f8-a032-4afbb3715d5e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Reddit is one of the most popular social media platforms that allows users to create and join communities, post and vote on content, and comment and interact with other users. Reddit is also known for its open-source culture and its use of cutting-edge technologies.</p>
<p>In this blog post, I will show you how to deploy a Reddit clone app on Kubernetes with Ingress. This app is a simplified version of Reddit that has the basic features of creating posts, voting, commenting, and browsing subreddits. You can find the source code of the app on <a target="_blank" href="https://github.com/LondheShubham153/reddit-clone-k8s-ingress/tree/master">GitHub</a>.</p>
<p>Kubernetes is an open-source platform that allows you to automate the deployment, scaling, and management of your containerized applications across multiple hosts. Kubernetes is also known as K8s, which is derived from the number of letters between K and s in Kubernetes.</p>
<p>Ingress is a resource that defines rules to expose services to external traffic. Ingress allows you to route the traffic from outside the cluster to the appropriate service based on the host name or path. Ingress can also provide features such as load balancing, SSL termination, name-based virtual hosting, etc.</p>
<p>Why should we deploy a Reddit clone app on Kubernetes with Ingress? There are several reasons, such as:</p>
<ul>
<li><p>To learn how to use Kubernetes and Ingress to deploy and expose a web application.</p>
</li>
<li><p>To demonstrate the benefits of Kubernetes and Ingress, such as portability, scalability, availability, efficiency, and security.</p>
</li>
<li><p>To showcase your skills and knowledge as a DevOps learner.</p>
</li>
</ul>
<p>In this blog post, I will guide you through the following steps:</p>
<ul>
<li><p>Creating two servers on AWS EC2: one for the CI server and one for the deployment server.</p>
</li>
<li><p>Cloning the repository: cloning the source code of the app from GitHub.</p>
</li>
<li><p>Containerizing the application using Docker: creating a Dockerfile, building a Docker image, and pushing it to Dockerhub.</p>
</li>
<li><p>Deploying the application to Kubernetes: writing a deployment.yml file and a service.yml file, applying them using <code>kubectl</code>, and verifying that they are running.</p>
</li>
<li><p>Configuring Ingress: explaining what Ingress is and why it is used, exposing the application using Ingress, and testing the Ingress.</p>
</li>
</ul>
<p>By the end of this blog post, you will have a fully functional Reddit clone app running on Kubernetes with Ingress. You will also have a better understanding of Kubernetes and Ingress concepts and features.</p>
<p>Let’s get started!</p>
<h2 id="heading-creating-two-servers-on-aws-ec2">Creating two servers on AWS EC2</h2>
<p>The first step is to create two servers on AWS EC2: one for the CI server and one for the deployment server. The CI server will be used to clone the source code, build the Docker image, and push it to Dockerhub. The deployment server will be used to install Kubernetes using Minikube and deploy the application using <code>kubectl</code>.</p>
<p>To create two servers on AWS EC2, follow these steps:</p>
<h3 id="heading-step-1-create-a-t2-micro-instance-for-the-ci-server">Step 1: Create a t2 micro instance for the CI server.</h3>
<ul>
<li><p>Log in to your AWS account and go to the EC2 dashboard.</p>
</li>
<li><p>Click on Launch Instance and select Ubuntu Server 22.04 LTS (HVM), SSD Volume Type as the AMI.</p>
</li>
<li><p>Choose t2.micro as the instance type and click on Next: Configure Instance Details.</p>
</li>
<li><p>Leave everything as default and click on Next: Add Storage.</p>
</li>
<li><p>Leave everything as default and click on Next: Add Tags.</p>
</li>
<li><p>Add a tag with Key as Name and Value as CI-server and click on Next: Configure Security Group.</p>
</li>
<li><p>Create a new security group with Type as SSH, Protocol as TCP, Port Range as 22, Source as Anywhere (0.0.0.0/0), Description as SSH access. Click on Review and Launch.</p>
</li>
<li><p>Review your instance details and click on Launch.</p>
</li>
<li><p>Select an existing key pair or create a new one. Check the acknowledgment box and click on Launch Instances.</p>
</li>
<li><p>Wait for your instance to launch and note down its public IP address.</p>
</li>
</ul>
<h3 id="heading-step-2-create-a-t2-medium-instance-for-the-deployment-server">Step 2: Create a t2 medium instance for the deployment server.</h3>
<ul>
<li><p>Repeat the same steps as above but choose t2.medium as the instance type instead of t2.micro.</p>
</li>
<li><p>Add a tag with Key as Name and Value as Deployment-server instead of CI-server.</p>
</li>
<li><p>Create a new security group with Type as Custom TCP Rule, Protocol as TCP, Port Range as 30000 - 32767, Source as Anywhere (0.0.0.0/0), Description as NodePort access. This will allow us to access the NodePort service from outside the cluster.</p>
</li>
<li><p>Select the same key pair as before and launch the instance.</p>
</li>
<li><p>Wait for your instance to launch and note down its public IP address.</p>
</li>
</ul>
<h3 id="heading-step-3-install-the-required-components-on-both-servers">Step 3: Install the required components on both servers.</h3>
<ul>
<li><p>Connect to both servers using SSH. For example, ssh -i &lt;keypair.pem&gt; ubuntu@&lt;public-ip-address&gt;.</p>
</li>
<li><p>On the CI server, install git, docker, and docker-compose using the following commands:</p>
</li>
</ul>
<pre><code class="lang-bash">sudo apt update
sudo apt install git -y
sudo apt install docker.io -y
sudo usermod -aG docker <span class="hljs-variable">$USER</span> &amp;&amp; newgrp docker
sudo apt install docker-compose
sudo chmod +x /usr/<span class="hljs-built_in">local</span>/bin/docker-compose
</code></pre>
<ul>
<li>On the deployment server, install <code>kubectl</code> and minikube using the following commands:</li>
</ul>
<pre><code class="lang-bash">sudo apt update
sudo apt install curl docker.io -y
sudo snap install kubectl --classic
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/<span class="hljs-built_in">local</span>/bin/minikube
minikube start --driver=docker
</code></pre>
<h2 id="heading-cloning-the-repository">Cloning the repository</h2>
<p>The next step is to clone the repository that contains the source code of the Reddit clone app. The <a target="_blank" href="https://github.com/LondheShubham153/reddit-clone-k8s-ingress.git">repository</a> is available on GitHub.</p>
<p>To clone the repository, follow these steps:</p>
<h3 id="heading-step-1-clone-the-repository-from-httpsgithubcomlondheshubham153reddit-clone-k8s-ingressgithttpsgithubcomlondheshubham153reddit-clone-k8s-ingressgit">Step 1: Clone the repository from <a target="_blank" href="https://github.com/LondheShubham153/reddit-clone-k8s-ingress.git">https://github.com/LondheShubham153/reddit-clone-k8s-ingress.git</a>.</h3>
<ul>
<li>On the CI server, create a directory called <strong>reddit-clone</strong> and cd into it:</li>
</ul>
<pre><code class="lang-bash">mkdir reddit-clone &amp;&amp; <span class="hljs-built_in">cd</span> reddit-clone
</code></pre>
<ul>
<li>Clone the repository using git:</li>
</ul>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/LondheShubham153/reddit-clone-k8s-ingress.git .
</code></pre>
<ul>
<li>You should see the following files and directories in your <strong>reddit-clone</strong> directory:</li>
</ul>
<pre><code class="lang-bash">.
├── Dockerfile
├── README.md
├── deployment.yml
├── firebase.json
├── <span class="hljs-built_in">functions</span>
│   ├── package-lock.json
│   ├── package.json
│   ├── src
│   │   └── index.ts
│   ├── tsconfig.dev.json
│   └── tsconfig.json
├── ingress.yml
├── next-env.d.ts
├── next.config.js
├── package-lock.json
├── package.json
├── public
│   ├── favicon.ico
│   ├── images
│   │   ├── googlelogo.png
│   │   ├── recCommsArt.png
│   │   ├── redditFace.svg
│   │   ├── redditPersonalHome.png
│   │   ├── redditText.svg
│   │   └── redditlogo.png
│   └── vercel.svg
├── service.yml
├── src
│   ├── atoms
│   │   ├── authModalAtom.ts
│   │   ├── communitiesAtom.ts
│   │   ├── directoryMenuAtom.ts
│   │   ├── postsAtom.ts
│   │   └── userAtom.ts
│   ├── chakra
│   │   ├── button.ts
│   │   ├── input.ts
│   │   └── theme.ts
│   ├── components
│   │   ├── Community
│   │   │   ├── About.tsx
│   │   │   ├── CommunityNotFound.tsx
│   │   │   ├── CreatePostLink.tsx
│   │   │   ├── Header.tsx
│   │   │   ├── PersonalHome.tsx
│   │   │   ├── Premium.tsx
│   │   │   ├── Recommendations.tsx
│   │   │   └── Temp.tsx
│   │   ├── Layout
│   │   │   ├── InputField.tsx
│   │   │   ├── InputItem.tsx
│   │   │   ├── PageContent.tsx
│   │   │   └── index.tsx
│   │   ├── Main
│   │   │   └── index.tsx
│   │   ├── Modal
│   │   │   ├── Auth
│   │   │   │   ├── Inputs.tsx
│   │   │   │   ├── Login.tsx
│   │   │   │   ├── OAuthButtons.tsx
│   │   │   │   ├── ResetPassword.tsx
│   │   │   │   ├── SignUp.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── CreateCommunity
│   │   │   │   └── index.tsx
│   │   │   └── ModalWrapper.tsx
│   │   ├── Navbar
│   │   │   ├── Directory
│   │   │   │   ├── Communities.tsx
│   │   │   │   ├── MenuListItem.tsx
│   │   │   │   ├── Moderating.tsx
│   │   │   │   ├── MyCommunities.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── RightContent
│   │   │   │   ├── ActionIcon.tsx
│   │   │   │   ├── AuthButtons.tsx
│   │   │   │   ├── Icons.tsx
│   │   │   │   ├── ProfileMenu
│   │   │   │   │   ├── MenuWrapper.tsx
│   │   │   │   │   ├── NoUserList.tsx
│   │   │   │   │   └── UserList.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── SearchInput.tsx
│   │   │   └── index.tsx
│   │   └── Post
│   │       ├── Comments
│   │       │   ├── CommentItem.tsx
│   │       │   ├── Input.tsx
│   │       │   └── index.tsx
│   │       ├── Loader.tsx
│   │       ├── PostForm
│   │       │   ├── ImageUpload.tsx
│   │       │   ├── NewPostForm.tsx
│   │       │   ├── TabItem.tsx
│   │       │   └── TextInputs.tsx
│   │       ├── PostItem
│   │       │   └── index.tsx
│   │       ├── Posts.tsx
│   │       └── PostsHome.tsx
│   ├── firebase
│   │   ├── authFunctions.ts
│   │   ├── clientApp.ts
│   │   └── errors.ts
│   ├── helpers
│   │   └── firestore.ts
│   ├── hooks
│   │   ├── useAuth.ts
│   │   ├── useCommunityData.ts
│   │   ├── useDirectory.ts
│   │   ├── usePosts.ts
│   │   └── useSelectFile.ts
│   ├── pages
│   │   ├── _app.tsx
│   │   ├── _document.tsx
│   │   ├── api
│   │   │   └── hello.ts
│   │   ├── index.tsx
│   │   └── r
│   │       └── [community]
│   │           ├── comments
│   │           │   └── [pid].tsx
│   │           ├── index.tsx
│   │           └── submit.tsx
│   └── styles
│       └── globals.css
└── tsconfig.json
</code></pre>
<h2 id="heading-containerizing-the-application-using-docker">Containerizing the application using Docker</h2>
<p>The next step is to containerize the application using Docker. Docker is a tool that allows you to create, run, and share containers that contain your application and its dependencies.</p>
<p>To containerize the application using Docker, follow these steps:</p>
<h3 id="heading-step-1-create-a-dockerfile">Step 1: Create a Dockerfile</h3>
<p>A Dockerfile is a file that contains instructions on how to build a Docker image. A Docker image is a snapshot of your application and its dependencies that can be run as a container.</p>
<p>To create a Dockerfile, use your favorite text editor and write the following code:</p>
<pre><code class="lang-Dockerfile"><span class="hljs-keyword">FROM</span> node:<span class="hljs-number">19</span>-alpine3.<span class="hljs-number">15</span>

<span class="hljs-keyword">WORKDIR</span><span class="bash"> /reddit-clone</span>

<span class="hljs-keyword">COPY</span><span class="bash"> . /reddit-clone</span>
<span class="hljs-keyword">RUN</span><span class="bash"> npm install </span>

<span class="hljs-keyword">EXPOSE</span> <span class="hljs-number">3000</span>
<span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"npm"</span>,<span class="hljs-string">"run"</span>,<span class="hljs-string">"dev"</span>]</span>
</code></pre>
<p>Save the file as Dockerfile in your reddit-clone directory.</p>
<h3 id="heading-step-2-build-the-docker-image">Step 2: Build the Docker image.</h3>
<p>To build the Docker image from the Dockerfile, use the following command:</p>
<pre><code class="lang-bash">docker build -t &lt;DockerHub_Username&gt;/reddit-clone .
</code></pre>
<p>Replace &lt;DockerHub_Username&gt; with your own username on Dockerhub. For example, if your username is londheshubham153, use:</p>
<pre><code class="lang-bash">docker build -t ajitfawade14/reddit-clone .
</code></pre>
<p>This command will create a Docker image with the name reddit.</p>
<h3 id="heading-deploying-the-application-to-kubernetes">Deploying the application to Kubernetes</h3>
<p>The next step is to deploy the application to Kubernetes using <code>kubectl</code>. Kubectl is a command-line tool that allows you to interact with the Kubernetes cluster and manage your resources.</p>
<p>To deploy the application to Kubernetes, follow these steps:</p>
<h3 id="heading-step-1-write-a-deploymentyml-file">Step 1: Write a deployment.yml file.</h3>
<p>A deployment.yml file is a file that defines the desired state of your application, such as the number of replicas, the image, the ports, etc. A deployment.yml file can be used to create or update a deployment resource in Kubernetes. A deployment resource is a higher-level abstraction that manages replica sets and provides declarative updates to pods.</p>
<p>To write a deployment.yml file, use your favorite text editor and write the following code:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">reddit-clone-deployment</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">reddit-clone</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">reddit-clone</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">reddit-clone</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">reddit-clone</span>
        <span class="hljs-attr">image:</span> <span class="hljs-string">ajitfawade14/reddit-clone</span>
        <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">3000</span>
</code></pre>
<p>Save the file as deployment.yml in your reddit-clone directory.</p>
<h3 id="heading-step-2-write-a-serviceyml-file">Step 2: Write a service.yml file.</h3>
<p>A service.yml file is a file that defines how to expose your application to other pods or external clients. A service.yml file can be used to create or update a service resource in Kubernetes. A service resource is an abstraction that defines a logical set of pods and a policy to access them. A service resource can be of different types, such as ClusterIP, NodePort, LoadBalancer, or ExternalName.</p>
<p>To write a service.yml file, use your favorite text editor and write the following code:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">reddit-clone-service</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">reddit-clone</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">NodePort</span>
  <span class="hljs-attr">ports:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">3000</span>
    <span class="hljs-attr">targetPort:</span> <span class="hljs-number">3000</span>
    <span class="hljs-attr">nodePort:</span> <span class="hljs-number">31000</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">reddit-clone</span>
</code></pre>
<p>Save the file as service.yml in your reddit-clone directory.</p>
<h3 id="heading-step-3-apply-the-deployment-and-service-files-using-kubectl">Step 3: Apply the deployment and service files using <code>kubectl</code></h3>
<p>To apply the deployment and service files using <code>kubectl</code>, use the following commands:</p>
<pre><code class="lang-bash">kubectl apply -f deployment.yml

kubectl apply -f service.yml
</code></pre>
<p>These commands will create or update the deployment and service resources in your Kubernetes cluster.</p>
<h3 id="heading-step-4-verify-that-the-deployment-and-service-are-running">Step 4: Verify that the deployment and service are running</h3>
<p>To verify that the deployment and service are running, use the following commands:</p>
<pre><code class="lang-bash">kubectl get deployments

kubectl get services
</code></pre>
<p>These commands will show you the status and details of your deployments and services. You should see something like this:</p>
<pre><code class="lang-bash">
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
reddit-clone-deployment   2/2     2            2           95s

NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes             ClusterIP      10.96.0.1        &lt;none&gt;        443/TCP          2m48s
reddit-clone-service   LoadBalancer   10.108.185.100   &lt;pending&gt;     3000:30086/TCP   43s
</code></pre>
<p>This means that your deployment has created three pods that are running your Reddit clone app, and your service has exposed them on port 80 externally and port 5000 internally. The NodePort type of service has also allocated a port from a range (default 30000-32767) for your service. In this case, it is 31000. This port will be accessible from outside the cluster using any node IP address and this port number.</p>
<h3 id="heading-expose-the-app">Expose the app</h3>
<ol>
<li><p>First We need to expose our deployment so use <code>kubectl expose deployment reddit-clone-deployment --type=NodePort</code> command.</p>
</li>
<li><p>You can test your deployment using curl -L <strong>http://192.168.49.2:30759</strong>. <strong>192.168.49.2</strong> is a minikube ip &amp; Port <strong>30759</strong> is defined in Service.yml</p>
</li>
<li><p>Then We have to expose our app service <code>kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0 &amp;</code></p>
</li>
</ol>
<h2 id="heading-configuring-ingress">Configuring Ingress</h2>
<p>The final step is to configure Ingress for your application. Ingress is a resource that defines rules to expose services to external traffic. Ingress allows you to route traffic from outside the cluster to your services based on host name or path. Ingress can also provide features such as load balancing, SSL termination, name-based virtual hosting, etc.</p>
<p><a target="_blank" href="https://www.weave.works/blog/introduction-to-kubernetes-ingress"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697651513668/689b4e65-3e3b-45ab-9a2c-32c3e8b49e15.jpeg" alt="Credits: weave.works" class="image--center mx-auto" /></a></p>
<p>To configure Ingress for your application, follow these steps:</p>
<h3 id="heading-step-1-explain-what-ingress-is-and-why-it-is-used">Step 1: Explain what Ingress is and why it is used.</h3>
<p>Ingress is a resource that defines rules to expose services to external traffic. Ingress allows you to:</p>
<ul>
<li><p>Expose your services to the internet or other networks using a single IP address or domain name</p>
</li>
<li><p>Route the traffic to your services based on the host name or path</p>
</li>
<li><p>Provide features such as load balancing, SSL termination, name-based virtual hosting, etc.</p>
</li>
<li><p>Simplify the management and configuration of your services</p>
</li>
</ul>
<p>Ingress is useful for scenarios where you want to:</p>
<ul>
<li><p>Host multiple services or applications on the same cluster and expose them using different host names or paths</p>
</li>
<li><p>Use a custom domain name or SSL certificate for your services</p>
</li>
<li><p>Use advanced load balancing or routing features for your services</p>
</li>
</ul>
<h3 id="heading-step-2-expose-the-application-using-ingress">Step 2: Expose the application using Ingress.</h3>
<p>To expose the application using Ingress, you need to do two things:</p>
<ul>
<li><p>Enable the Ingress addon on Minikube</p>
</li>
<li><p>Write an ingress.yml file that defines the Ingress rules for your service</p>
</li>
</ul>
<p>To enable the Ingress addon on Minikube, use the following command:</p>
<pre><code class="lang-bash">minikube addons <span class="hljs-built_in">enable</span> ingress
</code></pre>
<p>This command will install and start the Ingress controller on your cluster. The Ingress controller is responsible for fulfilling the Ingress rules by routing the traffic to the appropriate services.</p>
<p>To write an ingress.yml file that defines the Ingress rules for your service, use your favorite text editor and write the following code:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Ingress</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">ingress-reddit-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">host:</span> <span class="hljs-string">"domain.com"</span>
    <span class="hljs-attr">http:</span>
      <span class="hljs-attr">paths:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">pathType:</span> <span class="hljs-string">Prefix</span>
        <span class="hljs-attr">path:</span> <span class="hljs-string">"/test"</span>
        <span class="hljs-attr">backend:</span>
          <span class="hljs-attr">service:</span>
            <span class="hljs-attr">name:</span> <span class="hljs-string">reddit-clone-service</span>
            <span class="hljs-attr">port:</span>
              <span class="hljs-attr">number:</span> <span class="hljs-number">3000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">host:</span> <span class="hljs-string">"*.domain.com"</span>
    <span class="hljs-attr">http:</span>
      <span class="hljs-attr">paths:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">pathType:</span> <span class="hljs-string">Prefix</span>
        <span class="hljs-attr">path:</span> <span class="hljs-string">"/test"</span>
        <span class="hljs-attr">backend:</span>
          <span class="hljs-attr">service:</span>
            <span class="hljs-attr">name:</span> <span class="hljs-string">reddit-clone-service</span>
            <span class="hljs-attr">port:</span>
              <span class="hljs-attr">number:</span> <span class="hljs-number">3000</span>
</code></pre>
<p>Save the file as ingress.yml in your reddit-clone directory.</p>
<p>To apply the ingress.yml file using <code>kubectl</code>, use the following command:</p>
<pre><code class="lang-bash">kubectl apply -f ingress.yml
</code></pre>
<p>This command will create or update the Ingress resource in your Kubernetes cluster.</p>
<h3 id="heading-step-3-test-the-ingress">Step 3: Test the Ingress.</h3>
<p>To test the Ingress, use the following command in the terminal.</p>
<pre><code class="lang-bash">curl -L domain/<span class="hljs-built_in">test</span>
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697655993059/e595a8bd-189b-49db-8ffb-dbd24f935014.png" alt class="image--center mx-auto" /></p>
<p>Congratulations! You have successfully deployed a Reddit clone app on Kubernetes with Ingress!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, we have learned how to deploy a Reddit clone app on Kubernetes with Ingress. We have covered the following steps:</p>
<ul>
<li><p><strong>Creating two servers on AWS EC2:</strong> one for the CI server and one for the deployment server.</p>
</li>
<li><p><strong>Cloning the repository:</strong> cloning the source code of the app from GitHub.</p>
</li>
<li><p><strong>Containerizing the application using Docker:</strong> creating a Dockerfile, building a Docker image, and pushing it to Dockerhub.</p>
</li>
<li><p><strong>Deploying the application to Kubernetes:</strong> writing a deployment.yml file and a service.yml file, applying them using <code>kubectl</code>, and verifying that they are running.</p>
</li>
<li><p><strong>Configuring Ingress:</strong> explaining what Ingress is and why it is used, exposing the application using Ingress, and testing the Ingress.</p>
</li>
</ul>
<p>We have also demonstrated some of the benefits of Kubernetes and Ingress, such as portability, scalability, availability, efficiency, and security.</p>
<p>We hope you enjoyed this blog post and learned something new from it. Please feel free to share your feedback or queries in the comments section below.</p>
<p>Happy learning! 😊</p>
]]></content:encoded></item><item><title><![CDATA[Cracking Kubernetes: Mastering Key Concepts and Top Interview Questions]]></title><description><![CDATA[Kubernetes is one of the most popular and widely used tools for container orchestration and management. It is an open-source platform that allows you to automate the deployment, scaling, and management of your containerized applications across multip...]]></description><link>https://blog.ajitfawade.com/cracking-kubernetes-mastering-key-concepts-and-top-interview-questions</link><guid isPermaLink="true">https://blog.ajitfawade.com/cracking-kubernetes-mastering-key-concepts-and-top-interview-questions</guid><category><![CDATA[Devops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[interview questions]]></category><category><![CDATA[beginnersguide]]></category><category><![CDATA[#90daysofdevops]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Fri, 13 Oct 2023 19:26:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697223118023/41e1d0b6-c878-4f6f-810a-5d1e3d0731f7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Kubernetes is one of the most popular and widely used tools for container orchestration and management. It is an open-source platform that allows you to automate the deployment, scaling, and management of your containerized applications across multiple hosts. Kubernetes is also known as K8s, which is derived from the number of letters between K and s in Kubernetes.</p>
<p>If you are preparing for a DevOps or Kubernetes interview, you need to be well-versed in the basic concepts and features of Kubernetes. You also need to be able to demonstrate your practical skills and knowledge by answering some common Kubernetes interview questions.</p>
<blockquote>
<p>To help you ace your interview, I have compiled a comprehensive list of the top 16 Kubernetes interview questions and answers. These questions cover a wide range of topics, such as Kubernetes architecture, container concepts, deployment strategies, networking, scaling, security, troubleshooting, and integration with other tools.</p>
</blockquote>
<p>So, without further ado, let’s dive into the blog post and learn the top Kubernetes interview questions and answers.</p>
<h1 id="heading-top-16-kubernetes-interview-questions-and-answers">Top 16 Kubernetes Interview Questions and Answers:</h1>
<h2 id="heading-1-what-is-kubernetes-and-why-it-is-important">1. What is Kubernetes and why it is important?</h2>
<p>Kubernetes is an open-source platform that allows you to automate the deployment, scaling, and management of your containerized applications across multiple hosts. It was originally developed by Google based on their experience of running production workloads at scale. It is now maintained by the Cloud Native Computing Foundation (CNCF).</p>
<p>Kubernetes is important because it provides several benefits for your applications, such as:</p>
<ul>
<li><p><strong>Portability</strong>: You can run your applications on any platform that supports Kubernetes, such as on-premises, cloud, or hybrid environments. You can also migrate your applications from one platform to another without any hassle.</p>
</li>
<li><p><strong>Scalability</strong>: You can scale your applications up or down based on the demand or performance. You can also use horizontal or vertical scaling methods to adjust the number or size of your pods (the smallest unit of deployment in Kubernetes).</p>
</li>
<li><p><strong>Availability</strong>: You can ensure that your applications are always available and resilient to failures. You can use features such as replication, load balancing, health checks, self-healing, and rolling updates to achieve high availability.</p>
</li>
<li><p><strong>Efficiency</strong>: You can optimize the utilization of your resources and reduce operational costs. You can use features such as resource limits, requests, quotas, and autoscaling to allocate and manage your resources effectively.</p>
</li>
<li><p><strong>Security</strong>: You can protect your applications from unauthorized access or exposure. You can use features such as network policies, service accounts, secrets, encryption, authentication, and authorization to enforce network security and access control.</p>
</li>
</ul>
<h2 id="heading-2-what-is-the-difference-between-docker-swarm-and-kubernetes">2. What is the difference between docker swarm and Kubernetes?</h2>
<p>Docker Swarm and Kubernetes are both tools for container orchestration and management. They both allow you to create clusters of nodes (servers) that run containers and provide features such as service discovery, load balancing, scaling, scheduling, networking, and security.</p>
<p>However, there are some differences between Docker Swarm and Kubernetes in terms of their architecture, functionality, complexity, and maturity.</p>
<p>Some of the main differences are:</p>
<ul>
<li><p><strong>Architecture</strong>: Docker Swarm follows a simple architecture where all the nodes are equal and communicate with each other using a gossip protocol. There is no master node or central control plane in Docker Swarm. Kubernetes follows a more complex architecture where there are master nodes that control the cluster state and worker nodes that run the containers. There is a central control plane in Kubernetes that consists of several components such as an API server, controller manager, scheduler, etcd, etc.</p>
</li>
<li><p><strong>Functionality</strong>: Docker Swarm provides basic functionality for container orchestration and management. It supports only one type of service (replicated) and one type of load balancer (round-robin). It does not support advanced features such as rolling updates, health checks, self-healing, ingress controllers, etc. Kubernetes provides more functionality for container orchestration and management. It supports multiple types of services (replicated, daemonset, statefulset) and multiple types of load balancers (round-robin, least-connection). It also supports advanced features such as rolling updates, health checks, self-healing, ingress controllers, etc.</p>
</li>
<li><p><strong>Complexity</strong>: Docker Swarm is easier to set up and use than Kubernetes. It has a simpler and more intuitive command-line interface and configuration file than Kubernetes. It also has less overhead and maintenance than Kubernetes. Kubernetes is harder to set up and use than Docker Swarm. It has a more complex and less intuitive command-line interface and configuration file than Docker Swarm. It also has more overhead and maintenance than Docker Swarm.</p>
</li>
<li><p><strong>Maturity</strong>: Docker Swarm is less mature and stable than Kubernetes. It has fewer features and integrations than Kubernetes. It also has less community support and documentation than Kubernetes. Kubernetes is more mature and stable than Docker Swarm. It has more features and integrations than Docker Swarm. It also has more community support and documentation than Docker Swarm.</p>
</li>
</ul>
<h2 id="heading-3-how-does-kubernetes-handle-network-communication-between-containers">3. How does Kubernetes handle network communication between containers?</h2>
<p>Kubernetes handles network communication between containers using the following concepts:</p>
<ul>
<li><p><strong>Pod</strong>: A pod is a group of one or more containers that share the same network namespace and IP address. Containers within a pod can communicate with each other using <a target="_blank" href="http://localhost">localhost</a>. Pods are the smallest unit of deployment in Kubernetes.</p>
</li>
<li><p><strong>Service</strong>: A service is an abstraction that defines a logical set of pods and a policy to access them. A service provides a stable and consistent IP address and DNS name for the pods, regardless of where they are scheduled or how they are scaled. Services can be of different types, such as ClusterIP, NodePort, LoadBalancer, or ExternalName. Services allow pods to communicate with each other across nodes or clusters.</p>
</li>
<li><p><strong>Ingress</strong>: An ingress is an API object that defines rules to expose services to external traffic. An ingress controller is responsible for fulfilling the ingress rules by routing the traffic to the appropriate services. An ingress can provide features such as load balancing, SSL termination, name-based virtual hosting, etc. Ingress allows pods to communicate with external clients or services.</p>
</li>
</ul>
<h2 id="heading-4-how-does-kubernetes-handle-the-scaling-of-applications">4. How does Kubernetes handle the scaling of applications?</h2>
<p>Kubernetes handles the scaling of applications using the following concepts:</p>
<ul>
<li><p><strong>ReplicaSet</strong>: A ReplicaSet is a controller that ensures that a specified number of replicas of a pod are running at any given time. A ReplicaSet can be used to scale up or down the number of pods manually or automatically based on CPU utilization or other metrics.</p>
</li>
<li><p><strong>Deployment</strong>: A deployment is a higher-level abstraction that manages ReplicaSets and provides declarative updates to pods. A deployment can be used to scale up or down the number of pods by changing the replica field in the deployment specification. A deployment can also perform rolling updates or rollbacks to pods without any downtime.</p>
</li>
<li><p><strong>Horizontal Pod Autoscaler (HPA)</strong>: An HPA is a controller that automatically scales the number of pods in a ReplicaSet, Deployment, StatefulSet, or any other custom resource that implements the scale subresource based on the observed CPU utilization or other metrics. An HPA can be configured with a target CPU utilization percentage and a minimum and maximum number of pods.</p>
</li>
<li><p><strong>Vertical Pod Autoscaler (VPA)</strong>: A VPA is a controller that automatically adjusts the CPU and memory requests and limits of pods based on their resource consumption and availability. A VPA can be configured with different modes, such as off (no action), initial (set requests only on pod creation), auto (set requests and limits on pod creation and update), or recreate (set requests and limits on pod creation and recreate existing pods).</p>
</li>
</ul>
<h2 id="heading-5-what-is-a-kubernetes-deployment-and-how-does-it-differ-from-a-replicaset">5. What is a Kubernetes Deployment and how does it differ from a ReplicaSet?</h2>
<p>A Kubernetes Deployment is a higher-level abstraction that manages ReplicaSets and provides declarative updates to pods. A Deployment can be used to create new ReplicaSets or update existing ones. A Deployment can also perform rolling updates or rollbacks to pods without any downtime.</p>
<p>A ReplicaSet is a lower-level abstraction that ensures that a specified number of replicas of a pod are running at any given time. A ReplicaSet can be used to scale up or down the number of pods manually or automatically based on CPU utilization or other metrics.</p>
<p>The main difference between a Deployment and a ReplicaSet is that a Deployment can perform declarative updates to pods, while a ReplicaSet can only ensure that a fixed number of pods are running. A Deployment can also manage multiple ReplicaSets, while a ReplicaSet can only manage one set of pods.</p>
<h2 id="heading-6-can-you-explain-the-concept-of-rolling-updates-in-kubernetes">6. Can you explain the concept of rolling updates in Kubernetes?</h2>
<p>Rolling updates are a way of updating pods in a Deployment without any downtime. Rolling updates allow you to gradually replace old pods with new ones while ensuring that at least a certain number of pods are available at all times.</p>
<p>To perform rolling updates in Kubernetes, you need to specify the following parameters in your Deployment specification:</p>
<ul>
<li><p><strong>updateStrategy.type</strong>: This defines the type of update strategy for your Deployment. The default value is RollingUpdate, which means that old pods are replaced with new ones gradually.</p>
</li>
<li><p><strong>updateStrategy.rollingUpdate.maxUnavailable</strong>: This defines the maximum number of pods that can be unavailable during the update process. The default value is 25%, which means that up to 25% of the total number of pods can be unavailable at any time.</p>
</li>
<li><p><strong>updateStrategy.rollingUpdate.maxSurge</strong>: This defines the maximum number of pods that can be created above the desired number of pods during the update process. The default value is 25%, which means that up to 25% more pods than the desired number can be created at any time.</p>
</li>
</ul>
<p>For example, if you have a Deployment with 10 replicas and you want to update it with a new image, you can use the following specification:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">10</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">my-app</span>
        <span class="hljs-attr">image:</span> <span class="hljs-string">my-app:v2</span> <span class="hljs-comment"># This is the new image that you want to update to.</span>
  <span class="hljs-attr">strategy:</span>
    <span class="hljs-attr">type:</span> <span class="hljs-string">RollingUpdate</span>
    <span class="hljs-attr">rollingUpdate:</span>
      <span class="hljs-attr">maxUnavailable:</span> <span class="hljs-number">2</span> <span class="hljs-comment"># This means that up to 2 pods can be unavailable during the update process.</span>
      <span class="hljs-attr">maxSurge:</span> <span class="hljs-number">3</span> <span class="hljs-comment"># This means that up to 3 more pods than the desired number can be created during the update process.</span>
</code></pre>
<p>The rolling update process will work as follows:</p>
<ul>
<li><p>First, Kubernetes will create 3 new pods with the new image, since the maxSurge value is 3. This will result in 13 pods in total, out of which 10 are available and 3 are pending.</p>
</li>
<li><p>Next, Kubernetes will terminate 2 old pods, since the maxUnavailable value is 2. This will result in 11 pods in total, out of which 8 are available and 3 are pending.</p>
</li>
<li><p>Then, Kubernetes will create 2 more new pods with the new image, since the maxSurge value is still 3. This will result in 13 pods in total, out of which 10 are available and 3 are pending.</p>
</li>
<li><p>After that, Kubernetes will terminate 2 more old pods, since the maxUnavailable value is still 2. This will result in 11 pods in total, out of which 10 are available and 1 is pending.</p>
</li>
<li><p>Finally, Kubernetes will create the last new pod with the new image, since the maxSurge value is still 3. This will result in 12 pods in total, out of which 11 are available and 1 is pending.</p>
</li>
<li><p>At this point, all the old pods have been replaced with new ones, and the rolling update is complete. Kubernetes will terminate the extra pod that was created due to the maxSurge value, and bring the total number of pods back to the desired number of replicas, which is 10.</p>
</li>
</ul>
<h2 id="heading-7-how-does-kubernetes-handle-network-security-and-access-control">7. How does Kubernetes handle network security and access control?</h2>
<p>Kubernetes handles network security and access control using the following concepts:</p>
<ul>
<li><p><strong>Network Policy</strong>: A network policy is a resource that defines how pods are allowed to communicate with each other and with other network endpoints. A network policy specifies a set of rules that determine which pods can send or receive traffic based on their labels, ports, protocols, or IP addresses. A network policy can be applied to a namespace or a pod selector. A network policy requires a network plugin that supports it, such as Calico, Cilium, or Weave Net.</p>
</li>
<li><p><strong>Service Account</strong>: A service account is an identity that represents a pod or a group of pods for accessing the Kubernetes API server. A service account can be assigned to a pod using the serviceAccountName field in the pod specification. A service account can also be associated with a set of permissions or roles using role-based access control (RBAC) or attribute-based access control (ABAC).</p>
</li>
<li><p><strong>Secret</strong>: A secret is a resource that stores sensitive data in an encrypted form. A secret can be used to store passwords, tokens, keys, certificates, or any other data that you want to keep secret. A secret can be mounted as a volume or injected as an environment variable into a pod. A secret can also be referenced by a service account for accessing external services.</p>
</li>
</ul>
<h2 id="heading-8-can-you-give-an-example-of-how-kubernetes-can-be-used-to-deploy-a-highly-available-application">8. Can you give an example of how Kubernetes can be used to deploy a highly available application?</h2>
<p>Kubernetes can be used to deploy a highly available application using the following steps:</p>
<ul>
<li><p>Create a Deployment that defines the desired state of your application, such as the number of replicas, the image, the ports, etc.</p>
</li>
<li><p>Create a Service that exposes your application to other pods or external clients. The service acts as a load balancer that distributes traffic among your pods.</p>
</li>
<li><p>Create an Ingress that defines rules to expose your service to external traffic. The ingress controller routes the traffic to your service based on the host name or path.</p>
</li>
<li><p>Configure health checks for your pods using liveness and readiness probes. These probes allow Kubernetes to monitor the health and availability of your pods and restart them if they fail or become unresponsive.</p>
</li>
<li><p>Configure rolling updates for your deployment using updateStrategy parameters. These parameters allow you to perform zero-downtime updates to your pods without affecting the availability of your application.</p>
</li>
<li><p>Configure horizontal pod autoscaling for your deployment using HPA parameters. These parameters allow you to automatically scale your pods based on CPU utilization or other metrics.</p>
</li>
</ul>
<p>For example, you can use the following specifications to deploy a highly available application:</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># Deployment specification</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">3</span> <span class="hljs-comment"># This defines the desired number of replicas for your application.</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">my-app</span>
        <span class="hljs-attr">image:</span> <span class="hljs-string">my-app:v2</span> <span class="hljs-comment"># This is the new image that you want to update to.</span>
        <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">8080</span>
        <span class="hljs-attr">livenessProbe:</span> <span class="hljs-comment"># This defines a health check for your pod using an HTTP request.</span>
          <span class="hljs-attr">httpGet:</span>
            <span class="hljs-attr">path:</span> <span class="hljs-string">/healthz</span>
            <span class="hljs-attr">port:</span> <span class="hljs-number">8080</span>
          <span class="hljs-attr">initialDelaySeconds:</span> <span class="hljs-number">10</span> <span class="hljs-comment"># This defines how long to wait before performing the first probe.</span>
          <span class="hljs-attr">periodSeconds:</span> <span class="hljs-number">10</span> <span class="hljs-comment"># This defines how often to perform the probe.</span>
          <span class="hljs-attr">failureThreshold:</span> <span class="hljs-number">3</span> <span class="hljs-comment"># This defines how many failures to tolerate before restarting the pod.</span>
        <span class="hljs-attr">readinessProbe:</span> <span class="hljs-comment"># This defines a readiness check for your pod using an HTTP request.</span>
          <span class="hljs-attr">httpGet:</span>
            <span class="hljs-attr">path:</span> <span class="hljs-string">/readyz</span>
            <span class="hljs-attr">port:</span> <span class="hljs-number">8080</span>
          <span class="hljs-attr">initialDelaySeconds:</span> <span class="hljs-number">10</span> <span class="hljs-comment"># This defines how long to wait before performing the first probe.</span>
          <span class="hljs-attr">periodSeconds:</span> <span class="hljs-number">10</span> <span class="hljs-comment"># This defines how often to perform the probe.</span>
          <span class="hljs-attr">successThreshold:</span> <span class="hljs-number">2</span> <span class="hljs-comment"># This defines how many successes to require before marking the pod as ready.</span>
      <span class="hljs-attr">serviceAccountName:</span> <span class="hljs-string">my-app-sa</span> <span class="hljs-comment"># This defines the service account that the pod will use to access the Kubernetes API server.</span>
  <span class="hljs-attr">strategy:</span>
    <span class="hljs-attr">type:</span> <span class="hljs-string">RollingUpdate</span>
    <span class="hljs-attr">rollingUpdate:</span>
      <span class="hljs-attr">maxUnavailable:</span> <span class="hljs-number">2</span> <span class="hljs-comment"># This means that up to 2 pods can be unavailable during the update process.</span>
      <span class="hljs-attr">maxSurge:</span> <span class="hljs-number">3</span> <span class="hljs-comment"># This means that up to 3 more pods than the desired number can be created during the update process.</span>

<span class="hljs-comment"># Service specification</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app-service</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span> <span class="hljs-comment"># This matches the label of the pods that are part of the service.</span>
  <span class="hljs-attr">ports:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
    <span class="hljs-attr">port:</span> <span class="hljs-number">80</span> <span class="hljs-comment"># This is the port that the service will expose externally.</span>
    <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8080</span> <span class="hljs-comment"># This is the port that the pods will listen on internally.</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">LoadBalancer</span> <span class="hljs-comment"># This means that the service will be exposed externally using a cloud provider's load balancer.</span>

<span class="hljs-comment"># Ingress specification</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.k8s.io/v1beta1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Ingress</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app-ingress</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">host:</span> <span class="hljs-string">my-app.example.com</span> <span class="hljs-comment"># This is the host name that will be used to access the service from outside the cluster.</span>
    <span class="hljs-attr">http:</span>
      <span class="hljs-attr">paths:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">/</span> <span class="hljs-comment"># This is the path that will be used to access the service from outside the cluster.</span>
        <span class="hljs-attr">backend:</span>
          <span class="hljs-attr">serviceName:</span> <span class="hljs-string">my-app-service</span> <span class="hljs-comment"># This refers to the name of the service that will handle the traffic.</span>
          <span class="hljs-attr">servicePort:</span> <span class="hljs-number">80</span> <span class="hljs-comment"># This refers to the port of the service that will handle the traffic.</span>
</code></pre>
<h2 id="heading-9-what-is-a-namespace-in-kubernetes-which-namespace-any-pod-takes-if-we-dont-specify-any-namespace">9. What is a namespace in Kubernetes? Which namespace any pod takes if we don’t specify any namespace?</h2>
<p>A namespace is a logical grouping of resources and objects in Kubernetes. A namespace allows you to isolate and manage different aspects of your cluster, such as projects, teams, environments, or applications. A namespace also provides a scope for names, so that you can have resources with the same name in different namespaces.</p>
<p>If you don’t specify any namespace for a pod, it will take the default namespace, which is the default namespace for all resources that are not explicitly assigned to any other namespace.</p>
<h2 id="heading-10-how-does-ingress-help-in-kubernetes">10. How does ingress help in Kubernetes?</h2>
<p>Ingress is a resource that defines rules to expose services to external traffic. Ingress helps in Kubernetes by allowing you to:</p>
<ul>
<li><p>Expose your services to the internet or other networks using a single IP address or domain name</p>
</li>
<li><p>Route the traffic to your services based on the host name or path</p>
</li>
<li><p>Provide features such as load balancing, SSL termination, name-based virtual hosting, etc.</p>
</li>
<li><p>Simplify the management and configuration of your services</p>
</li>
</ul>
<h2 id="heading-11-explain-different-types-of-services-in-kubernetes">11. Explain different types of services in Kubernetes</h2>
<p>Services are abstractions that define a logical set of pods and a policy to access them. Services allow pods to communicate with each other across nodes or clusters. There are different types of services in Kubernetes, such as:</p>
<ul>
<li><p><strong>ClusterIP</strong>: This is the default type of service that assigns a stable and internal IP address to the service. This IP address is only reachable within the cluster and can be used by other pods to access the service.</p>
</li>
<li><p><strong>NodePort</strong>: This type of service exposes the service on a static port on each node in the cluster. This port can be accessed from outside the cluster using the node IP address and the port number.</p>
</li>
<li><p><strong>LoadBalancer</strong>: This type of service exposes the service externally using a cloud provider’s load balancer. This load balancer assigns an external IP address to the service and routes the traffic to the nodes and ports that are part of the service.</p>
</li>
<li><p><strong>ExternalName</strong>: This type of service maps the service to an external DNS name. This DNS name can be resolved by pods or external clients using a CNAME record.</p>
</li>
</ul>
<h2 id="heading-12-can-you-explain-the-concept-of-self-healing-in-kubernetes-and-give-examples-of-how-it-works">12. Can you explain the concept of self-healing in Kubernetes and give examples of how it works?</h2>
<p>Self-healing is a concept that refers to the ability of Kubernetes to detect and correct failures or errors in its resources and objects. Self-healing helps in Kubernetes by ensuring that your applications are always available and resilient to failures.</p>
<p>Some examples of how self-healing works in Kubernetes are:</p>
<ul>
<li><p>If a pod fails or becomes unresponsive, Kubernetes will restart or replace it with a new one based on the liveness probe and readiness probe settings.</p>
</li>
<li><p>If a node fails or becomes unreachable, Kubernetes will reschedule the pods that were running on that node to other nodes in the cluster based on the node affinity and anti-affinity settings.</p>
</li>
<li><p>If a deployment fails or becomes outdated, Kubernetes will roll back or update it with a new one based on the updateStrategy parameters.</p>
</li>
<li><p>If a replicaSet fails or becomes under-scaled or over-scaled, Kubernetes will adjust it with a new one based on the HPA parameters.</p>
</li>
</ul>
<h2 id="heading-13-how-does-kubernetes-handle-storage-management-for-containers">13. How does Kubernetes handle storage management for containers?</h2>
<p>Kubernetes handles storage management for containers using the following concepts:</p>
<ul>
<li><p><strong>Volume</strong>: A volume is a directory that is accessible by all containers in a pod. A volume can be used to store data that needs to persist across container restarts or share data between containers in a pod. A volume can be backed by different types of storage sources, such as emptyDir, hostPath, nfs, gcePersistentDisk, awsElasticBlockStore, etc.</p>
</li>
<li><p><strong>Persistent Volume (PV)</strong>: A PV is an abstraction that represents a piece of storage in the cluster. A PV can be provisioned manually by an administrator or dynamically by a storage class. A PV can have different attributes, such as capacity, access mode, reclaim policy, etc.</p>
</li>
<li><p><strong>Persistent Volume Claim (PVC)</strong>: A PVC is a request for storage by a user or an application. A PVC specifies the size and access mode of the storage that it needs. A PVC can be bound to a PV that matches its requirements.</p>
</li>
<li><p><strong>Storage Class</strong>: A storage class is an abstraction that defines a type of storage that can be dynamically provisioned by a provisioner. A storage class can have different parameters, such as performance, availability, replication, etc.</p>
</li>
</ul>
<h2 id="heading-14-how-does-the-nodeport-service-work">14. How does the NodePort service work?</h2>
<p>A NodePort service exposes the service on a static port on each node in the cluster. This port can be accessed from outside the cluster using the node IP address and the port number.</p>
<p>A NodePort service works as follows:</p>
<ul>
<li><p>When you create a NodePort service, Kubernetes will allocate a port from a range (default 30000-32767) for your service. This port will be the same on all nodes in the cluster.</p>
</li>
<li><p>Kubernetes will also create a ClusterIP service for your service, which will be used internally by the pods in the cluster to access the service.</p>
</li>
<li><p>Kubernetes will configure the iptables rules on each node to forward the traffic from the NodePort to the ClusterIP service, which will then route the traffic to the pods that are part of the service.</p>
</li>
<li><p>To access the service from outside the cluster, you can use any node IP address and the NodePort as the URL, such as <a target="_blank" href="http://node-ip:node-port">http://node-ip:node-port</a>.</p>
</li>
</ul>
<h2 id="heading-15-what-is-a-multinode-cluster-and-single-node-cluster-in-kubernetes">15. What is a multinode cluster and single-node cluster in Kubernetes?</h2>
<p>A multinode cluster is a cluster that consists of more than one node (server) that runs containers. A multinode cluster can have one or more master nodes that control the cluster state and one or more worker nodes that run the containers.</p>
<p>A single-node cluster is a cluster that consists of only one node (server) that runs both the master and worker components. A single-node cluster can be used for development or testing purposes, but not for production.</p>
<h2 id="heading-16-difference-between-create-and-apply-in-kubernetes">16. Difference between <code>create</code> and <code>apply</code> in Kubernetes?</h2>
<p><code>create</code> and <code>apply</code> are two commands that can be used to create or update resources in Kubernetes using files or the command line.</p>
<p>The main difference between create and apply is that create uses an imperative approach, while apply uses a declarative approach.</p>
<ul>
<li><p>Create uses an imperative approach, which means that you specify what actions you want to perform on the resources, such as create, update, delete, etc. Create does not keep track of the previous state of the resources and does not allow you to modify or merge changes with existing resources. Create is suitable for creating new resources or performing one-time operations.</p>
</li>
<li><p>Apply uses a declarative approach, which means that you specify the desired state of the resources, such as how they should look like, what properties they should have, etc. Apply keeps track of the previous state of the resources and allows you to modify or merge changes with existing resources. Apply is suitable for managing existing resources or performing recurring operations.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, I have covered some of the most common and important Kubernetes interview questions and answers for 2023. These questions will help you test your knowledge and understanding of Kubernetes concepts and features. They will also help you prepare for any interview or certification exam that you may need to take once you have completed your Kubernetes training.</p>
<p>I hope you enjoyed this blog post and learned something new from it. Please feel free to share your feedback or queries in the comments section below.</p>
<p>Happy learning! 😊</p>
]]></content:encoded></item><item><title><![CDATA[Mastering Kubernetes Persistent Volumes: A Guide for Beginners 🚀 | Day 36 of 90DaysOfDevOps]]></title><description><![CDATA[Hi everyone, welcome to my #90DaysOfDevOps blog series where I share my daily learning and progress on DevOps. Today is day 36 and the focus is on understanding and managing Persistent Volumes (PVs) in Kubernetes deployments.

The goal is to demystif...]]></description><link>https://blog.ajitfawade.com/mastering-kubernetes-persistent-volumes-a-guide-for-beginners-day-36-of-90daysofdevops</link><guid isPermaLink="true">https://blog.ajitfawade.com/mastering-kubernetes-persistent-volumes-a-guide-for-beginners-day-36-of-90daysofdevops</guid><category><![CDATA[Devops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[kubernetes-persistent-volumes]]></category><category><![CDATA[beginnersguide]]></category><category><![CDATA[storage]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Thu, 12 Oct 2023 20:18:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697140383343/072b9415-9fbc-4d2d-9f96-a17d1af35506.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi everyone, welcome to my #90DaysOfDevOps blog series where I share my daily learning and progress on DevOps. Today is day 36 and the focus is on understanding and managing Persistent Volumes (PVs) in Kubernetes deployments.</p>
<blockquote>
<p>The goal is to demystify PVs and provide a step-by-step guide on how to incorporate them into a Node Todo app. By the end of this post, you should confidently navigate the world of Kubernetes PVs.</p>
</blockquote>
<p>Let's dive in! 🚀</p>
<h2 id="heading-what-are-persistent-volumes">What are Persistent Volumes?</h2>
<p>Persistent Volumes (PVs) in Kubernetes are virtual storage units, like digital hard drives, that enable applications to store and retrieve data. Unlike ephemeral storage, which is tied to the lifecycle of a pod, PVs exist independently of pods and can persist across pod restarts or failures. PVs are useful for applications that need to store stateful data, such as databases, logs, or configuration files.</p>
<h2 id="heading-how-to-add-a-persistent-volume-to-a-node-todo-app">How to Add a Persistent Volume to a Node Todo App</h2>
<p>In this section, I'll show you how to add a persistent volume to a Node Todo app, which is a simple web application that allows users to create and manage tasks.</p>
<p>We'll create a PV resource and a Persistent Volume Claim (PVC) resource to request and bind the PV. We'll also create a Service resource to expose the deployment pod within the cluster. Here are the steps:</p>
<ol>
<li>Create a file named <code>pv.yaml</code> and paste the following content:</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">PersistentVolume</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pv-todo-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">capacity:</span>
    <span class="hljs-attr">storage:</span> <span class="hljs-string">1Gi</span>
  <span class="hljs-attr">accessModes:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">ReadWriteOnce</span>
  <span class="hljs-attr">persistentVolumeReclaimPolicy:</span> <span class="hljs-string">Retain</span>
  <span class="hljs-attr">hostPath:</span>
    <span class="hljs-attr">path:</span> <span class="hljs-string">"/tmp/data"</span>
</code></pre>
<p>This manifest defines a PV resource named <code>pv-todo-app</code> with a capacity of 1 GB, an access mode of ReadWriteOnce (which means it can be mounted by only one pod at a time), a reclaim policy of Retain (which means it will not be deleted when unbound), and a hostPath type (which means it will use a directory on the host node as storage).</p>
<ol>
<li>Create another file named <code>pvc.yaml</code> and paste the following content:</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">PersistentVolumeClaim</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pvc-todo-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">accessModes:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">ReadWriteOnce</span>
  <span class="hljs-attr">resources:</span>
    <span class="hljs-attr">requests:</span>
      <span class="hljs-attr">storage:</span> <span class="hljs-string">500Mi</span>
</code></pre>
<p>This manifest defines a PVC resource named <code>pvc-todo-app</code> that requests 1 GB of storage, an access mode of ReadWriteOnce, no storage class, and a specific PV named <code>pv-todo-app</code> to bind to.</p>
<ol>
<li>Create another file named <code>deployment.yaml</code> and paste the following content:</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">todo-app-deployment</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">1</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">todo-app</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">todo-app</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">todo-app</span>
          <span class="hljs-attr">image:</span> <span class="hljs-string">ajitfawade14/node-todo-app</span>
          <span class="hljs-attr">ports:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">8000</span>
          <span class="hljs-attr">volumeMounts:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">pv-todo-app</span>
              <span class="hljs-attr">mountPath:</span> <span class="hljs-string">/app</span>
      <span class="hljs-attr">volumes:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">pv-todo-app</span>
          <span class="hljs-attr">persistentVolumeClaim:</span>
            <span class="hljs-attr">claimName:</span> <span class="hljs-string">pvc-todo-app</span>
</code></pre>
<p>This manifest defines a Deployment resource named <code>todo-app-deployment</code> that creates one pod with a container running the <code>node-todo-app</code> image. The container exposes port 8000 and mounts a volume named <code>pv-todo-app</code> at <code>/app</code> path. The volume uses the PVC named <code>pvc-todo-app</code> to claim the PV named <code>pv-todo-app</code>.</p>
<ol>
<li>Create another file named <code>todo-svc.yaml</code> and paste the following content:</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">todo-app-svc</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">todo-app</span>
  <span class="hljs-attr">ports:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
      <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
      <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8000</span>
      <span class="hljs-attr">nodePort:</span> <span class="hljs-number">30007</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">NodePort</span>
</code></pre>
<p>This manifest defines a Service resource named <code>todo-app-svc</code> that exposes port 80 and targets the pods with the label <code>app:todo-app</code>. This service allows us to access our app from outside the cluster.</p>
<ol>
<li><p>Apply the manifests to create the resources on the Kubernetes cluster:</p>
<pre><code class="lang-bash"> kubectl apply -f pv.yaml -f pvc.yaml -f deployment.yaml -f todo-svc.yaml
</code></pre>
</li>
<li><p>Verify that the resources are created:</p>
<pre><code class="lang-bash"> kubectl get pv,pvc,deploy,svc
</code></pre>
</li>
</ol>
<p>You should see something like this:</p>
<pre><code class="lang-bash">NAME                           CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
persistentvolume/pv-todo-app   1Gi        RWO            Retain           Available                                   8s

NAME                                 STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/pvc-todo-app   Pending                                      local-path     8s

NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/todo-app-deployment   0/1     1            0           8s

NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes     ClusterIP   10.96.0.1        &lt;none&gt;        443/TCP        39d
service/todo-app-svc   NodePort    10.102.171.108   &lt;none&gt;        80:30007/TCP   8s
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697137161363/25bfea98-566b-4d41-aa55-dc92c7fdf318.png" alt class="image--center mx-auto" /></p>
<p><strong>Congratulations!</strong></p>
<p>You have successfully added a persistent volume to your Node Todo app.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, I learned how to add a persistent volume to a Node Todo app on Kubernetes. I learned how to create a PV resource, a PVC resource, a Deployment resource, and a Service resource for the Node Todo app. I also learned how to apply the manifests and verify the status of the resources on the Kubernetes cluster.</p>
<p>I hope you found this post useful and informative. If you have any questions or feedback, feel free to leave a comment below or reach out to me on LinkedIn or GitHub.</p>
<p>Thanks for reading and happy coding! 😊</p>
<p>LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/ajitfawade/">https://www.linkedin.com/in/ajitfawade/</a></p>
<p>GitHub: <a target="_blank" href="https://github.com/ajitfawade">https://github.com/ajitfawade</a></p>
]]></content:encoded></item><item><title><![CDATA[Demystifying Kubernetes ConfigMaps and Secrets for Smooth Deployments 🚀: Day 35 of 90DaysOfDevOps]]></title><description><![CDATA[ConfigMaps and Secrets play a pivotal role in Kubernetes for managing configuration data and safeguarding sensitive information. Let's delve into these critical components, understand how to use them, and explore their real-world significance.
What a...]]></description><link>https://blog.ajitfawade.com/demystifying-kubernetes-configmaps-and-secrets-for-smooth-deployments-day-35-of-90daysofdevops</link><guid isPermaLink="true">https://blog.ajitfawade.com/demystifying-kubernetes-configmaps-and-secrets-for-smooth-deployments-day-35-of-90daysofdevops</guid><category><![CDATA[Devops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[secrets]]></category><category><![CDATA[configmap]]></category><category><![CDATA[containers]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Wed, 11 Oct 2023 18:39:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697047659217/40b28454-f8de-4156-9f54-5e449afae5cb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>ConfigMaps and Secrets play a pivotal role in Kubernetes for managing configuration data and safeguarding sensitive information. Let's delve into these critical components, understand how to use them, and explore their real-world significance.</p>
<h2 id="heading-what-are-configmaps-and-secrets">What are ConfigMaps and Secrets?</h2>
<h3 id="heading-configmaps">ConfigMaps 📁</h3>
<p>A ConfigMap is a Kubernetes object that stores configuration data as key-value pairs. A ConfigMap allows you to decouple the configuration data from the container image, making it easier to update and reuse. You can use a ConfigMap to store environment variables, configuration files, command-line arguments, or any other data that you want to pass to your containers.</p>
<blockquote>
<p>Think of ConfigMaps as neatly labeled folders within a file cabinet. Each folder contains instructions or settings that help different parts of your spaceship (Kubernetes cluster) function efficiently.</p>
</blockquote>
<p>To create a ConfigMap for your deployment, you need to define the key-value pairs that you want to store in the ConfigMap. You can do this using a file or the command line.</p>
<ul>
<li>To create a ConfigMap using a file, you need to create a YAML or JSON file that contains the key-value pairs. For example, you can create a file named config.yml with the following content:</li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ConfigMap</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">mysql-config</span>
<span class="hljs-attr">data:</span>
  <span class="hljs-attr">MYSQL_HOST:</span> <span class="hljs-string">mysql</span>
  <span class="hljs-attr">MYSQL_USER:</span> <span class="hljs-string">root</span>
  <span class="hljs-attr">MYSQL_DATABASE:</span> <span class="hljs-string">mydb</span>
</code></pre>
<ul>
<li>To create a ConfigMap using the command line, you need to use the <code>kubectl create configmap</code> command with the <code>--from-literal</code> option. For example, you can run the following command:</li>
</ul>
<pre><code class="lang-bash">kubectl create configmap mysql-config --from-literal=MYSQL_HOST=mysql --from-literal=MYSQL_USER=root --from-literal=MYSQL_DATABASE=todo_db
</code></pre>
<h3 id="heading-secrets">Secrets 🔐</h3>
<p>A Secret is a Kubernetes object that stores sensitive data in an encrypted form. A Secret allows you to protect your data from unauthorized access or exposure. You can use a Secret to store passwords, tokens, keys, certificates, or any other data that you want to keep secret.</p>
<blockquote>
<p>Imagine Secrets as a highly secured safe where you store your most valuable possessions. They are encrypted and protected, allowing only authorized personnel (containers) with the right clearance to access them.</p>
</blockquote>
<p>To create a Secret for your deployment, you need to encode the data that you want to store in the Secret using base64 encoding. You can do this using a file or the command line.</p>
<ul>
<li>To create a Secret using a file, you need to create a YAML or JSON file that contains the encoded data. For example, you can create a file named secret.yml with the following content:</li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Secret</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">mysql-secret</span>
<span class="hljs-attr">type:</span> <span class="hljs-string">Opaque</span>
<span class="hljs-attr">data:</span>
  <span class="hljs-attr">MYSQL_PASSWORD:</span> <span class="hljs-string">YWRtaW4K</span> <span class="hljs-comment"># This is the base64 encoded value of "admin".</span>
</code></pre>
<ul>
<li>To create a Secret using the command line, you need to use the kubectl create secret generic command with the --from-literal option. For example, you can run the following command:</li>
</ul>
<pre><code class="lang-bash">kubectl create secret generic mysql-secret --from-literal=MYSQL_PASSWORD=root
</code></pre>
<p>Now, let's put these concepts into practice by setting up ConfigMaps and Secrets for a two-tier application running on Flask and MySQL within a Kubernetes cluster.</p>
<h1 id="heading-configmaps-and-secrets-in-a-two-tier-application">ConfigMaps and Secrets in a Two-Tier Application</h1>
<p>In this example, we have a two-tier application consisting of a Flask backend and a MySQL database. We'll create ConfigMaps and Secrets to manage the configuration and sensitive data for these components.</p>
<h2 id="heading-creating-configmaps-for-a-two-tier-application">Creating ConfigMaps for a Two-Tier Application</h2>
<h3 id="heading-step-1-create-a-configmap-for-your-deployment">Step 1: Create a ConfigMap for your Deployment</h3>
<p>Let's start by creating a ConfigMap for your Flask deployment. We'll define the configuration in a YAML file, <code>mysql-config.yaml</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ConfigMap</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">mysql-config</span>
<span class="hljs-attr">data:</span>
  <span class="hljs-attr">MYSQL_HOST:</span> <span class="hljs-string">mysql</span>
  <span class="hljs-attr">MYSQL_USER:</span> <span class="hljs-string">root</span>
  <span class="hljs-attr">MYSQL_DATABASE:</span> <span class="hljs-string">mydb</span>
</code></pre>
<p>In this example, we define key-value pairs for the database URL, API key, and debug mode.</p>
<h3 id="heading-step-2-update-the-flask-deployment-to-include-the-configmap">Step 2: Update the Flask deployment to include the ConfigMap</h3>
<p>To use the ConfigMap in your deployment, you need to update the deployment.yml file to include the <code>envFrom</code> field under the <code>spec.containers</code> section. The <code>envFrom</code> field allows you to inject all the key-value pairs from the ConfigMap as environment variables into your containers.</p>
<p>For example, you can update your deployment.yml file for your Flask web server with the following content:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">two-tier-app</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">two-tier-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">1</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">two-tier-app</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">two-tier-app</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">two-tier-app</span>
          <span class="hljs-attr">image:</span> <span class="hljs-string">'trainwithshubham/flaskapp:latest'</span>
          <span class="hljs-attr">envFrom:</span> <span class="hljs-literal">null</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">configMapRef:</span>
            <span class="hljs-attr">name:</span> <span class="hljs-string">mysql-config</span>
          <span class="hljs-attr">ports:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">5000</span>
          <span class="hljs-attr">imagePullPolicy:</span> <span class="hljs-string">Always</span>
</code></pre>
<p>By referencing the ConfigMap <code>mysql-config</code>, your Flask application can access these configuration values.</p>
<h3 id="heading-step-3-apply-the-updated-deployment">Step 3: Apply the updated deployment</h3>
<p>To apply the updated deployment to your cluster, you need to use the <code>kubectl apply</code> command with the <code>-f</code> option and specify the name of your deployment file. For example, you can run the following command:</p>
<pre><code class="lang-bash">kubectl apply -f two-tier-app-deployment.yml
</code></pre>
<h3 id="heading-step-4-verify-that-the-configmap-has-been-created">Step 4: Verify that the ConfigMap has been created</h3>
<p>To verify that the ConfigMap has been created, you can use the <code>kubectl get configmaps</code> command to list all the ConfigMaps. You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697045196219/bba8f566-eabc-4559-b09a-7d40410496e7.png" alt /></p>
<p>To inspect the details of a specific ConfigMap, you can use the <code>kubectl describe configmap</code> command with the name of the ConfigMap. For example, you can run the following command:</p>
<pre><code class="lang-bash">kubectl describe configmap mysql-config
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697045225075/446325a8-6af9-4315-a2d6-3bbfbd91adf8.png" alt /></p>
<h2 id="heading-creating-secrets-for-a-two-tier-application">Creating Secrets for a Two-Tier Application</h2>
<h3 id="heading-step-1-create-a-secret-for-your-deployment">Step 1: Create a Secret for your Deployment</h3>
<p>Let's create a Secret to securely store the MySQL database credentials. Define the Secret in a YAML file, <code>mysql-secret.yaml</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Secret</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">mysql-secret</span>
<span class="hljs-attr">type:</span> <span class="hljs-string">Opaque</span>
<span class="hljs-attr">data:</span>
  <span class="hljs-attr">MYSQL_PASSWORD:</span> <span class="hljs-string">YWRtaW4K</span> <span class="hljs-comment"># This is the base64 encoded value of "admin".</span>
</code></pre>
<p>In this example, we encode the password to keep it secure.</p>
<h3 id="heading-step-2-update-the-mysql-deployment-to-include-the-secret">Step 2: Update the MySQL deployment to include the Secret</h3>
<p>To use the Secret in your deployment, you need to update the deployment.yml file to include the env field under the <code>spec.containers</code> section. The env field allows you to inject specific key-value pairs from the Secret as environment variables into your containers.</p>
<p>For example, you can update your deployment.yml file for your Flask web server with the following content:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">two-tier-app</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">two-tier-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">1</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">two-tier-app</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">two-tier-app</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">two-tier-app</span>
          <span class="hljs-attr">image:</span> <span class="hljs-string">trainwithshubham/flaskapp:latest</span>
        <span class="hljs-attr">envFrom:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">configMapRef:</span>
            <span class="hljs-attr">name:</span> <span class="hljs-string">mysql-config</span> <span class="hljs-comment"># This refers to the name of the ConfigMap that we created earlier.</span>
        <span class="hljs-attr">env:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">MYSQL_ROOT_PASSWORD</span> <span class="hljs-comment"># This is an additional environment variable that we want to inject from the Secret.</span>
          <span class="hljs-attr">valueFrom:</span>
            <span class="hljs-attr">secretKeyRef:</span>
              <span class="hljs-attr">name:</span> <span class="hljs-string">mysql-secret</span> <span class="hljs-comment"># This refers to the name of the Secret that we created earlier.</span>
              <span class="hljs-attr">key:</span> <span class="hljs-string">MYSQL_PASSWORD</span> <span class="hljs-comment"># This refers to the key of the data that we want to inject from the Secret.</span>
</code></pre>
<h3 id="heading-step-3-apply-the-updated-deployment-1">Step 3: Apply the updated deployment</h3>
<p>Apply the changes to your Kubernetes cluster:</p>
<pre><code class="lang-shell">kubectl apply -f two-tier-app-deployment.yml
</code></pre>
<h3 id="heading-step-4-verify-that-the-secret-has-been-created">Step 4: Verify that the Secret has been created</h3>
<p>To verify that the Secret has been created, you can use the <code>kubectl get secrets</code> command to list all the Secrets. You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697045271996/c9ba819f-d6c7-4b1d-83d9-678fd287a43d.png" alt /></p>
<p>To inspect the details of a specific Secret, you can use the <code>kubectl describe secret</code> command with the name of the Secret. For example, you can run the following command:</p>
<pre><code class="lang-bash">kubectl describe secret mysql-secret
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697045286163/d2145e2f-4b5c-40e5-ab75-dfbbfca9812c.png" alt /></p>
<p>I've presented the two-tier deployment configuration here, but you can find all the configuration files for this project in the Git repository.</p>
<p><a target="_blank" href="https://github.com/ajitfawade/two-tier-flask-app">https://github.com/ajitfawade/two-tier-flask-app</a></p>
<h1 id="heading-exploring-real-world-scenarios">Exploring Real-World Scenarios</h1>
<p>The above steps demonstrate how to set up ConfigMaps and Secrets for a two-tier application. However, in real-world scenarios, you might encounter more complex requirements, such as dynamic updates, multiple namespaces, or external secrets management tools. The flexibility of Kubernetes allows you to adapt to these challenges efficiently.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this blog post, we learned how to create ConfigMap and Secret for a two-tier application in Kubernetes. We saw how to create, update, and apply ConfigMap and Secret for our deployments using files or the command line. We also learned how to verify that our ConfigMap and Secret have been created and applied correctly by checking the status of our resources.</p>
<p>ConfigMap and Secret are essential tools for managing configuration data and secrets in Kubernetes. They help us keep our deployments consistent, secure, and scalable. By mastering ConfigMap and Secret, we can ensure that our Kubernetes clusters run smoothly and efficiently.</p>
<p>If you want to learn more about ConfigMap and Secret, you can check out these resources:</p>
<ul>
<li><p>Kubernetes Documentation: <a target="_blank" href="https://kubernetes.io/docs/concepts/configuration/configmap/">ConfigMaps</a></p>
</li>
<li><p>Kubernetes Documentation: <a target="_blank" href="https://kubernetes.io/docs/concepts/configuration/secret/">Secrets</a></p>
</li>
<li><p>Kubernetes Tutorial: <a target="_blank" href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/">Configure a Pod to Use a ConfigMap</a></p>
</li>
<li><p>Kubernetes Tutorial: <a target="_blank" href="https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/">Distribute Credentials Securely Using Secrets</a></p>
</li>
</ul>
<p>I hope you enjoyed this blog post on creating ConfigMap and Secret for a two-tier application in Kubernetes. Please leave your feedback or questions in the comments section below.</p>
<p>Happy sailing on your Kubernetes spaceship! 🌟</p>
]]></content:encoded></item><item><title><![CDATA[How to Deploy a Microservices Application on AWS EC2 using Kubernetes: A Step-by-Step Guide]]></title><description><![CDATA[Hi everyone, welcome to my #90DaysOfDevOps blog series where I share my daily learning and progress on DevOps.
Today, I'm going to show you how to deploy a microservices application on AWS EC2 using Kubernetes, which is a popular platform for managin...]]></description><link>https://blog.ajitfawade.com/how-to-deploy-a-microservices-application-on-aws-ec2-using-kubernetes-a-step-by-step-guide</link><guid isPermaLink="true">https://blog.ajitfawade.com/how-to-deploy-a-microservices-application-on-aws-ec2-using-kubernetes-a-step-by-step-guide</guid><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[deployment]]></category><category><![CDATA[TrainWithShubham]]></category><category><![CDATA[Microservices]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Sun, 08 Oct 2023 19:20:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1696763095245/c3c5da3e-aa78-4fdd-8eb2-69b7cd9d2f2a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi everyone, welcome to my #90DaysOfDevOps blog series where I share my daily learning and progress on DevOps.</p>
<p>Today, I'm going to show you how to deploy a microservices application on AWS EC2 using Kubernetes, which is a popular platform for managing containerized applications.</p>
<p>The blog post will consist of the following sections:</p>
<ul>
<li><p>Setting up AWS EC2 Instances: In this section, I will show you how to create two t2.medium instances on AWS EC2, one for the master node and one for the worker node. I will also show you how to configure the security groups and SSH keys for these instances.</p>
</li>
<li><p>Installing Kubernetes on AWS EC2 Instances: In this section, I will show you how to install Kubernetes on both instances using <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code>. I will also show you how to initialize the master node and join the worker node to the cluster.</p>
</li>
<li><p>Deploying the Microservices Application on Kubernetes: In this section, I will show you how to deploy a microservices application that consists of a MongoDB database and a taskmaster service. The taskmaster service is a web app that allows you to create and manage tasks. The app is written in Flask and uses MongoDB as the database. I will show you how to deploy the persistent volume and persistent volume claim, the MongoDB database, the ClusterIP service for MongoDB, the taskmaster service, and the NodePort service for taskmaster.</p>
</li>
</ul>
<p>By the end of this blog post, you will have a working microservices application running on AWS EC2 using Kubernetes. You will also learn some important concepts and commands related to Kubernetes, such as pods, services, deployments, etc.</p>
<p>I hope you are excited to learn more about this topic. If you are ready, let’s begin! 🚀</p>
<h1 id="heading-setting-up-aws-ec2-instances">Setting up AWS EC2 Instances</h1>
<p>In this section, we will create two <code>t2.medium</code> instances on AWS EC2, one for the master node and one for the worker node. We will also configure the security groups and SSH keys for these instances.</p>
<h2 id="heading-creating-two-t2medium-instances">Creating Two <code>t2.medium</code> Instances</h2>
<p>To create two <code>t2.medium</code> instances on AWS EC2, follow these steps:</p>
<ol>
<li><p>Log in to your AWS console and go to the EC2 dashboard.</p>
</li>
<li><p>Click on the Launch Instance button.</p>
</li>
<li><p>Choose Ubuntu Server 22.04 LTS (HVM) as the AMI.</p>
</li>
<li><p>Choose <code>t2.medium</code> as the instance type.</p>
</li>
<li><p>Click on Next until you reach the Configure Security Group page.</p>
</li>
<li><p>Create a new security group with the following rules:</p>
<ul>
<li><p>Allow SSH from anywhere (port 22)</p>
</li>
<li><p>Allow TCP from anywhere (port 80)</p>
</li>
<li><p>Allow TCP from anywhere (port 5000)</p>
</li>
<li><p>Allow TCP from anywhere (port 6443)</p>
</li>
<li><p>Allow all traffic from within the security group (port range 0-65535)</p>
</li>
</ul>
</li>
<li><p>Click on the Review and Launch button.</p>
</li>
<li><p>Create a new key pair or use an existing one and download it.</p>
</li>
<li><p>Click on the Launch Instances button.</p>
</li>
</ol>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696763928395/e5660dbd-fc42-4515-b389-3e32635eeb7a.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully launched two instances on AWS EC2.</p>
<h2 id="heading-configuring-security-groups-and-ssh-keys">Configuring Security Groups and SSH Keys</h2>
<p>To configure the security groups and SSH keys for our instances, follow these steps:</p>
<ol>
<li><p>Go to the Instances page on the EC2 dashboard and select one of your instances.</p>
</li>
<li><p>Click on Actions &gt; Networking &gt; Change Security Groups.</p>
</li>
<li><p>Select the security group that you created in the previous step and click on the Assign Security Groups button.</p>
</li>
<li><p>Repeat the same steps for the other instance.</p>
</li>
</ol>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696764092830/ea5fc0eb-e54f-4884-801f-0a9bd579c871.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully assigned the same security group to both instances.</p>
<ol>
<li>Go to your terminal and change the permissions of your key pair file by running:</li>
</ol>
<pre><code class="lang-bash">chmod 400 ~/.ssh/mykey.pem
</code></pre>
<p>Replace <code>~/.ssh/mykey.pem</code> with the path to your key pair file.</p>
<p>This will make sure that only you can read and write to your key pair file.</p>
<ol>
<li>SSH into one of your instances by running:</li>
</ol>
<pre><code class="lang-bash">ssh -i ~/.ssh/mykey.pem ubuntu@&lt;instance-ip&gt;
</code></pre>
<p>Replace <code>~/.ssh/mykey.pem</code> with the path to your key pair file and <code>&lt;instance-ip&gt;</code> with the public IPv4 address of your instance.</p>
<p>This will establish a secure connection to your instance using your key pair.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696764223306/340684c3-d566-4450-88ce-267ea5b7a925.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully logged into your instance.</p>
<ol>
<li>Repeat the same steps for the other instance.</li>
</ol>
<p>You should now have two terminals connected to your instances, one for the master node and one for the worker node.</p>
<p>You have successfully set up two AWS EC2 instances for our Kubernetes cluster. In the next section, we will install Kubernetes on these instances.</p>
<h1 id="heading-installing-kubernetes-on-aws-ec2-instances">Installing Kubernetes on AWS EC2 Instances</h1>
<p>In this section, we will install Kubernetes on both instances using <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code>. Kubeadm is a tool that helps us bootstrap a Kubernetes cluster. Kubelet is an agent that runs on each node and communicates with the master node. Kubectl is a command-line tool that allows us to interact with the cluster.</p>
<h2 id="heading-installing-docker-on-both-instances">Installing Docker on Both Instances</h2>
<p>Before we install Kubernetes, we need to install Docker on both instances. Docker is a software that allows us to run containers, which are isolated environments that contain our applications and their dependencies.</p>
<p>To install Docker on both instances, follow these steps:</p>
<ol>
<li>SSH into one of your instances by running:</li>
</ol>
<pre><code class="lang-bash">ssh -i ~/.ssh/mykey.pem ubuntu@&lt;instance-ip&gt;
</code></pre>
<p>Replace <code>~/.ssh/mykey.pem</code> with the path to your key pair file and <code>&lt;instance-ip&gt;</code> with the public IPv4 address of your instance.</p>
<ol>
<li>Update the package index by running:</li>
</ol>
<pre><code class="lang-bash">sudo apt update
</code></pre>
<ol>
<li>Install Docker by running:</li>
</ol>
<pre><code class="lang-bash">sudo apt install docker.io -y
</code></pre>
<ol>
<li>Start and enable the Docker service by running:</li>
</ol>
<pre><code class="lang-bash">sudo systemctl start docker
sudo systemctl <span class="hljs-built_in">enable</span> docker
</code></pre>
<ol>
<li>Verify that Docker is installed and running by running:</li>
</ol>
<pre><code class="lang-bash">sudo docker version
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696764601947/2b56cc44-cbbf-42e3-8c02-fc43b7e0ae7f.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully installed Docker on your instance.</p>
<ol>
<li>Add current user to the docker group</li>
</ol>
<pre><code class="lang-bash">sudo usermod -aG docker <span class="hljs-variable">$USER</span>
</code></pre>
<ol>
<li>Repeat the same steps for the other instance.</li>
</ol>
<p>You should now have Docker installed and running on both instances.</p>
<p>Try restarting your instances before proceeding further. This will make sure that the docker is installed and the current user is added to the docker group.</p>
<h2 id="heading-installing-kubeadm-kubelet-and-kubectl-on-both-instances">Installing <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code> on Both Instances</h2>
<p>To install <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code> on both instances, follow these steps:</p>
<ol>
<li>SSH into one of your instances by running:</li>
</ol>
<pre><code class="lang-bash">ssh -i ~/.ssh/mykey.pem ubuntu@&lt;instance-ip&gt;
</code></pre>
<p>Replace <code>~/.ssh/mykey.pem</code> with the path to your key pair file and <code>&lt;instance-ip&gt;</code> with the public IPv4 address of your instance.</p>
<ol>
<li>Add the Kubernetes apt repository by running:</li>
</ol>
<pre><code class="lang-bash">sudo apt update
sudo apt install apt-transport-https ca-certificates curl -y
curl -fsSL <span class="hljs-string">"https://packages.cloud.google.com/apt/doc/apt-key.gpg"</span> | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
<span class="hljs-built_in">echo</span> <span class="hljs-string">'deb https://packages.cloud.google.com/apt kubernetes-xenial main'</span> | sudo tee /etc/apt/sources.list.d/kubernetes.list
</code></pre>
<ol>
<li>Install <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code> by running:</li>
</ol>
<pre><code class="lang-bash">sudo apt update
sudo apt install kubeadm=1.20.0-00 kubectl=1.20.0-00 kubelet=1.20.0-00 -y
</code></pre>
<ol>
<li>Verify that <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code> are installed by running:</li>
</ol>
<pre><code class="lang-bash">kubeadm version
kubelet --version
kubectl version --client
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696765105427/0f2ef9d7-117d-45be-965f-8015feb0aadf.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully installed kubeadm, kubelet, and kubectl on your instance.</p>
<ol>
<li>Repeat the same steps for the other instance.</li>
</ol>
<p>You should now have <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code> installed on both instances.</p>
<h2 id="heading-initializing-the-master-node">Initializing the Master Node</h2>
<p>To initialize the master node, follow these steps:</p>
<ol>
<li>SSH into the instance that you want to use as the master node by running:</li>
</ol>
<pre><code class="lang-bash">ssh -i ~/.ssh/mykey.pem ubuntu@&lt;master-node-ip&gt;
</code></pre>
<p>Replace <code>~/.ssh/mykey.pem</code> with the path to your key pair file and <code>&lt;master-node-ip&gt;</code> with the public IPv4 address of your master node instance.</p>
<ol>
<li>Initialize the master node by running:</li>
</ol>
<pre><code class="lang-bash">sudo kubeadm init
</code></pre>
<p>This command will take some time to complete and will output a lot of information. At the end of the output, you should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696765417459/50075e77-82b8-40d1-92c1-d446d7490dd4.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully initialized the master node.</p>
<ol>
<li><p>Copy the join command that is displayed at the end of the output. You will need this command later to join the worker node to the cluster.</p>
</li>
<li><p>Configure your user account to use <code>kubectl</code> by running:</p>
</li>
</ol>
<pre><code class="lang-bash">mkdir -p <span class="hljs-variable">$HOME</span>/.kube
sudo cp -i /etc/kubernetes/admin.conf <span class="hljs-variable">$HOME</span>/.kube/config
sudo chown $(id -u):$(id -g) <span class="hljs-variable">$HOME</span>/.kube/config
</code></pre>
<p>This will create a <code>.kube</code> directory in your home directory and copy the cluster configuration file to it. This will allow you to use kubectl to interact with the cluster.</p>
<ol>
<li>Install a pod network add-on by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
</code></pre>
<p>This will install Flannel, a pod network add-on that provides a layer of networking for the pods in the cluster. Flannel will use the pod network CIDR that we specified earlier when initializing the master node.</p>
<ol>
<li><p>Generate a token for worker nodes to join:</p>
<pre><code class="lang-bash"> sudo kubeadm token create --print-join-command
</code></pre>
</li>
<li><p>Verify that the master node is ready by running:</p>
</li>
</ol>
<pre><code class="lang-bash">kubectl get nodes
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696765718322/8d597ba6-a88c-44d7-9cef-18d46ae19993.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one node in your cluster, which is the master node, and it is ready to run pods.</p>
<p>You have successfully initialized the master node. In the next section, we will join the worker node to the cluster.</p>
<h2 id="heading-joining-the-worker-node-to-the-cluster">Joining the Worker Node to the Cluster</h2>
<p>In this section, we will join the worker node to the cluster using the join command that we copied earlier from the master node. This will allow us to run pods on both nodes and distribute the workload.</p>
<p>To join the worker node to the cluster, follow these steps:</p>
<ol>
<li>SSH into the instance that you want to use as the worker node by running:</li>
</ol>
<pre><code class="lang-bash">ssh -i ~/.ssh/mykey.pem ubuntu@&lt;worker-node-ip&gt;
</code></pre>
<p>Replace <code>~/.ssh/mykey.pem</code> with the path to your key pair file and <code>&lt;worker-node-ip&gt;</code> with the public IPv4 address of your worker node instance.</p>
<ol>
<li><p>Run the following command</p>
<pre><code class="lang-bash"> sudo kubeadm reset pre-flight checks
</code></pre>
</li>
<li><p>Join the worker node to the cluster by running the join command that you copied from the master node. The command should look something like this:</p>
</li>
</ol>
<pre><code class="lang-bash">sudo kubeadm join 172.31.29.92:6443 --token thclqt.0m4dzsh5m6haswf5 --discovery-token-ca-cert-hash sha256:51bc85440423635ec77009514443330cfd2ff6292491dd33833e37406b34a8ba
</code></pre>
<p>Replace <code>&lt;master-node-ip&gt;</code> with the public IPv4 address of your master node instance, <code>&lt;token&gt;</code> with the token that was generated by kubeadm, and <code>&lt;hash&gt;</code> with the hash of the CA certificate.</p>
<p>This command will take some time to complete and will output some information. At the end of the output, you should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696767944180/203c74e0-2334-4081-9615-5aa323cc3b6b.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully joined the worker node to the cluster.</p>
<ol>
<li>Verify that the worker node is ready by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get nodes
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696768402866/48d09c04-f978-4c31-98af-f137babffbad.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have two nodes in your cluster, one master and one worker, and both are ready to run pods.</p>
<p>You have successfully joined the worker node to the cluster. In the next section, we will deploy a microservices application on Kubernetes.</p>
<h1 id="heading-deploying-the-microservices-application-on-kubernetes">Deploying the Microservices Application on Kubernetes</h1>
<p>In this section, we will deploy a microservices application on Kubernetes that consists of a MongoDB database and a taskmaster service. The taskmaster service is a web app that allows you to create and manage tasks. The app is written in Node.js and uses MongoDB as the database.</p>
<p>To deploy the microservices application on Kubernetes, follow these steps:</p>
<h2 id="heading-cloning-the-github-repositories">Cloning the GitHub Repositories</h2>
<p>To clone the GitHub repositories that contain the source code and the configuration files for our microservices application, follow these steps:</p>
<ol>
<li>SSH into the master node by running:</li>
</ol>
<pre><code class="lang-bash">ssh -i ~/.ssh/mykey.pem ubuntu@&lt;master-node-ip&gt;
</code></pre>
<p>Replace <code>~/.ssh/mykey.pem</code> with the path to your key pair file and <code>&lt;master-node-ip&gt;</code> with the public IPv4 address of your master node instance.</p>
<ol>
<li>Install git by running:</li>
</ol>
<pre><code class="lang-bash">sudo apt install git -y
</code></pre>
<ol>
<li>Clone the repository that contains the configuration files for our MongoDB database by running:</li>
</ol>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/ajitfawade/microservices-k8s.git
</code></pre>
<p>This will create a directory named <code>microservices-k8s</code> in your current directory.</p>
<h2 id="heading-deploying-the-persistent-volume-and-persistent-volume-claim">Deploying the Persistent Volume and Persistent Volume Claim</h2>
<p>To deploy the persistent volume and persistent volume claim for our MongoDB database, follow these steps:</p>
<ol>
<li>Go to the <code>mongodb-k8s</code> directory by running:</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> microservices-k8s/flask-api/k8s
</code></pre>
<ol>
<li>Apply the YAML file that defines the persistent volume by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f mongo-pv.yml
</code></pre>
<p>This will create a persistent volume object named <code>mongodb-pv</code> that allocates 1 GB of storage on the host path <code>/data/mongodb</code>.</p>
<ol>
<li>Apply the YAML file that defines the persistent volume claim by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f mongo-pvc.yml
</code></pre>
<p>This will create a persistent volume claim object named <code>mongodb-pvc</code> that requests 1 GB of storage from the persistent volume.</p>
<ol>
<li>Verify that the persistent volume and persistent volume claim are created and bound by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get pv,pvc
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696768763519/d3587c7f-b5fd-4462-8e4b-28f43c315b8b.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one persistent volume named <code>mongo-pv</code> and one persistent volume claim named <code>mongo-pvc</code>.</p>
<p>You have successfully deployed the persistent volume and persistent volume claim for our MongoDB database. In the next section, we will deploy the MongoDB database itself.</p>
<h2 id="heading-deploying-the-mongodb-database">Deploying the MongoDB Database</h2>
<p>To deploy the MongoDB database for our microservices application, follow these steps:</p>
<ol>
<li>Apply the YAML file that defines the deployment by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f mongo.yml
</code></pre>
<p>This will create a deployment object named <code>mongo-deployment</code> that creates one replica of a pod that runs the <code>mongo:4.4.6</code> image. The deployment has the label <code>app: mongodb</code>. The pod mounts the persistent volume claim <code>mongodb-pvc</code> to the path <code>/data/db</code> and uses the secret <code>mongodb-secret</code> to set the environment variables <code>MONGO_INITDB_ROOT_USERNAME</code> and <code>MONGO_INITDB_ROOT_PASSWORD</code>.</p>
<ol>
<li>Verify that the deployment is created and running by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get deployments
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696769051475/c82ab7d8-8e0b-4f5a-8ba6-0de0e87e203f.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one deployment named <code>mongo</code> that has one replica ready and up-to-date.</p>
<ol>
<li>Verify that the pod is running by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get pods
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696769085560/a368b7aa-c64d-41ea-b92b-10d5583c7d11.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one pod named <code>mongodb-786f4cb565-9tmrs</code> that is running and ready.</p>
<p>You have successfully deployed the MongoDB database for our microservices application. In the next section, we will deploy the ClusterIP service for MongoDB.</p>
<h2 id="heading-deploying-the-clusterip-service-for-mongodb">Deploying the ClusterIP Service for MongoDB</h2>
<p>To deploy the ClusterIP Service for MongoDB, follow these steps:</p>
<ol>
<li>Apply the YAML file that defines the service by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f mongo-svc.yml
</code></pre>
<p>This will create a service object named <code>mongo</code> that exposes port 27017 of our pods as port 27017 on an internal IP address. The service selects the pods that have the label <code>app: mongo</code>. The <code>type: ClusterIP</code> specifies that this is a ClusterIP Service.</p>
<ol>
<li>Verify that the service is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get services
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696769351347/5bb817a3-7056-49b6-95fb-a01cfd8ae269.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one ClusterIP Service named <code>mongo</code> that exposes port 27017 of your pods as port 27017 on an internal IP address <code>10.101.9.108</code>.</p>
<p>You have successfully deployed the ClusterIP Service for MongoDB. This will allow our taskmaster service to communicate with our MongoDB database within the cluster. In the next section, we will deploy the taskmaster service itself.</p>
<h2 id="heading-deploying-the-taskmaster-service">Deploying the Taskmaster Service</h2>
<p>To deploy the taskmaster service for our microservices application, follow these steps:</p>
<ol>
<li>Apply the YAML file that defines the deployment by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f taskmaster.yml
</code></pre>
<p>This will create a deployment object named <code>taskmaster-deployment</code> that creates two replicas of pods that run the <code>ajitfawade14/first-repo</code> image. The deployment has the label <code>app: taskmaster</code>. The pods use the environment variable <code>MONGO_URL</code> to connect to the MongoDB database via the ClusterIP Service <code>mongodb-service</code>.</p>
<ol>
<li>Verify that the deployment is created and running by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get deployments
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696769610176/f119f7de-1d29-43d7-8231-954b71a996b8.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one deployment named <code>taskmaster-deployment</code> that has two replicas ready and up-to-date.</p>
<ol>
<li>Verify that the pods are running by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get pods
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696769644405/209cea1b-23f4-43d0-9763-513f394f8c52.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have two pods named <code>taskmaster-&lt;random-string&gt;</code> that are running and ready.</p>
<p>You have successfully deployed the taskmaster service for our microservices application. In the next section, we will deploy the NodePort Service for taskmaster. This will allow us to access our web app from outside the cluster.</p>
<h2 id="heading-deploying-the-nodeport-service-for-taskmaster">Deploying the NodePort Service for Taskmaster</h2>
<p>To deploy the NodePort Service for taskmaster, follow these steps:</p>
<ol>
<li>Apply the YAML file that defines the service by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f taskmaster-svc.yml
</code></pre>
<p>This will create a service object named <code>taskmaster</code> that exposes port 5000 of our pods as port 30007 on each node’s IP address. The service selects the pods that have the label <code>app: taskmaster</code>. The <code>type: NodePort</code> specifies that this is a NodePort Service.</p>
<ol>
<li>Verify that the service is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get services
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696769949375/edb88007-7cce-4c5b-b448-a9656022cf6b.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one NodePort Service named <code>taskmaster</code> that exposes port 5000 of your pods as port 30007 on each node’s IP address.</p>
<ol>
<li>Access the taskmaster web app from your browser by going to http://&lt;node-ip&gt;:30007/. You can use any node’s IP address, either the master or the worker. You should see something like this:</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696770048618/08f4924a-3e0c-4bfd-8a48-567edcb4cc4b.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully accessed your taskmaster web app via the NodePort Service from outside your cluster.</p>
<p>You have successfully deployed the NodePort Service for taskmaster. This completes our microservices application deployment on Kubernetes.</p>
<h2 id="heading-summary-and-conclusion">Summary and Conclusion</h2>
<p>In this blog post, we learned how to deploy a microservices application on AWS EC2 using Kubernetes, which is a popular platform for managing containerized applications. We covered the following topics:</p>
<ul>
<li><p>Setting up AWS EC2 Instances: We created two <code>t2.medium</code> instances on AWS EC2, one for the master node and one for the worker node. We also configured the security groups and SSH keys for these instances.</p>
</li>
<li><p>Installing Kubernetes on AWS EC2 Instances: We installed Kubernetes on both instances using <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code>. We also initialized the master node and joined the worker node to the cluster.</p>
</li>
<li><p>Deploying the Microservices Application on Kubernetes: We deployed a microservices application that consists of a MongoDB database and a taskmaster service. The taskmaster service is a web app that allows us to create and manage tasks. The app is written in Node.js and uses MongoDB as the database. We deployed the persistent volume and persistent volume claim, the MongoDB database, the ClusterIP service for MongoDB, the taskmaster service, and the NodePort service for taskmaster.</p>
</li>
</ul>
<p>By the end of this blog post, we had a working microservices application running on AWS EC2 using Kubernetes. We also learned some important concepts and commands related to Kubernetes, such as pods, services, deployments, etc.</p>
<p>I hope you enjoyed this blog post and learned something new. If you have any questions or feedback, please feel free to leave a comment below.</p>
<p>If you want to follow my journey of learning DevOps, you can check out my <a target="_blank" href="https://github.com/ajitfawade">GitHub</a> and my <a target="_blank" href="https://www.linkedin.com/in/ajitfawade/">LinkedIn</a> profile.</p>
<p>Thank you for reading and stay tuned for more!</p>
]]></content:encoded></item><item><title><![CDATA[Working with Services in Kubernetes | Day 34 of 90 Days of DevOps]]></title><description><![CDATA[Welcome to Day 34 of 90 Days of DevOps.
Today, we will learn how to work with Services in Kubernetes, a key concept that allows us to expose and access our applications in a cluster. We will also deploy and manage different types of Services for our ...]]></description><link>https://blog.ajitfawade.com/working-with-services-in-kubernetes</link><guid isPermaLink="true">https://blog.ajitfawade.com/working-with-services-in-kubernetes</guid><category><![CDATA[Devops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[kubernetes-services]]></category><category><![CDATA[kubernetesservice]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Sun, 01 Oct 2023 17:03:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1696178243222/2715ee05-4a3f-4529-acf7-af4018005228.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome to Day 34 of 90 Days of DevOps.</p>
<p>Today, we will learn how to work with Services in Kubernetes, a key concept that allows us to expose and access our applications in a cluster. We will also deploy and manage different types of Services for our sample ToDo app that we created on <a target="_blank" href="https://blog.ajitfawade.com/launching-your-kubernetes-cluster-with-deployment">Day 32</a>.</p>
<p>By the end of this blog post, you will be able to:</p>
<ul>
<li><p>Understand what Services are and how they work in Kubernetes</p>
</li>
<li><p>Create and delete Services using kubectl</p>
</li>
<li><p>Deploy a Service for your ToDo app Deployment</p>
</li>
<li><p>Create a ClusterIP Service for internal cluster access</p>
</li>
<li><p>Create a LoadBalancer Service for external access</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-understanding-services-in-kubernetes">Understanding Services in Kubernetes</h2>
<p>Services are an abstraction that defines a logical set of Pods and a policy to access them. Services allow us to expose our Pods to other Pods within the cluster or to external clients outside the cluster.</p>
<p>Services are useful for:</p>
<ul>
<li><p>Providing a stable and reliable way of accessing our Pods, regardless of their location or status</p>
</li>
<li><p>Load balancing the traffic among our Pods, distributing the requests evenly, and avoiding overloading</p>
</li>
<li><p>Discovering our Pods dynamically, using DNS or environment variables</p>
</li>
</ul>
<p>There are four types of Services in Kubernetes:</p>
<ul>
<li><p><code>ClusterIP</code>: This is the default type of Service that exposes our Pods within the cluster using an internal IP address. This type of Service is only accessible from within the cluster.</p>
</li>
<li><p><code>NodePort</code>: This type of Service exposes our Pods on each node’s IP address using a static port. This type of Service is accessible from outside the cluster using <code>&lt;node-ip&gt;:&lt;node-port&gt;</code>.</p>
</li>
<li><p><code>LoadBalancer</code>: This type of Service exposes our Pods using an external load balancer provided by our cloud provider or platform. This type of Service is accessible from outside the cluster using <code>&lt;load-balancer-ip&gt;:&lt;port&gt;</code>.</p>
</li>
<li><p><code>ExternalName</code>: This type of Service maps our Pods to an external domain name using a CNAME record. This type of Service does not have any selectors or ports.</p>
</li>
</ul>
<h2 id="heading-creating-and-managing-services">Creating and Managing Services</h2>
<p>In this section, we will create and manage different types of Services for our sample ToDo app that we deployed on <a target="_blank" href="https://blog.ajitfawade.com/launching-your-kubernetes-cluster-with-deployment">Day 32</a>. We will use <code>kubectl</code>, the command-line tool that interacts with Kubernetes clusters, to perform various operations on our resources.</p>
<h3 id="heading-creating-a-service-for-your-todo-app-deployment">Creating a Service for your ToDo app Deployment</h3>
<p>On <a target="_blank" href="https://blog.ajitfawade.com/launching-your-kubernetes-cluster-with-deployment">Day 32</a>, we deployed a ToDo app on Kubernetes using Deployment. The ToDo app is a simple web app that allows us to create and manage tasks. We used the Docker image <code>ajitfawade14/node-todo-app</code> as the source for our app.</p>
<p>To create a Service for our ToDo app Deployment, follow these steps:</p>
<ol>
<li>Create a YAML file named <code>service.yml</code> with the following content:</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">todo-service</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">todo</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">todo</span>
  <span class="hljs-attr">ports:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
      <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
      <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8000</span>
</code></pre>
<p>This file defines a Service object named <code>todo-service</code> that exposes port 80 of our Pods as port 8000 on an internal IP address. The Service belongs to the <code>todo</code> Namespace and select the Pods that have the label <code>app: todo</code>.</p>
<ol>
<li>Apply the YAML file to create the Service by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f service.yml -n todo
</code></pre>
<p>The <code>-n</code> flag specifies the Namespace that we want to create the Service in.</p>
<p>This will create the Service and assign it an internal IP address.</p>
<ol>
<li>Verify that the Service is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get services -n todo
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696175118020/76954024-1dd9-4441-ac5b-dfffa0fd63da.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one Service named <code>todo-service</code> that exposes port 80 of your Pods as port 8000 on an internal IP address <code>10.96.230.136</code> in the <code>todo</code> Namespace.</p>
<ol>
<li>Access the ToDo app from your browser by going to http://&lt;internal-ip&gt;:8000/.</li>
</ol>
<p>This shows that you have successfully accessed your ToDo app via the Service within your Namespace.</p>
<h3 id="heading-creating-a-clusterip-service-for-internal-cluster-access">Creating a ClusterIP Service for internal cluster access</h3>
<p>A ClusterIP Service is the default type of Service that exposes our Pods within the cluster using an internal IP address. This type of Service is only accessible from within the cluster.</p>
<p>To create a ClusterIP Service for our ToDo app Deployment, follow these steps:</p>
<ol>
<li>Create a YAML file named <code>cluster-ip-service.yml</code> with the following content:</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">todo-cluster-ip-service</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">todo</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">ClusterIP</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">todo</span>
  <span class="hljs-attr">ports:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
      <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
      <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8000</span>
</code></pre>
<p>This file defines a Service object named <code>todo-cluster-ip-service</code> that exposes port 80 of our Pods as port 8000 on an internal IP address. The Service belongs to the <code>todo</code> Namespace and select the Pods that have the label <code>app: todo</code>. The <code>type: ClusterIP</code> specifies that this is a ClusterIP Service.</p>
<ol>
<li>Apply the YAML file to create the Service by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f cluster-ip-service.yml -n todo
</code></pre>
<p>This will create the Service and assign it an internal IP address.</p>
<ol>
<li>Verify that the Service is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get services -n todo
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696175599918/53669e11-105b-4ce0-99f0-e4931f351f9b.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one ClusterIP Service named <code>todo-cluster-ip-service</code> that exposes port 80 of your Pods as port 8000 on an internal IP address <code>10.96.249.227</code> in the <code>todo</code> Namespace.</p>
<ol>
<li>Access the ToDo app from another Pod within the cluster by running:</li>
</ol>
<pre><code class="lang-bash">kubectl run -it --rm curl --image=curlimages/curl -- sh
</code></pre>
<p>This will create a temporary Pod named <code>curl</code> that runs a shell in an interactive mode.</p>
<p>In the shell, run the following command:</p>
<pre><code class="lang-bash">curl http://todo-cluster-ip-service.todo.svc.cluster.local
</code></pre>
<p>This will send a request to the ClusterIP Service using its DNS name, which consists of <code>&lt;service-name&gt;.&lt;namespace-name&gt;.svc.cluster.local</code>.</p>
<p>This shows that you have successfully accessed your ToDo app via the ClusterIP Service from another Pod within your Namespace.</p>
<p>To exit the shell, press Ctrl+D.</p>
<h3 id="heading-creating-a-loadbalancer-service-for-external-access">Creating a LoadBalancer Service for external access</h3>
<p>A LoadBalancer Service is a type of Service that exposes our Pods using an external load balancer provided by our cloud provider or platform. This type of Service is accessible from outside the cluster.</p>
<p>To create a LoadBalancer Service for our ToDo app Deployment, follow these steps:</p>
<ol>
<li>Create a YAML file named <code>load-balancer-service.yml</code> with the following content:</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">todo-load-balancer-service</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">todo</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">LoadBalancer</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">todo</span>
  <span class="hljs-attr">ports:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
      <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
      <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8000</span>
</code></pre>
<p>This file defines a Service object named <code>todo-load-balancer-service</code> that exposes port 80 of our Pods as port 8000 on an external IP address. The Service belongs to the <code>todo</code> Namespace and select the Pods that have the label <code>app: todo</code>. The <code>type: LoadBalancer</code> specifies that this is a LoadBalancer Service.</p>
<ol>
<li>Apply the YAML file to create the Service by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f load-balancer-service.yml -n todo
</code></pre>
<p>This will create the Service and assign it an external IP address.</p>
<ol>
<li>Verify that the Service is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get services -n todo
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696176009070/dbc31958-0248-470b-868b-ee31a2ffa820.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one LoadBalancer Service named <code>todo-load-balancer-service</code> that exposes port 80 of your Pods as port 80 on an external IP address <code>192.168.49.2</code> in the <code>todo</code> Namespace.</p>
<ol>
<li>Access the ToDo app from your browser by going to http://&lt;external-ip&gt;:80/. You should see something like this:</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696176106307/4054d2ea-8b38-4c04-a1cd-5427b48eb709.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have successfully accessed your ToDo app via the LoadBalancer Service from outside your cluster.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, we learned how to work with Services in Kubernetes, a key concept that allows us to expose and access our applications in a cluster. We also deployed and managed different types of Services for our sample ToDo app that we created on <a target="_blank" href="https://blog.ajitfawade.com/launching-your-kubernetes-cluster-with-deployment">Day 32</a>.</p>
<p>I hope you enjoyed this blog post and learned something new. If you have any questions or feedback, please feel free to leave a comment below.</p>
<p>If you want to follow my journey of learning DevOps, you can check out my <a target="_blank" href="https://github.com/ajitfawade">GitHub</a> and my <a target="_blank" href="https://www.linkedin.com/in/ajitfawade/">LinkedIn</a> profile.</p>
<p>Thank you for reading and stay tuned for more!</p>
]]></content:encoded></item><item><title><![CDATA[Mastering Namespaces and Services in Kubernetes | Day 33 of 90 Days of DevOps]]></title><description><![CDATA[Welcome to Day 33 of 90 Days of DevOps.
Today, we will learn how to master Namespaces and Services in Kubernetes, two important concepts that help us organize and expose our applications in a cluster.
We will also deploy a sample Nginx web server wit...]]></description><link>https://blog.ajitfawade.com/mastering-namespaces-and-services-in-kubernetes</link><guid isPermaLink="true">https://blog.ajitfawade.com/mastering-namespaces-and-services-in-kubernetes</guid><category><![CDATA[Devops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[Kubernetes namespaces]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Wed, 27 Sep 2023 03:48:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1695785700906/11aaa7a1-e7af-4db2-8bfc-adb26466567d.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome to Day 33 of 90 Days of DevOps.</p>
<p>Today, we will learn how to master Namespaces and Services in Kubernetes, two important concepts that help us organize and expose our applications in a cluster.</p>
<p>We will also deploy a sample Nginx web server within a Namespace and expose it as a Service.</p>
<p>By the end of this blog post, you will be able to:</p>
<ul>
<li><p>Understand what Namespaces and Services are and why they are useful</p>
</li>
<li><p>Create and delete Namespaces and Services using kubectl</p>
</li>
<li><p>Deploy a sample Nginx web server within a Namespace</p>
</li>
<li><p>Expose and access the web server as a Service</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-understanding-namespaces-and-services-in-kubernetes">Understanding Namespaces and Services in Kubernetes</h2>
<p>Namespaces and Services are two fundamental concepts in Kubernetes that help us manage the complexity and scalability of our applications. Let’s see what they are and how they work.</p>
<h3 id="heading-what-is-a-namespace">What is a Namespace?</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695784788095/1249cc0e-7319-47ef-9be2-8ceb0edee31c.png" alt class="image--center mx-auto" /></p>
<p>A Namespace is a logical grouping of resources within a Kubernetes cluster. A Namespace provides a scope for names, meaning that resources can have the same name as long as they belong to different Namespaces. A Namespace also isolates resources from each other, meaning that resources in one Namespace cannot see or access resources in another Namespace, unless explicitly allowed.</p>
<p>Namespaces are useful for:</p>
<ul>
<li><p>Organizing your cluster into logical units, such as teams, projects, environments, etc.</p>
</li>
<li><p>Sharing your cluster resources among multiple users or groups, with different access levels and quotas</p>
</li>
<li><p>Avoiding name conflicts for resources that have common names, such as pods, services, deployments, etc.</p>
</li>
</ul>
<p>By default, every Kubernetes cluster has three Namespaces:</p>
<ul>
<li><p><code>default</code>: This is the default Namespace where your resources are created if you don’t specify any other Namespace.</p>
</li>
<li><p><code>kube-system</code>: This is the Namespace where the system components of Kubernetes are created and managed, such as the API server, the scheduler, the controller manager, etc.</p>
</li>
<li><p><code>kube-public</code>: This is the Namespace that is readable by all users (including unauthenticated ones) and is mostly reserved for cluster usage, such as exposing the cluster information.</p>
</li>
</ul>
<p>You can create your own custom Namespaces to suit your needs and preferences.</p>
<h3 id="heading-what-is-a-service">What is a Service?</h3>
<p>A Service is an abstraction that defines a logical set of Pods and a policy to access them. A Service allows you to expose your Pods to other Pods within the cluster or to external clients outside the cluster.</p>
<p>A Service is useful for:</p>
<ul>
<li><p>Providing a stable and reliable way of accessing your Pods, regardless of their location or status</p>
</li>
<li><p>Load balancing the traffic among your Pods, distributing the requests evenly and avoiding overloading</p>
</li>
<li><p>Discovering your Pods dynamically, using DNS or environment variables</p>
</li>
</ul>
<p>There are four types of Services in Kubernetes:</p>
<ul>
<li><p><code>ClusterIP</code>: This is the default type of Service that exposes your Pods within the cluster using an internal IP address. This type of Service is only accessible from within the cluster.</p>
</li>
<li><p><code>NodePort</code>: This type of Service exposes your Pods on each node’s IP address using a static port. This type of Service is accessible from outside the cluster using <code>&lt;node-ip&gt;:&lt;node-port&gt;</code>.</p>
</li>
<li><p><code>LoadBalancer</code>: This type of Service exposes your Pods using an external load balancer provided by your cloud provider or platform. This type of Service is accessible from outside the cluster using <code>&lt;load-balancer-ip&gt;:&lt;port&gt;</code>.</p>
</li>
<li><p><code>ExternalName</code>: This type of Service maps your Pods to an external domain name using a CNAME record. This type of Service does not have any selectors or ports.</p>
</li>
</ul>
<h2 id="heading-practical-guide-deploying-nginx-within-a-namespace">Practical Guide: Deploying Nginx within a Namespace</h2>
<p>In this section, we will deploy a sample Nginx web server within a Kubernetes Namespace and expose it as a Service. We will use <code>kubectl</code>, the command-line tool that interacts with Kubernetes clusters, to perform various operations on our resources.</p>
<p>To deploy Nginx within a Namespace, follow these steps:</p>
<ol>
<li><p>Create a namespace before creating the manifest file.</p>
<pre><code class="lang-bash"> kubectl create namespace nginx
</code></pre>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695784298159/e14d37a1-4dae-4eb8-9fac-f061d42a2bd8.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Create a YAML file named <code>deployment.yml</code> with the following content:</p>
</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">nginx-deployment</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">nginx</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">nginx</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">3</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">nginx</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">namespace:</span> <span class="hljs-string">nginx</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">nginx</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span>
          <span class="hljs-attr">image:</span> <span class="hljs-string">nginx:latest</span>
          <span class="hljs-attr">ports:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">80</span>
</code></pre>
<p>This file defines a Deployment object named <code>nginx-deployment</code> that creates three replicas of Pods that run the <code>nginx:latest</code> image. The Deployment belongs to the <code>nginx</code> Namespace and has the label <code>app: nginx</code>. The Pods expose port 80 for the web server.</p>
<ol>
<li>Apply the YAML file to create the Deployment by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f deployment.yml
</code></pre>
<p>This will create the Deployment and its associated ReplicaSet and Pods.</p>
<ol>
<li>Verify that the Deployment is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get deployments -n nginx
</code></pre>
<p>The <code>-n</code> flag specifies the Namespace that we want to query.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695784270367/9cffc79c-4909-4083-a622-5762713a5dc0.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one Deployment named <code>nginx-deployment</code> that has three replicas ready and up-to-date in the <code>nginx</code> Namespace.</p>
<ol>
<li>Verify that the Pods are running by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get pods -n nginx
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695784256006/55c6ec9b-70c9-4ec2-b581-20dd8ad858d9.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have three Pods named <code>nginx-deployment-&lt;random-string&gt;</code> that are running and ready in the <code>nginx</code> Namespace.</p>
<ol>
<li>Expose the Pods as a Service by running:</li>
</ol>
<pre><code class="lang-bash">kubectl expose deployment nginx-deployment -n nginx --port=80 --<span class="hljs-built_in">type</span>=LoadBalancer
</code></pre>
<p>This will create a Service object named <code>nginx-deployment</code> that exposes port 80 of the Pods as a LoadBalancer service in the <code>nginx</code> Namespace. A LoadBalancer service allocates an external IP address and routes traffic from that IP address to the Pods.</p>
<ol>
<li>Verify that the Service is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get services -n nginx
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695784236742/c4f77ad4-a14a-46f3-ba05-a76af7996b43.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one Service named <code>nginx-deployment</code> that exposes port 80 of the Pods as port 80 on an external IP address in the <code>nginx</code> Namespace.</p>
<ol>
<li>Access the Nginx web server from your browser by going to http://&lt;external-ip&gt;:&lt;servicePort&gt;/. You should see something like this:</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695784218332/88c5a756-06f3-49c2-9dca-297c1021cc0e.png" alt class="image--center mx-auto" /></p>
<p>Congratulations! You have successfully deployed a sample Nginx web server within a Kubernetes Namespace and exposed it as a Service.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, we learned how to master Namespaces and Services in Kubernetes, two important concepts that help us organize and expose our applications in a cluster. We also deployed a sample Nginx web server within a Namespace and exposed it as a Service.</p>
<p>I hope you enjoyed this blog post and learned something new. If you have any questions or feedback, please feel free to leave a comment below.</p>
<p>If you want to follow my journey of learning DevOps, you can check out my <a target="_blank" href="https://github.com/ajitfawade">GitHub</a> profile and my <a target="_blank" href="https://www.linkedin.com/in/ajitfawade/">LinkedIn</a> profile.</p>
<p>Thank you for reading and stay tuned for more!</p>
]]></content:encoded></item><item><title><![CDATA[Launching Your Kubernetes Cluster with Deployment | Day 32 of 90 Days of DevOps]]></title><description><![CDATA[Welcome to Day 32 of 90 Days of DevOps.
Today, we will learn how to launch a Kubernetes cluster with Deployment, a configuration that allows us to manage updates to Pods and ReplicaSets. We will also deploy a sample ToDo application on Kubernetes usi...]]></description><link>https://blog.ajitfawade.com/launching-your-kubernetes-cluster-with-deployment</link><guid isPermaLink="true">https://blog.ajitfawade.com/launching-your-kubernetes-cluster-with-deployment</guid><category><![CDATA[#90daysofdevops]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[deployment]]></category><category><![CDATA[autoscaling]]></category><dc:creator><![CDATA[Ajit Fawade]]></dc:creator><pubDate>Sun, 17 Sep 2023 02:40:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694747523839/fe7dbb00-a151-4f4c-b527-4174a4c44277.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome to Day 32 of 90 Days of DevOps.</p>
<p>Today, we will learn how to launch a Kubernetes cluster with Deployment, a configuration that allows us to manage updates to Pods and ReplicaSets. We will also deploy a sample ToDo application on Kubernetes using the auto-healing and auto-scaling features.</p>
<p>By the end of this blog post, you will be able to:</p>
<ul>
<li><p>Understand what Kubernetes Deployments are and why they are useful</p>
</li>
<li><p>Deploy a sample ToDo application on Kubernetes using Deployment</p>
</li>
<li><p>Use <code>kubectl</code> to inspect and manage the Deployment</p>
</li>
<li><p>Enable auto-healing and auto-scaling for the Deployment</p>
</li>
</ul>
<p>Let’s get started!</p>
<h2 id="heading-understanding-kubernetes-deployments">Understanding Kubernetes Deployments</h2>
<p>A Deployment in Kubernetes provides a configuration for managing updates to Pods and ReplicaSets. A Pod is a group of one or more containers that share the same network namespace and storage volumes. A ReplicaSet is a controller that ensures that a specified number of Pods are running at any given time.</p>
<p>A Deployment allows you to describe the desired state of your application, such as the number of replicas, the image version, the update strategy, etc. The Deployment Controller ensures that the actual state matches this desired state, typically at a controlled rate. For example, you can use a Deployment to roll out a new version of your application without downtime or to roll back to a previous version if something goes wrong.</p>
<p>Deployments are useful for scaling by creating new replicas or replacing existing ones while maintaining high availability. You can also use Deployments to enable auto-healing and auto-scaling for your application, which we will see later in this post.</p>
<h2 id="heading-practical-application-deploying-a-sample-todo-app">Practical Application - Deploying a Sample ToDo App</h2>
<p>In this section, we will deploy a sample ToDo application on Kubernetes using Deployment. The ToDo application is a simple web app that allows you to create and manage tasks. The app is written in Node.js. We will use the Docker image <code>ajitfawade14/first-repo</code> as the source for our app.</p>
<p>To deploy the sample ToDo app on Kubernetes using Deployment, follow these steps:</p>
<ol>
<li>Create a YAML file named <code>deployment.yml</code> with the following content:</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">todo-app</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">todo</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">todo</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">todo</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">todo</span>
        <span class="hljs-attr">image:</span> <span class="hljs-string">rishikeshops/todo-app</span>
        <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">3000</span>
</code></pre>
<p>This file defines a Deployment object named <code>todo-app</code> that creates two replicas of Pods that run the <code>ajitfawade14/first-repo</code> image. The Pods expose port 3000 for the web server.</p>
<ol>
<li>Apply the YAML file to create the Deployment by running:</li>
</ol>
<pre><code class="lang-bash">kubectl apply -f deployment.yml
</code></pre>
<p>This will create the Deployment and its associated ReplicaSet and Pods.</p>
<ol>
<li>Verify that the Deployment is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get deployments
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694889179063/3ef1b806-7e89-4ef7-8fb9-efc7d3e10b10.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have one Deployment named <code>todo-app</code> that has two replicas ready and up-to-date.</p>
<ol>
<li>Verify that the Pods are running by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get pods
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694889110096/83a3391c-ca06-4b0c-8d1a-1b0fbc984f87.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have two Pods named <code>todo-app-&lt;random-string&gt;</code> that are running and ready.</p>
<ol>
<li>Expose the Pods as a Service by running:</li>
</ol>
<pre><code class="lang-bash">kubectl expose deployment todo-app --port=80 --<span class="hljs-built_in">type</span>=LoadBalancer
</code></pre>
<p>This will create a Service object named <code>todo-app</code> that exposes port 80 of the Pods as a LoadBalancer service. A LoadBalancer service allocates an external IP address and routes traffic from that IP address to the Pods.</p>
<ol>
<li>Verify that the Service is created by running:</li>
</ol>
<pre><code class="lang-bash">kubectl get services
</code></pre>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694889257256/3c15a431-7a7e-4a88-93d2-6bcadbdbf531.png" alt class="image--center mx-auto" /></p>
<p>This shows that you have two Services in your cluster: the <code>kubernetes</code> service, which is the default service for the cluster API, and the <code>todo-app</code> service, which exposes port 80 of the Pods as port 3000 on an external IP address.</p>
<ol>
<li>Access the ToDo app from your browser by going to http://&lt;external-ip&gt;:3000/.</li>
</ol>
<p>Congratulations! You have successfully deployed a sample ToDo app on Kubernetes using Deployment.</p>
<h2 id="heading-using-kubectl-to-inspect-and-manage-the-deployment">Using <code>kubectl</code> to Inspect and Manage the Deployment</h2>
<p>In this section, we will use <code>kubectl</code> to inspect and manage the Deployment that we created in the previous section. <code>kubectl</code> is a command-line tool that allows you to interact with Kubernetes clusters and perform various operations on them.</p>
<p>To use <code>kubectl</code> to inspect and manage the Deployment, follow these steps:</p>
<ol>
<li>Get the details of the Deployment by running:</li>
</ol>
<pre><code class="lang-bash">kubectl describe deployment todo-app
</code></pre>
<p>This will show you the information about the Deployment, such as the labels, the replicas, the selector, the template, the update strategy, the conditions, the events, etc.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694814293992/ac5242a9-5e41-40dd-a88a-7072ae115b1b.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Get the details of the Pods by running:</li>
</ol>
<pre><code class="lang-bash">kubectl describe pods -l app=todo
</code></pre>
<p>This will show you the information about the Pods that belong to the Deployment, such as the labels, the status, the containers, the volumes, the events, etc.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694890902480/321cc702-4455-4151-b0bc-30257a4dbee6.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Get the logs of a Pod by running:</li>
</ol>
<pre><code class="lang-bash">kubectl logs &lt;pod-name&gt;
</code></pre>
<p>Replace <code>&lt;pod-name&gt;</code> with the name of one of the Pods that you want to see the logs of.</p>
<p>This will show you the output of the container running in the Pod.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694891026012/7f0db25f-5d3f-4ccc-90e9-427ce970a860.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Execute a command in a Pod by running:</li>
</ol>
<pre><code class="lang-bash">kubectl <span class="hljs-built_in">exec</span> -it &lt;pod-name&gt; -- &lt;<span class="hljs-built_in">command</span>&gt;
</code></pre>
<p>Replace <code>&lt;pod-name&gt;</code> with the name of one of the Pods that you want to execute a command in, and <code>&lt;command&gt;</code> with the command that you want to execute.</p>
<p>This will open an interactive shell in the container running in the Pod and execute the command.</p>
<p>For example, you can run <code>kubectl exec -it todo-app-&lt;random-string&gt; -- sh</code> to open a bash shell in one of the Pods.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694891143303/2e813075-1645-48cf-9f54-4f4056997f2d.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Scale up or down the number of replicas by running:</li>
</ol>
<pre><code class="lang-bash">kubectl scale deployment todo-app --replicas=&lt;number&gt;
</code></pre>
<p>Replace <code>&lt;number&gt;</code> with the desired number of replicas that you want to have.</p>
<p>This will update the Deployment and create or delete Pods accordingly.</p>
<p>For example, you can run <code>kubectl scale deployment todo-app --replicas=3</code> to increase the number of replicas to 3.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694891210120/9bd8b355-ae7e-46ce-9c65-e3ddd0773207.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Update the image version by running:</li>
</ol>
<pre><code class="lang-bash">kubectl <span class="hljs-built_in">set</span> image deployment todo-app todo=&lt;new-image&gt;
</code></pre>
<p>Replace <code>&lt;new-image&gt;</code> with the name of the new image that you want to use.</p>
<p>This will update the Deployment and create a new ReplicaSet that uses the new image. The old ReplicaSet will be scaled down and eventually deleted.</p>
<p>For example, you can run <code>kubectl set image deployment todo-app todo=ajitfawade14/first-repo:v2</code> to use a new version of your image.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694891300610/c4fbac9f-fafc-4fc8-b652-e33c730c512c.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Roll back to a previous version by running:</li>
</ol>
<pre><code class="lang-bash">kubectl rollout undo deployment todo-app
</code></pre>
<p>This will undo the last update that was made to the Deployment and restore it to its previous state.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694891386180/be2b8b50-32d1-414a-9ed7-7c44dea20eae.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-enabling-auto-healing-and-auto-scaling-for-the-deployment">Enabling Auto-Healing and Auto-Scaling for the Deployment</h2>
<p>In this section, we will enable auto-healing and auto-scaling for our Deployment. Auto-healing is a feature that allows Kubernetes to automatically restart failed containers or reschedule Pods to healthy nodes. Auto-scaling is a feature that allows Kubernetes to automatically adjust the number of replicas based on demand or metrics.</p>
<p>To enable auto-healing and auto-scaling for our Deployment, follow these steps:</p>
<ol>
<li>To enable auto-healing, we don’t need to do anything special. Kubernetes already does this by default for Deployments. If a container crashes or a node fails, Kubernetes will automatically create a new Pod and assign it to a healthy node.</li>
</ol>
<p>To test this feature, you can manually delete one of your Pods by running:</p>
<pre><code class="lang-bash">kubectl delete pod &lt;pod-name&gt;
</code></pre>
<p>Replace <code>&lt;pod-name&gt;</code> with the name of one of your Pods that you want to delete.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694891518814/7c2b42cb-b0cc-4b9f-a41a-26368d820029.png" alt class="image--center mx-auto" /></p>
<p>If you check your Pods again by running <code>kubectl get pods</code>, you should see that a new Pod has been created to replace the deleted one.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694891586795/b84eece0-3759-4dba-9d2e-a7fb5d359799.png" alt class="image--center mx-auto" /></p>
<ol>
<li>To enable auto-scaling, we need to create a Horizontal Pod Autoscaler (HPA) object that defines how we want to scale our Deployment based on CPU utilization or other metrics.</li>
</ol>
<p>To create an HPA object that scales our Deployment between 1 and 5 replicas based on CPU utilization, run:</p>
<pre><code class="lang-bash">kubectl autoscale deployment todo-app --min=1 --max=5 --cpu-percent=50
</code></pre>
<p>This will create an HPA object named <code>todo-app</code> that monitors the average CPU utilization of our Pods and adjusts the number of replicas accordingly.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694891699514/a52ea44b-9759-4347-a2fe-1e2419af3cef.png" alt class="image--center mx-auto" /></p>
<p>To verify that the HPA is created, run:</p>
<pre><code class="lang-bash">kubectl get hpa
</code></pre>
<p>You should see something like this:</p>
<p>This shows that you have one HPA named <code>todo-app</code> that targets the Deployment <code>todo-app</code> with a minimum of 1 and a maximum of 5 replicas, and a target CPU utilization of 50%.</p>
<p>To see the current CPU utilization and the desired number of replicas, run:</p>
<pre><code class="lang-bash">kubectl get hpa -w
</code></pre>
<p>This will show you the HPA status in a watch mode, which updates every few seconds.</p>
<p>This shows that the current CPU utilization is 0% and the current number of replicas is 2</p>
<p>To test the auto-scaling feature, you can generate some load on your Pods by running:</p>
<pre><code class="lang-bash">kubectl run -it --rm load-generator --image=busybox /bin/sh
</code></pre>
<p>This will create a temporary Pod named <code>load-generator</code> that runs a shell in an interactive mode.</p>
<p>In the shell, run the following command:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span> wget -q -O- http://todo-app.default.svc.cluster.local; <span class="hljs-keyword">done</span>
</code></pre>
<p>This will send an infinite loop of requests to the ToDo app service.</p>
<p>In another terminal, watch the HPA status by running:</p>
<pre><code class="lang-bash">kubectl get hpa -w
</code></pre>
<p>You should see that the CPU utilization increases and the number of replicas changes accordingly.</p>
<p>This shows that the HPA has scaled up the number of replicas to 5 to handle the increased load.</p>
<p>To stop the load generator, press Ctrl+C in the shell and exit.</p>
<p>You should see that the CPU utilization decreases and the number of replicas changes accordingly.</p>
<p>This shows that the HPA has scaled down the number of replicas to 1 to save resources.</p>
<p>Congratulations! You have successfully enabled auto-healing and auto-scaling for your Deployment.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, we learned how to launch a Kubernetes cluster with Deployment, a configuration that allows us to manage updates to Pods and ReplicaSets. We also deployed a sample ToDo app on Kubernetes using Deployment and enabled auto-healing and auto-scaling for it.</p>
<p>I hope you enjoyed this blog post and learned something new. If you have any questions or feedback, please feel free to leave a comment below.</p>
<p>If you want to follow my journey of learning DevOps, you can check out my <a target="_blank" href="https://github.com/ajitfawade">GitHub</a> and <a target="_blank" href="https://www.linkedin.com/in/ajitfawade/">LinkedIn</a> profile.</p>
<p>Thank you for reading and stay tuned for more!</p>
]]></content:encoded></item></channel></rss>