<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ec2 on Alperen Doc</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/</link><description>Recent content in ec2 on Alperen Doc</description><generator>Hugo</generator><language>en</language><atom:link href="https://blog.ulutasalperen.com/docs/aws/ec2/index.xml" rel="self" type="application/rss+xml"/><item><title>ec2-instance-configuration-keys</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/ec2-instance-configuration-keys/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/ec2-instance-configuration-keys/</guid><description>&lt;h1 id="ec2-instance-configuration-keys"&gt;EC2 Instance Configuration: Keys&lt;a class="anchor" href="#ec2-instance-configuration-keys"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;We need to get the PatientPing application running on a server, but first we need a secure way to &lt;em&gt;connect&lt;/em&gt; to that server. Usually, this is done with &lt;code&gt;ssh&lt;/code&gt; and a key pair.&lt;/p&gt;&#10;&lt;p&gt;Windows servers have extra hoops to jump through (some of them also requiring a key pair), but Linux systems make up &lt;a href="https://sqmagazine.co.uk/linux-statistics/#:~:text=Linux%20runs%2049.2%25%20of%20all,among%20active%20subscriptions%20in%202025."&gt;the majority&lt;/a&gt; of cloud servers, even on Microsoft&amp;rsquo;s &lt;a href="https://build5nines.com/linux-is-most-used-os-in-microsoft-azure-over-50-percent-fo-vm-cores/"&gt;Azure&lt;/a&gt;, which gives me joy. We&amp;rsquo;ll focus on Linux for this document.&lt;/p&gt;</description></item><item><title>ec2-instances</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/ec2-instances/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/ec2-instances/</guid><description>&lt;h1 id="ec2-instances"&gt;EC2 Instances&lt;a class="anchor" href="#ec2-instances"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;With a VPC, subnets, and a key pair in hand, we&amp;rsquo;re ready to launch our first AWS &lt;strong&gt;server instance&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Elastic Cloud Compute&lt;/strong&gt; (&lt;strong&gt;EC2&lt;/strong&gt;) is AWS&amp;rsquo; flagship service for running servers on their infrastructure. It&amp;rsquo;s their answer to questions like:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How do I get a Linux or Windows box in Amazon&amp;rsquo;s cloud?&lt;/li&gt;&#10;&lt;li&gt;How do I provision dedicated hardware?&lt;/li&gt;&#10;&lt;li&gt;How do I build a server with a GPU attached?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Let&amp;rsquo;s create an instance and look at the choices we have to make along the way.&lt;/p&gt;</description></item><item><title>elastic-ips</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/elastic-ips/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/elastic-ips/</guid><description>&lt;h1 id="elastic-ips"&gt;Elastic IPs&lt;a class="anchor" href="#elastic-ips"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;Our PatientPing server &lt;em&gt;does&lt;/em&gt; need a public IP address to be reachable on the internet, but we&amp;rsquo;re going to use an &amp;ldquo;&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html"&gt;Elastic IP address&lt;/a&gt;&amp;rdquo; (EIP). This is an address that we can attach to any of our servers and move around as needed. You might be thinking:&lt;/p&gt;&#10;&lt;blockquote class='book-hint '&gt;&#10;&lt;p&gt;&amp;ldquo;But Alperen, why not just use the nice automatic public IP address?&amp;rdquo;&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;Well, the &amp;ldquo;auto-provisioned IP address&amp;rdquo; that we opted &lt;em&gt;not&lt;/em&gt; to use earlier has a few downsides:&lt;/p&gt;</description></item><item><title>aws-security-groups</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/aws-security-groups/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/aws-security-groups/</guid><description>&lt;h1 id="security-groups"&gt;Security Groups&lt;a class="anchor" href="#security-groups"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;Wait, so anyone who knows my server&amp;rsquo;s public IP address can access it?!&lt;/p&gt;&#10;&lt;p&gt;On some level, yes. That&amp;rsquo;s why we need a layer of protection to inspect network traffic coming in and going out, and make sure it&amp;rsquo;s traffic we actually want. We need a &lt;strong&gt;firewall&lt;/strong&gt;, or in AWS terms, a &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html"&gt;security group&lt;/a&gt;. It lets you set rules like:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;All traffic coming from my server is allowed to go where it wants (i.e., &lt;strong&gt;outbound&lt;/strong&gt; traffic).&lt;/li&gt;&#10;&lt;li&gt;Folks on the internet are allowed to reach my web server, but not my database server (i.e., &lt;strong&gt;inbound&lt;/strong&gt; traffic).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img src="https://storage.googleapis.com/qvault-webapp-dynamic-assets/course_assets/n4CKrKx-831x680.png" alt="" /&gt;&lt;/p&gt;</description></item><item><title>ssh-to-aws-server</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/ssh-to-aws-server/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/ssh-to-aws-server/</guid><description>&lt;h1 id="ssh-to-our-server"&gt;SSH to Our Server&lt;a class="anchor" href="#ssh-to-our-server"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;You may start to understand why people sometimes throw up their hands and use an &amp;ldquo;easier&amp;rdquo; provider like Vercel or Heroku. Those providers configure all the same things we&amp;rsquo;ve done so far, then sell it to you at a (steep) markup.&lt;/p&gt;&#10;&lt;p&gt;But if you can handle the basics on your own (and you can), you&amp;rsquo;ll save money and have more control over your infrastructure.&lt;/p&gt;&#10;&lt;p&gt;Seriously, some folks are happy to chew through C code full of &lt;code&gt;malloc&lt;/code&gt;, &lt;code&gt;calloc&lt;/code&gt;, and &lt;code&gt;int *int_list_ptr = (int *)struct_list_of_ints;&lt;/code&gt;, but adding a route is too hard? Not you; onward and upward.&lt;/p&gt;</description></item><item><title>deploy-site-to-aws-server</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/deploy-site-to-aws-server/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/deploy-site-to-aws-server/</guid><description>&lt;h1 id="deploy-the-patientping-site"&gt;Deploy the PatientPing Site&lt;a class="anchor" href="#deploy-the-patientping-site"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;Now that you can SSH into the &lt;code&gt;patientping-web&lt;/code&gt; server, let&amp;rsquo;s get the PatientPing application running on it. We&amp;rsquo;ll install &lt;code&gt;git&lt;/code&gt;, clone the app, install its dependencies, and start the web server.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Cost check:&lt;/strong&gt; No new resources. You&amp;rsquo;re using the same EC2 instance; cost is unchanged.&lt;/p&gt;&#10;&lt;h2 id="assignment"&gt;Assignment&lt;a class="anchor" href="#assignment"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;Deploy the PatientPing application on the &lt;code&gt;patientping-web&lt;/code&gt; instance.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;SSH into your &lt;code&gt;patientping-web&lt;/code&gt; instance (e.g. &lt;code&gt;ssh patientping&lt;/code&gt; if you configured that in the previous lesson).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Install &lt;code&gt;git&lt;/code&gt;&lt;/strong&gt; on the instance (the base AMI may not include it). On Amazon Linux, run:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf upgrade&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;&#10;&lt;li&gt;Install &lt;a href="https://github.com/astral-sh/uv"&gt;&lt;code&gt;uv&lt;/code&gt;&lt;/a&gt; to be able to run the Python server:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -LsSf https://astral.sh/uv/install.sh | sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="4"&gt;&#10;&lt;li&gt;Verify that you have both &lt;code&gt;git&lt;/code&gt; and &lt;code&gt;uv&lt;/code&gt; in &lt;code&gt;PATH&lt;/code&gt;:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;which git&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;which uv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="5"&gt;&#10;&lt;li&gt;&lt;strong&gt;Clone the GitHub repo&lt;/strong&gt; of the PatientPing app to the EC2 instance:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd ~&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://github.com/bootdotdev/patientping-web.git&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd patientping-web&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;uv sync&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;uv run patientping.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote class='book-hint '&gt;&#10;&lt;p&gt;You should see the server start up on port &lt;code&gt;8080&lt;/code&gt;!&lt;/p&gt;&#10;&lt;/blockquote&gt;</description></item><item><title>open-web-traffic</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/open-web-traffic/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/open-web-traffic/</guid><description>&lt;h1 id="open-web-traffic"&gt;Open Web Traffic&lt;a class="anchor" href="#open-web-traffic"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;The PatientPing app is running on the server, but nobody can reach it because our &lt;code&gt;patientping-public&lt;/code&gt; security group only allows inbound SSH traffic on port &lt;code&gt;22&lt;/code&gt;. Port &lt;code&gt;8080&lt;/code&gt;, where the app is listening, is blocked.&lt;/p&gt;&#10;&lt;p&gt;This is actually a &lt;em&gt;good&lt;/em&gt; default. A firewall that blocks everything except what you explicitly allow is the safest starting point. You saw firsthand in the last lesson what that looks like: the browser just hangs because the packets never make it through.&lt;/p&gt;</description></item><item><title>creating-and-using-your-own-ami</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/creating-and-using-your-own-ami/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/creating-and-using-your-own-ami/</guid><description>&lt;h1 id="creating-and-using-your-own-ami"&gt;Creating and Using Your Own AMI&lt;a class="anchor" href="#creating-and-using-your-own-ami"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;When we configured our server, we chose one of the out-of-the-box &amp;ldquo;base AMIs&amp;rdquo; that AWS provides. However, it&amp;rsquo;s also possible to make your own!&lt;/p&gt;&#10;&lt;h2 id="why-create-an-ami"&gt;Why Create an AMI?&lt;a class="anchor" href="#why-create-an-ami"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Simple backup:&lt;/strong&gt; You can snapshot a running server so that if something goes wrong, you can launch a new instance from that image and get back to a known good state.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Cold store and save on costs:&lt;/strong&gt; Instead of leaving a server running 24/7 when you don&amp;rsquo;t need it, you can create an AMI, terminate the instance, and later launch a new instance from the AMI when you need it again. You pay only for the (cheaper) storage of the AMI/snapshot until you spin the server back up.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Transfer to a different region:&lt;/strong&gt; AMIs are region-specific. If you want to run the same setup in another region, you can copy your AMI to that region and launch instances there. Handy for disaster recovery or moving closer to your users.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Cookie cutter for new servers:&lt;/strong&gt; Once you have a server configured the way you want (OS, app, config), you can create an AMI from it and use that AMI as the basis for &lt;strong&gt;new instances&lt;/strong&gt; (we&amp;rsquo;ll talk more about this soon).&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="assignment"&gt;Assignment&lt;a class="anchor" href="#assignment"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;Create an AMI from your &lt;code&gt;patientping-web&lt;/code&gt; instance&lt;/strong&gt; so you have a reusable image (and a simple backup).&lt;/p&gt;</description></item><item><title>aws-launch-template</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/aws-launch-template/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/aws-launch-template/</guid><description>&lt;h1 id="launch-template"&gt;Launch Template&lt;a class="anchor" href="#launch-template"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;A &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/launch-templates.html"&gt;launch template&lt;/a&gt; is a pre-baked configuration for EC2 instances.&lt;/p&gt;&#10;&lt;p&gt;As you know, an AMI is an image of the software on the server, but a launch template goes one step further: it also captures the &amp;ldquo;hardware&amp;rdquo; (instance type), the network configuration (subnet, security groups), and more. It&amp;rsquo;s a way to say, &amp;ldquo;This is the &lt;em&gt;exact&lt;/em&gt; configuration I want for new servers.&amp;rdquo;&lt;/p&gt;&#10;&lt;h2 id="assignment"&gt;Assignment&lt;a class="anchor" href="#assignment"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;PatientPing is eventually going to need a bunch of servers. Create a launch template that uses the AMI you created&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>launch-from-template-aws</title><link>https://blog.ulutasalperen.com/docs/aws/ec2/launch-from-template-aws/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ulutasalperen.com/docs/aws/ec2/launch-from-template-aws/</guid><description>&lt;h1 id="launch-from-template"&gt;Launch from Template&lt;a class="anchor" href="#launch-from-template"&gt;#&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;The point of creating our launch template was so we could treat servers &lt;em&gt;like cattle, not pets&lt;/em&gt;. Let&amp;rsquo;s do that.&lt;/p&gt;&#10;&lt;p&gt;We&amp;rsquo;ll terminate our &lt;code&gt;patientping-web&lt;/code&gt; instance, and launch a brand new one from the &lt;code&gt;patientping-web-launcher&lt;/code&gt; template to get the site back up. Because the AMI already has the app baked in, we&amp;rsquo;ll basically just need to SSH back in and start the app.&lt;/p&gt;&#10;&lt;h2 id="assignment"&gt;Assignment&lt;a class="anchor" href="#assignment"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;Terminate the current PatientPing instance and launch a replacement from your launch template.&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>