<?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" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Daniel Langer - Daniel Langer]]></title><description><![CDATA[A business, man.]]></description><link>https://daniellanger.com/</link><image><url>https://daniellanger.com/favicon.png</url><title>Daniel Langer - Daniel Langer</title><link>https://daniellanger.com/</link></image><generator>Ghost 2.12</generator><lastBuildDate>Sun, 23 Aug 2026 03:30:26 GMT</lastBuildDate><atom:link href="https://daniellanger.com/author/dan/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Retrieving Open Data from ArcGIS]]></title><description><![CDATA[Step-by-step instructions on how to access the data that powers ArcGIS open-data vistualizations and dashboards.]]></description><link>https://daniellanger.com/retrieving-open-data-from-arcgis/</link><guid isPermaLink="false">5eb952867413a242feaacdfe</guid><category><![CDATA[opendata]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Mon, 11 May 2020 15:04:56 GMT</pubDate><content:encoded><![CDATA[<p>When accessing <a href="https://open.canada.ca/en/open-data">open data</a> from government agencies, it's often presented as a map or dashboard using <a href="https://www.arcgis.com/index.html">ArcGIS</a> (and not raw data). Governments do this because ArcGIS does a great sales job of presenting itself as an "open data hub", and it's easy for them to wire ArcGIS directly up to the internal systems generating the data. The cost of doing that, however, is that it's often more difficult to find the underlying data and do your own work on it - but with a little work, we can still access it.</p><h2 id="recognizing-arcgis">Recognizing ArcGIS </h2><p>In order to use this technique, you need to be sure that the data you're looking for is being hosted by ArcGIS. The easiest way to confirm this is by looking at the URL - it'll often contain the word <code>arcgis</code>:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2020/05/image-1.png" class="kg-image"></figure><p>The other easy way to recognize ArcGIS is by the look-and-feel of their dashboards:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2020/05/image-4.png" class="kg-image"></figure><p>or their browser icons:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2020/05/image-5.png" class="kg-image"></figure><p>Once you have a good feeling that you're looking at an ArcGIS dashboard, it's time to go looking for the underlying data.</p><h2 id="accessing-the-underlying-data">Accessing the Underlying Data</h2><p>ArcGIS is <a href="https://developers.arcgis.com/">API-driven</a>, so our task here is to find a way to interact with the API and retrieve the data in the form we want. Because of the many ways ArcGIS dashboards can be set up, I've found the most reliable way to find the API is using Chrome's <a href="https://developers.google.com/web/tools/chrome-devtools">DevTools</a> to see where the dashboard's API requests are sent.</p><p>With DevTools open, browse to the ArcGIS page you'd like to find the data for, and look at the <em>Network</em> tab, typing  <code>query</code> into the <em>Filter</em> filed. You'll see something like this:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2020/05/image-6.png" class="kg-image"></figure><p>Those <code>query?f=json...</code> lines are the API requests we're trying to find. Right-click on one of them, select <em>Copy → Copy as link address</em>, and then paste that into your browser's location bar. In my example, I get <code>https://services8.arcgis.com/</code><br><code>aCyQID5qQcyrJMm2/arcgis/rest/services/RHA_CurrentStats2_Public2</code><br><code>/FeatureServer/0/queryf=json&amp;where=RHAShort%3D'Central_RHA'</code><br><code>&amp;returnGeometry=false&amp;spatialRel=esriSpatialRelIntersects&amp;outFields</code><br><code>=*&amp;resultOffset=0&amp;resultRecordCount=25&amp;resultType=standard&amp;cacheHint=true</code>. Delete everything after <code>/rest/services/</code>, and then go to that page - in my example, I end up with <code>https://services8.arcgis.com/aCyQID5qQcyrJMm2/arcgis/rest/services/</code>. This is a list of all the different ArcGIS data sources that have been made public on this server, and looks something like this:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2020/05/image-7.png" class="kg-image"></figure><p>On this list, it's important to <strong>be selective about the data you pick</strong><em>. </em>You're looking at the raw data here, without the context of how it's captured, how up-to-date it is, how it's been processed, etc. You'll often see several version of the "same" data (e.g. <code>Covid_19_PHC_Cases_Current</code> and <code>Covid_19_PHC_Cases_Current_v2</code>) and not know how or why they're different,</p><p>Once you've found a service that sounds interesting, click into it, and then click into the <em>Layer</em> that has the data you want:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2020/05/image-8.png" class="kg-image"></figure><p>On this screen, you can see the fields in each record (<em>Fields</em>) and when the data was last updated (<em>Last Edit Date</em>). Click <em>Query</em> at the bottom (next to <em>Supported Operations</em>), and you'll get the API query page:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2020/05/image-9.png" class="kg-image"></figure><p>You have three fields to update before pressing <code>Query (GET)</code><em> </em>at the bottom:</p><ol><li>Set <em>Where</em> to <code>1=1</code>. This tells the system that you want all records where <code>1=1</code>, which is another way of saying you want all of them.</li><li>Set <em>Out fields</em> to <code>*</code>. This tells the system that you want all fields in each record. Once you understand what's there, you can change this to be a comma-separated list of only the fields you want.</li><li>Set <em>Return Geometry</em> to <code>False</code>, assuming you're looking for data values and not mapping polygons. </li></ol><p>Once you've done that and press <code>Query (GET)</code>, you'll see the first page of your data displayed. From that data, you can select the fields you're interested in, and put them into the <em>Out fields</em> box. When you're ready to go, change the <em>Format</em> box to <code>JSON</code>, and press <code>Query (GET)</code> again.</p><p>This time, you'll end up with a JSON-only result that looks something like this:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2020/05/image-10.png" class="kg-image"></figure><p>and a URL that looks like <code>https://services8.arcgis.com/aCyQID5qQcyrJMm2</code><br><code>/ArcGIS/rest/services/Covid_19_PHC_Cases_Current_v2/FeatureServer</code><br><code>/0/query?where=1%...</code>. </p><p>This page is your raw data in machine-readable form, and that URL pulls new data each time you visit it. You can now add this into your data pipeline, and use the identical data that's driving the Government visualizations. You can also do interesting things like watching how the data changes over time (by downloading it every day), like I've done <a href="https://github.com/dlanger/coronavirus-hc-infobase-archive">here</a>. </p>]]></content:encoded></item><item><title><![CDATA[Why Alexa Can't Read]]></title><description><![CDATA[A daily discourse, in three conversations.]]></description><link>https://daniellanger.com/why-alexa-cant-read/</link><guid isPermaLink="false">5c66dd707413a242feaacdbb</guid><category><![CDATA[alexa]]></category><category><![CDATA[aws]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Fri, 15 Feb 2019 15:50:43 GMT</pubDate><content:encoded><![CDATA[<p>A daily discourse, in the middle of winter:</p>
<blockquote>
<p>Alexa, what's the heat set to?<br>
- Sorry, what device?<br>
Kitchen<br>
- That's not supported yet</p>
</blockquote>
<blockquote>
<p>Alexa, what's the temperature set to?<br>
- The heat's set to twenty<br>
Alexa, set the heat to nineteen<br>
- Sorry, what device?<br>
Kitchen<br>
- It's set to heat</p>
</blockquote>
<blockquote>
<p>Alexa, set the temperature to nineteen<br>
- The heat's set to nineteen</p>
</blockquote>
<p>I'll call it natural-language when I don't have to remember which synonym turns up the heat.</p>
]]></content:encoded></item><item><title><![CDATA[Someone Hacked My Computer!]]></title><description><![CDATA[If you got an email saying that someone hacked your computer and included one of your passwords as proof, here's what to do.]]></description><link>https://daniellanger.com/someone-hacked-my-computer-email-scam/</link><guid isPermaLink="false">5c60d26c7413a242feaacd70</guid><category><![CDATA[passwords]]></category><category><![CDATA[scam]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Mon, 11 Feb 2019 01:43:01 GMT</pubDate><content:encoded><![CDATA[<p>There's an interesting email scam going around now, where you'll get an email from an extortionist that includes a password you use and a threat to release embarrassing videos of you. The emails tend to look something like this, but with different amounts and threats:</p><figure class="kg-card kg-image-card"><img src="https://daniellanger.com/content/images/2019/02/image.png" class="kg-image"></figure><p>If you've received one of these, <strong>don't panic</strong><em>. </em>Your computer hasn't been hacked, but you should change the passwords you care about - especially if you use the same password in several places. </p><h2 id="what-happened">What happened?</h2><p>Every now and then you might see a <a href="https://www.wired.com/story/collection-one-breach-email-accounts-passwords/">news</a> <a href="https://techcrunch.com/2018/11/30/starwood-hotels-says-500-million-guest-records-stolen-in-massive-data-breach/">article </a>about a <a href="https://www.forbes.com/sites/gordonkelly/2014/05/21/ebay-suffers-massive-security-breach-all-users-must-their-change-passwords/#29eeec737492">big</a> <a href="https://www.bankinfosecurity.com/chase-breach-affects-76-million-households-a-7395">data</a> <a href="https://www.forbes.com/sites/leemathews/2018/10/14/department-of-defense-data-breach-exposes-30000-employees/#7515d22e1a6b">breach</a>, where someone broke into a company's computer system and got a list of usernames and passwords. These lists are then sold to extortionists and scammers, for them to use in scams like this one (or identity theft).</p><p>Bulk emails are cheap to send, so a scammer could run a profit on a scam like this if only one or two people in the world pay the "ransom". This is why they don't care that the email looks amateur and why they don't bother really customizing it for you: these scams are designed to be as low-effort as possible for the scammer, and by having it look suspicious, it filters out people who are less likely to fall for the scam . </p><p>To see where the password probably came from, put your email into <a href="https://haveibeenpwned.com/">haveibeenpwned.com</a>. This is a free service run by a researcher who gets copies of most of the data breaches out there and indexes them. You'll see that many breaches are a few years old, which explains why the password in the email may be one you stopped using. </p><h2 id="what-do-i-do">What do I do?</h2><p>Most importantly, <strong>don't send any money</strong> to the address in the email. There is no recording , and there's no one that has all your contacts to send it to. </p><p>The key thing is to now realize that a lot of bad people on the internet have the combination of email and password that were included in that email, and they're trying to use them to get into all sorts of accounts you have (taking advantage of the fact that most people use the same password in a few places). This is called "<a href="https://en.wikipedia.org/wiki/Credential_stuffing">credential stuffing</a>", and is a popular type of hacking. </p><p>The most important thing you can do now is <strong>change your passwords</strong>. Change any service that you know used the password included in the email, and change your critical passwords (email, bank, social media) even if they didn't. Change each one to a different and unrelated password, and <a href="https://www.betterbuys.com/estimating-password-cracking-times/">don't use words</a> or simple substitutions like switching <code>0</code> for <code>O</code> or <code>1</code> for <code>l</code>.</p><p>Once that's done, <strong>check <a href="https://haveibeenpwned.com">haveibeenpwned.com</a></strong> to see what other passwords of yours are in the wild. Change the password on any service you see listed there.</p><p>Since you're changing all your passwords, this is a great time to <strong>start using a password manager </strong>like <a href="https://1password.com/">1Password</a> or <a href="https://www.lastpass.com/">LastPass</a>. Password managers are secure apps that store all your passwords, and keep track of things like when you last changed them or <a href="https://support.1password.com/watchtower/">if they've been found</a> in a data breach. </p><p>The idea is that you only have to remember one (complex) password for the password manager, and then the app keeps track of all the individual passwords that it creates for every service. They have browser plugins and mobile apps too, so that you never have to type a password in again. Using a password manager and letting it generate a unique password for every site is the <strong>best thing you can do </strong>for your online security, and it makes your life easier as a bonus. </p>]]></content:encoded></item><item><title><![CDATA[Visiting Bhutan]]></title><description><![CDATA[<p>Everyone has their own reason to travel to Bhutan.</p>
<p>My trip was driven by timing, more than anything else: I wanted to go trekking in that part of the world, and the <a href="https://www.gadventures.com/trips/bhutan-trekking-the-druk-path/ADDP/">G Adventures trip</a> fit my schedule.</p>
<p>Others were more interesting, though. One woman in my group had dreamed</p>]]></description><link>https://daniellanger.com/visiting-bhutan/</link><guid isPermaLink="false">5c4a858f961d3d40d6026798</guid><category><![CDATA[bhutan]]></category><category><![CDATA[travel]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Fri, 25 Jan 2019 00:32:05 GMT</pubDate><media:content url="https://daniellanger.com/content/images/2019/01/IMG_20181113_115541.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://daniellanger.com/content/images/2019/01/IMG_20181113_115541.jpg" alt="Visiting Bhutan"><p>Everyone has their own reason to travel to Bhutan.</p>
<p>My trip was driven by timing, more than anything else: I wanted to go trekking in that part of the world, and the <a href="https://www.gadventures.com/trips/bhutan-trekking-the-druk-path/ADDP/">G Adventures trip</a> fit my schedule.</p>
<p>Others were more interesting, though. One woman in my group had dreamed of going since she was five, and got the trip as a present from her kids. Another was a European diplomat based in India, who wanted to go somewhere that was cold and offered a break from the smog. One was a corporate lawyer on gardening leave, and came because his friends dared him.</p>
<p>We all had different reasons, but we were all drawn on some level by those same few facts that always get repeated about Bhutan:</p>
<ol>
<li>It's a tiny isolated Himalayan kingdom</li>
<li>They run their country in pursuit of Gross National Happiness, as opposed to Gross National Product</li>
<li>It's way, way, far <em>over there</em> [waves hand broadly in the direction of India]</li>
</ol>
<p>Because I'm a sucker for seeing trivia pan out in real life, I ended up spending slightly under two weeks tromping around a few valleys in a country roughly twice the size of Wales.</p>
<p>So, what do you do in Bhutan? You walk.</p>
<p>I went for the Druk Path.</p>
<p><img src="https://daniellanger.com/content/images/2019/01/IMG_20181112_102954.jpg" alt="Visiting Bhutan"></p>
<h1 id="trekkingthedrukpath">Trekking the Druk Path</h1>
<p>The Druk Path isn't what you think of as a trail in the Western sense. It's not formally marked, nor is it run by a particular agency, nor does it have a nice map. Broadly <em>hiking the Druk Path</em> is walking the route that people used to use to get between Paro and Thimpu, and using common campsites. This means that different tour companies will have different routes and different lengths.</p>
<p>The particular trek I took did the route in six days, which is about as leisurely as one could get. We'd start walking around 9am and be in camp by 4pm, after stopping for lunch for an hour and for regular tea breaks. While that'd be listed as seven hours of walking on an itinerary, it's really around four and a half hours of feet-moving time spread over seven hours. Based on my trip, a five-day route would be nice for someone of average fitness, and a four-day route would be very doable for someone used to hiking. The whole route is ~55Km, and Bhutanese have been known to do it in a day.</p>
<p>The route I took was Paro → Jele Dzong → Jangchulakha → Jimilangtsho → Simkotra → Phajoding → Thimpu. Of those days, only the third one (Jangchulakha to Jimilangtsho) was challenging - but the guide explained that if we were doing the trek in fewer days, he'd have taken a shorter route between the two areas, and ended the day one campsite further along.</p>
<p>In comparison, G Adventures trips for next year will go Paro → Jele Dzong → Jimilangtsho → Simkotra → Thimpu. Assuming they take the shorter route from Jele Dzong to Jimilangtsho, this seems aggressive but doable by someone of average fitness. Their overview makes a big deal out of the length of the Simkotra to Thimpu day, but it's nothing to be afraid of; leaving Simkotra at 9am, we arrived at Phajoding by 2pm, and the Thimpu pick-up point is only a few hours down a hill from there.</p>
<p>If you're coming from Nepal, the Druk Path will seem pleasantly depopulated. Only about 1200 people do it per year (which breaks out to around fifteen groups per month), and the odds are good of being alone out there on the trek. There was one other group doing it at the same time as I was, and our groups would only run into one another maybe once per day.</p>
<p><img src="https://daniellanger.com/content/images/2019/01/IMG_20181121_105417.jpg" alt="Visiting Bhutan"></p>
<h1 id="weather">Weather</h1>
<p>I did the trek in mid-November, which is the end of the tourist season and the start of winter.</p>
<p>In Paro &amp; Thimpu, the days were around 12 °C, going down to 5-7 °C in the evenings - so not especially cold, but definitely crisp and needing a jacket.</p>
<p>On the trek itself, there are two temperatures: in the sun, and out of the sun.</p>
<p>When in the sun (starting an hour or so after wake-up, lasting until about 4pm), it was glorious. Pure, unfiltered, high-altitude sunshine, and 10 °C. For me, that meant hiking pants, a <a href="https://www.uniqlo.com/us/en/men-heattech-extra-warm-crew-neck-long-sleeve-t-shirt-400227.html">base thermal layer</a>, and a light zip-up fleece. I kept a down jacket in my day-pack, but only wore before I warmed up or when stopping for lunch.</p>
<p>When not in the sun, it was cold. Within half an hour of losing the sun (which always happened after reaching camp) the temperature would drop to around 3 °C, and I'd add a windbreaker, toque, better gloves, and put on a layer of thermal long-underwear. Even with that on, huddling around the fire was key to staying comfortable.</p>
<p>Overnight, it would go down to -15 °C or so. Water bottles left outside the tent would freeze, batteries would wear down, and mornings would find the inside of the tent covered with a layer of ice from my breathing. I had a -18 °C sleeping bag, and was warm enough if I slept in my thermal long-underwear. If you're going this late in the season, I wouldn't bring a lighter bag.</p>
<p>Luckily, there was no rain while on my trek (although there was some light snow late at night) - but I can see how it'd be cold and miserable if there was.</p>
<p><img src="https://daniellanger.com/content/images/2019/01/IMG_20181117_071403.jpg" alt="Visiting Bhutan"></p>
<h1 id="packing">Packing</h1>
<p>There are a bunch of packing lists <a href="https://www.google.com/search?q=druk+path+packing+list">out there</a>, but it ultimately comes down to the amount of warm gear you'd like to bring, and how many times you'd like to re-wear the same base layers and socks. The usual hiking advice about layering strongly applies here, and it's worth planning which pieces of clothing you'll carry in your day pack versus which you'll leave on the horses, to be seen again when you arrive at camp each day.</p>
<p>Aside from that, the technical essentials are a pair of hiking boots or trekking shoes, a day pack, a few water bottles, a head lamp, a rain jacket and pants, and a warm sleeping bag. Unless you have balance or knee worries, I wouldn't bother with trekking poles; the only spot they'd be useful is a few hours going down hill on the last day.</p>
<p>Sadly, there isn't anywhere in Paro to rent gear - while it's 100% a tourist town, there isn't the traffic for rentals as Bhutan isn't a place you short-notice drop in to. If you're doing the trek in the middle of a larger trip and don't want to carry a sleeping bag everywhere, fly via Kathmandu and rent your gear there.</p>
<p><img src="https://daniellanger.com/content/images/2019/01/IMG_20181121_160712.jpg" alt="Visiting Bhutan"></p>
<h1 id="otherplaces">Other Places</h1>
<p>If you're coming back to Paro after your trek, the <a href="https://en.wikipedia.org/wiki/Paro_Taktsang">Tiger's Nest Monastery</a> is one of, if not the, biggest tourist sites in Bhutan. First built in the 1600s, it was mostly rebuilt in 1988 due to a fire. On one hand, it's a spectacular view, and the most recognizable thing in Bhutan. On the other, it's full of SAADC tourists, and while it remains a working monastery, the whole rebuilt-in-1988 thing makes it feel a little fake. On balance, though, it remains a must-visit.</p>
<p>The round-trip hike is about seven kilometers, and there's no driving option (although you can rent a horse for portions of the climb). All-in, budget three hours to trek up, an hour or so at the monastery, and then an hour to trek down. The route is mostly wide dirt paths, with half an hour of rock stairs at the final pitch. I wore my full hiking gear, but you'll see many people do it in jeans and trainers.</p>
<p>Hiking around the <a href="https://www.google.com/search?q=chelela+pass&amp;source=lnms&amp;tbm=isch">Chelelea Pass</a> was one of the highlights of my trip. You'll see thousands of prayer flags, but the reason you're up there is views of the Paro &amp; Haa valleys and of Mt. Jhomolhari. You'll also get a nice view of the route the Druk Path takes, and you can see the ridges you spent the first few days walking over.</p>
<p>There isn't much there there on arrival, aside from a truck selling porridge. Park your car and starting walking up, and go until there isn't any further up. If you go all the way to the end of the ridgeline, it's three or four hours' (return) walk - but you can turn around at any point, and past an hour's walk outbound the views are similar. Bring water, and wear jeans and trainers. To get there, the drive from Paro to the base of the pass is about 90 minutes of forested switchbacks. On your way home, don't bother driving down into the Haa Valley - the Indian military base and the one Dzong aren't worth it.</p>
<p>Another option is to extend your stay in central Bhutan and head to <a href="https://www.makemytrip.com/blog/places-to-visit-in-punakha">Punakha</a>. I haven't been, but I'm told it has some beautiful hikes and Dzongs.</p>
<p><img src="https://daniellanger.com/content/images/2019/01/IMG_20181111_100524.jpg" alt="Visiting Bhutan"></p>
<h1 id="returning">Returning</h1>
<p>Having been once, would I go back? Probably not.</p>
<p>I enjoyed my time there greatly, but if I'm taking the time and flights to go trekking in the Himalayas, I'll go somewhere else - new culture, new views, new passport stamp. It's a place worth visiting once, but probably not a second time.</p>
<p><em>Flights to Bhutan are available on <a href="https://www.drukair.com.bt/">Drukair</a> and <a href="http://www.bhutanairlines.bt/">Bhutan Airlines</a> - which may be different brands of the same company - from Bangkok, Singapore, Kathmandu, and major Indian cities.</em></p>
]]></content:encoded></item><item><title><![CDATA[The Ontario Landlord and Tenant Board]]></title><description><![CDATA[A self-represented tenant's perspective on taking a landlord to the Ontario Landlord & Tenant Board (LTB). ]]></description><link>https://daniellanger.com/ontario-ltb/</link><guid isPermaLink="false">5c4a858f961d3d40d6026797</guid><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Mon, 22 Oct 2018 15:59:59 GMT</pubDate><content:encoded><![CDATA[<p>Living in rental housing is weird.</p>
<p>Someone has bought this expensive piece of property, and then they just hand you the keys for it, cash your cheques, and do maintenance - or at least, that's the best case.</p>
<p>Often, though, the best case doesn't happen. Things break and they don't get fixed, your landlord does things they're not supposed to, or you and they have a difference of agreement on something. When that happens, the best plan is to try and fairly work something out informally. When that doesn't work, the Ontario legal system has a special place to deal with the situation: the <a href="http://www.sjto.gov.on.ca/ltb/">Landlord and Tenant Board</a>.</p>
<p>In my case, my landlord and I disagreed on who was responsible for fixing some broken cabinets. We tried to work it out, but after a lot of back-and-forth we couldn't - so I applied for an order to force them to fix my cabinets, and they applied for an order to force me to pay for fixing their cabinets.</p>
<p>In the end, we reached a mediated settlement that both of us were happy with. While preparing for that, though, I found there wasn't much out there about the experience from the perspective of a self-represented tenant.</p>
<p>Here's what I learned.</p>
<h1 id="structureoftheboard">Structure of the Board</h1>
<p>The Landlord and Tenant Board (LTB) is a tribunal created by the <em>Rental Tenancies Act</em>, charged with resolving disputes between landlords and tenants. This means that while it's not a court like on <em>Law &amp; Order</em>, its judgements are real and legally binding.</p>
<p>Hearings are conducted by Members, who are career civil servants. Members may or may not have had legal training before they joined the LTB, but by the time they handle your case they'll know the <em>Rental Tenancies Act</em> inside and out, and will be experienced in how to run a session. Like judges, they can issue binding decisions and order fines. Unlike judges, they don't deal with criminal or civil matters, and they can't send you to jail or have you arrested.</p>
<p>You start an interaction with the LTB by filing a <a href="http://www.sjto.gov.on.ca/ltb/forms/">notice or application</a>, which is a form asking the Board to order someone to do (or not do) something - as examples, this could be a tenant asking the Board to order their landlord to stop entering their unit, or a landlord asking the Board to order their tenant to move out. In either case, the person that filed the application is known as the <em>applicant</em>, and person receiving the order is the <em>respondent</em>.</p>
<p>You don't need a lawyer to appear before the LTB; especially in simpler cases, both sides representing themselves is pretty common. You can hire a lawyer, though, and if one side has one there's no obligation for the other side to have one. You can also hire a paralegal, bring a friend, or have a friend/family member who has legal training help you out (although there are some restrictions on this if you don't pay them). The important thing is that everyone involved only has one role, meaning that your friend who's sitting at the table and helping you out can't also be called as a witness.</p>
<h1 id="preparation">Preparation</h1>
<p>Preparation for a hearing consists of three main areas: understanding precedents and the law, creation of your narrative, and the collection &amp; presentation of documents.</p>
<h2 id="precedentsthelaw">Precedents &amp; the Law</h2>
<p>In order to make a decent case, you need to know the law - so read it. At the LTB, the main governing laws are the <a href="https://www.ontario.ca/laws/statute/06r17"><em>Residential Tenancies Act</em></a> and the by-laws of the community where the property is. Both of these are pretty straightforward as laws go, and can be read in an afternoon. You should also read the LTB's <a href="http://www.sjto.gov.on.ca/ltb/rules-practice-directions-guidelines/">rules, guides and interpretations</a>, which are like cheat-sheets for how the LTB <em>usually</em> handles certain parts of the law. The Advocacy Centre for Tenants Ontario also releases great <a href="https://www.acto.ca/for-tenants/tip-sheets/">tip-sheets</a> on specific situations.</p>
<p>Once you've found the relevant part of the law, you'll likely see that your situation is slightly different than the exact one covered by the text. This is OK and normal - it doesn't mean that you've fallen into some hole in the legal system. Rather, it means that your task becomes to convince the Member that while there may be a small difference, your situation is what the law is talking about, and that you should get the remedy the law says.</p>
<p>If there's something in the law you're really not sure of, you can call a <a href="http://www.legalaid.on.ca/en/contact/contact.asp?type=cl">Community Legal Clinic</a>. They're overworked and underpaid, but can likely point you in the right direction. Some communities may have tenants' rights groups with helplines, like <a href="https://torontotenants.org/services/hotline">FMTA</a> (for tenants in Toronto).</p>
<p>From watching <em>Law &amp; Order</em>, you may think that the most important argument you have is based on precedents - which isn't really the case at the LTB. Since the Board isn't a court, Members don't have to follow precedents directly, and they can get offended if you keep throwing references at them. Two or three references in one place is usually fine, but beyond that you're tempting fate. It's also important to present them not as &quot;here's a binding thing you have to follow&quot;, but rather as a very respectful &quot;here's how some other Member thought about this situation&quot;.</p>
<p>Reading old decisions is great, though, for seeing how your issue has been handled in the past. Searching <a href="https://www.canlii.org/en/on/onltb/">CanLII</a> for keywords from the part of the law you're interested in can help you find relevant LTB decisions. I found them most useful for suggesting arguments which won't work, and for showing how the average Member will deal with definitions and terms which aren't covered in the text of the law.</p>
<p>At this point, you should have a pretty good idea of what laws apply to your situation, what remedy those laws entitle you to, and how a few cases around them have been handled in the past. Armed with that, you're now ready to start crafting the story you'll use to explain why your interpretation is the right one.</p>
<h2 id="narrative">Narrative</h2>
<p>Your narrative is the story of what happened and led you to be at the LTB, as you see it. This is what you'll explain at the start of your hearing, and what you'll use to position and contextualize all your responses and questions. This should be informed by your understanding of the law, and will influence how you select and organize your evidence.</p>
<p>The important thing here is that while you should be using facts and descriptions in a way that supports your story, the facts still have to be true (from your perspective). As an example, let's say the issue is who's responsible for fixing a wall which collapsed. The landlord's narrative will likely be &quot;the tenant did X, which caused the wall to fall down&quot;. In that case, your narrative could be &quot;I don't know why the wall fell down, but it wasn't my fault&quot;. Both of those narratives reflect the truth as seen by each party, despite them being different.</p>
<p>If there are obvious things that happened which don't benefit your story, you should still include them (as the landlord certainly will). This shows to the Member that you're not trying to pull a fast one on them, and gives you the opportunity to put them into the context that they happened in, and mitigate their impact.</p>
<p>Lastly, while your narrative should be personal and told to promote the outcome you want, you shouldn't make it emotional or centered around a sob-story. Members see that every day; when you keep emotion out of it, you're showing that you're there for business, and want to be judged on your merits - not ignored as someone who's hoping the law will magically fix their problems.</p>
<p>When you set up your narrative properly, the rest of the process is about selling that narrative to the Member. If they believe yours is what happened, you win - if not, you don't.</p>
<h2 id="documents">Documents</h2>
<p>The Board places a lot of emphasis on communication and timing, so the minute you think something may end up at the Board you should start planning for this. That means trying to keep all discussion between you and the landlord over email, and if you have to have a phone call or in-person meeting, immediately sending them a follow-up email that recounts your version of what was discussed (so you have a <a href="https://en.wikipedia.org/wiki/Dismissal_of_James_Comey#Comey_memos">contemporary record</a> of it). The goal here is to &quot;transform&quot; the conversation into an email so that you can refer to it easier and enter it as evidence. Ideally the landlord agrees with your read-out of the call, but even if not, it's much better than nothing.</p>
<p>You'll also want to prepare a summary spreadsheet of all communications, showing who initiated it, a one-line summary of what was said, and a time. The goal is to show that you're the reasonable and proactive one, and it's the landlord who's not being helpful.</p>
<p>Similarly, it's useful to make a timeline of important events in the process. Include things like when you moved in, when the incident took place, when any important conversations took place, and when any LTB filings happened. This will be helpful when you're debating the exact order things took place in, which can be critical.</p>
<p>Lastly, don't forget any photos or other relevant documents you want to refer to. Things like copies of your lease, articles about your landlord, and repair quotes. Even if they'll also be introduced by the landlord, putting them in your package means you can present them in your context, and use them to tell your narrative. If you've sent them to the landlord in advance - which you should - that's good to mention as well.</p>
<p>Take all these documents, create a simple cover page and table of contents with tabs, and get them bound at a copy shop. Make it look like something you'd give your CEO. This is now the package you'll give to the landlord and Member at the start of your hearing. If you can make most of this package before your hearing and mail it in to the LTB, you'll be in even better shape - as the Member will have read all your evidence without hearing the landlord's side.</p>
<h1 id="thedayofthehearing">The Day of the Hearing</h1>
<p>My application was heard at the LTB's Eastern Office, in Ottawa. It's a non-descript floor of an office building. I arrived about 45 minutes before my hearing was scheduled to start, and there were a few others milling around. Nothing happened until it was 30 minutes before the scheduled start, which was when my notice had told me to show up.</p>
<p>At this point, three things happened:</p>
<ol>
<li>A Commissionaire came out and started taking attendance, having everyone present sign in. You're tracked by your application number, so make sure you have that handy (and in the case where you're there for several applications, you need to sign in for each separately)</li>
<li>The organizer of the tenant duty counsel came out and reminded everyone that there was free legal advice available for tenants</li>
<li>The organizer of the mediation service came out and reminded everyone that mediation is available, should both sides desire it</li>
</ol>
<p>If you elect to both consult the duty counsel and do mediation, don't worry about scheduling - the staff will arrange things so that your mediation spot doesn't happen until after you're done with duty counsel, and your hearing doesn't start until after you're done with mediation. If they miss it and your application gets called early, tell the Member right off the bat and they'll reorder it to give you some time.</p>
<p>My first stop was to sign up for a duty counsel slot - I did this even before they made the announcement, as I saw the sign-up list on a door.</p>
<h2 id="tenantdutycounsel">Tenant Duty Counsel</h2>
<p><a href="http://yourlegalrights.on.ca/organization/tenant-duty-counsel">Duty counsel</a> is a service provided by Legal Aid. In my case, it was a pair of local law students who worked out of the community legal clinic. They did a quick interview to get the facts of my case and a list of specific questions I had, and then went off to speak with their supervising lawyer.</p>
<p>After ten minutes they came back with some general guidance, answers to the specific questions I had asked, and three important new pieces of information:</p>
<ul>
<li>If you're asking for a rent abatement because of loss of enjoyment or use of your unit, you should file a <a href="http://www.sjto.gov.on.ca/documents/ltb/Tenant%20Applications%20&amp;%20Instructions/T2.pdf">Form T2</a> (Application about Tenant Rights) in addition the original form where you ask for the abatement. The content may be the same, but the requests are handled under different standards depending on the form used.</li>
<li>The usual amount given for a rent abatement is 10%-20%. More is possible, but you need to show very strong evidence for it.</li>
<li>If you're asking for compensation for damage for personal belongings, the Board doesn't use strict replacement value - they depreciate the value based on how long you've had the item in question. In my case, this means that I wouldn't be likely to get much for the damage to my table as it's 15+ years old.</li>
</ul>
<p>After I was done with duty counsel, I went to the hearing room to watch some proceedings and get a sense of how things work. On my way in, the mediation organizer stopped me and asked if I'd be interested in mediation. I said yes, and she said that she'd arrange the schedule so we had some time to chat before the application was called.</p>
<h2 id="thehearing">The Hearing</h2>
<p>From speaking to others, I gather this varies a lot between Members adjudicating the hearing. The Member on my day was conversational, but very stern.</p>
<p>After giving both sides a preemptive lecture about how she doesn't take well to interruptions, the Member would ask the applicant to give their side of the story. Every time a document was mentioned, she would ensure that both she and the respondent were given a copy. After a few minutes she'd ask clarifying questions - all-in, each side would get about eight minutes to say their piece. This not a place for grand speeches; the Member was looking for the facts and the narrative around them, and nothing emotional or extra.</p>
<p>Following the applicant, the respondent would be given the chance to tell their side, with the Member asking similar questions - but this time, also to the applicant when the respondent said something that didn't match. Imagine <em>Judge Judy</em>, but taking place in a generic boardroom. Same self-represented feeling, same issues, same type of person leading the hearing while also questioning both sides.</p>
<p>While this is going on, people are coming and going from the hearing room, and the Commissionaire, mediation organizer, and duty counsel organizers are grabbing people. About halfway through the first contested application, it was my time for mediation.</p>
<h2 id="mediation">Mediation</h2>
<p><a href="http://www.sjto.gov.on.ca/documents/ltb/Brochures/Mediation%20by%20the%20Board%20(EN).pdf">Mediation</a> is a free and optional service offered by the LTB to help get the sides to a solution without an actual hearing. It's you, the landlord, and a neutral third-party (who works for the Board) chatting about your application. The mediator will ask questions, let both sides present their perspectives, and try to facilitate the discussion. It's a very informal discussion, with no rules of procedure.</p>
<p>The mediator will have read the application before starting the session, but it'll likely still start with both sides telling their narratives. From there, how it goes depends on the mediator and the positions of both sides.</p>
<p>In the best case, there's an agreement on how to settle the application. The mediator writes up an agreement that both sides sign, and you're done for the day. That agreement isn't an order of the Board, but it is legally binding - so if one side violates it, it's an easier process to come back to and get an order.</p>
<p>In cases where there isn't an overall agreement, the goal of the mediator is to get agreement on smaller things to make the actual hearing more streamlined. In this case the mediator will write out a letter the agreed points and give it to both sides and the Member, and it'll be what opens up the hearing.</p>
<p>If you do mediation, your goal should be to get the other side to make the arguments that they'll make in the hearing, and to see any evidence they'll be presenting. This gives you a bit more time to think about how you'll present your story, and preemptively rebut the positions they'll use. You can also change your approach if it seems like it isn't working, as the mediator isn't allowed to tell the Member about any of the discussions that took place.</p>
<p>In my case, mediation was successful. My mediator reminded both sides about precedents and rules, answered a few questions about what could be changed on the applications, offered perspective on which requests may not fly with the specific Member holding the hearings that day, and prodded appropriately when discussions were breaking down. I walked out of the LTB office with a signed mediation agreement that I was happy with, and was pretty close to what I could have expected to get at a hearing.</p>
<h1 id="tips">Tips</h1>
<ul>
<li><strong>Always file a</strong> <a href="http://www.sjto.gov.on.ca/documents/ltb/Tenant%20Applications%20&amp;%20Instructions/T2.pdf"><strong>Form T2</strong></a> (Application about Tenant Rights). At worst, it'll be rejected by the Member - but if not, it gives you a second chance to make your argument about how the landlord's action is disrupting your &quot;reasonable enjoyment of the rental unit&quot;.</li>
<li>If all your applications are about the same core issue (or if the landlord has also filed something about your issue), <strong>see if you can get them all heard together</strong>. It'll be less of an inconvenience for you, and hearing all the arguments in one sitting makes it easier to tell the your larger story.</li>
<li>You should <strong>address the Member</strong> &quot;Mr./Ms. [last name]&quot; or &quot;Sir/Ma'am&quot;. They're not judges, so no need for &quot;Your Honour&quot; or anything more formal. Most people there will be dressed in <strong>business casual</strong>, including the lawyers &amp; paralegals.</li>
<li>Take advantage of <strong>low expectations</strong>. Most tenants who show up at the LTB are emotional and disorganized, so that's who most landlords and Members expect to deal with. If you show up as organized, rational, and polite-but-firm, you'll send a message to the landlord that you're there for business, and they they can't just make things up and walk all over you.</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Thinking about Envoy]]></title><description><![CDATA[<p><a href="https://lyft.github.io/envoy/docs/index.html">Envoy</a> is the new kid on the block when it comes to <a href="https://lyft.github.io/envoy/docs/intro/what_is_envoy.html">inter-service communication</a>. It has everything you'd want in a smart network, but it'll cost you in terms of <a href="https://lyft.github.io/envoy/docs/install/ref_configs.html#configuration-generator">complexity</a> - and it's likely <a href="https://blog.bradfieldcs.com/you-are-not-google-84912cf44afb">solving a problem you don't really have</a>.</p>
<p>As you do your investigation and prototyping to</p>]]></description><link>https://daniellanger.com/thinking-about-envoy/</link><guid isPermaLink="false">5c4a858f961d3d40d6026796</guid><category><![CDATA[docker]]></category><category><![CDATA[envoy]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Tue, 13 Jun 2017 01:16:53 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://lyft.github.io/envoy/docs/index.html">Envoy</a> is the new kid on the block when it comes to <a href="https://lyft.github.io/envoy/docs/intro/what_is_envoy.html">inter-service communication</a>. It has everything you'd want in a smart network, but it'll cost you in terms of <a href="https://lyft.github.io/envoy/docs/install/ref_configs.html#configuration-generator">complexity</a> - and it's likely <a href="https://blog.bradfieldcs.com/you-are-not-google-84912cf44afb">solving a problem you don't really have</a>.</p>
<p>As you do your investigation and prototyping to help decide if the cost is worth it, I suggest starting with the following question:</p>
<h1 id="amihappywithmyservicediscoverysystem">Am I happy with my service discovery system?</h1>
<p>In many ways, service discovery is at the heart of Envoy. If a product is going to create a mesh between containers and act as a smart communication bus between them, it needs to be able to find all those containers and address them directly.</p>
<p>Directly, here, is critical. Envoy needs something - an <a href="https://lyft.github.io/envoy/docs/intro/arch_overview/service_discovery.html#service-discovery-service-sds">API</a> or a <a href="https://lyft.github.io/envoy/docs/intro/arch_overview/service_discovery.html#logical-dns">DNS server</a> - which can return the IPs of all containers<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> of a particular service. In the <a href="https://lyft.github.io/envoy/docs/intro/arch_overview/service_discovery.html#static">simplest case</a>, this could even be a configuration file in each Envoy container, so long as you have a way to keep it up-to-date.  The IP of a load-balancer isn't sufficient here, as the whole point of Envoy is that it does its own load-balancing across long-running HTTP/2 connections.</p>
<p>If you don't have this, there's a good chance that Envoy is more than you need. For many use-cases, putting containers behind load-balancers and then distributing those load-balancer addresses is a great solution.</p>
<h1 id="really">Really?</h1>
<p>As an example of why service discovery is so core, let's consider how to deploy a new container. In a traditional architecture, we<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> bring a new container online by making an API call to the load-balancer, waiting for health-checks to pass, and making a second API call to drain connections and then remove the old container.</p>
<p>In the world of Envoy - where routing is powered by service discovery - sending traffic to a new container is a side-effect of launching it. Once the new container is running it'll show up in service discovery, which will cause Envoy to start <a href="https://lyft.github.io/envoy/docs/intro/arch_overview/health_checking.html">health-checking</a> it, which will result in it getting traffic. Similarly, terminating the old container will cause it to fall out of service discovery and fail health checks, either of which will cause it to no longer get traffic.</p>
<h1 id="imconvinced">I'm convinced</h1>
<p>Even if you have a <a href="https://www.consul.io/docs/agent/dns.html">great</a> service discovery system in place, Envoy may not be for you. It's a very new piece of technology that was written with some specific problems in mind, and there's a good chance that you don't have those problems. If you think you do, however, it's got some great <a href="https://istio.io/">backers</a> and shows huge promise.</p>
<p>If you don't have a service discovery system in place that you're happy with, you're probably best served by continuing with what you have, or starting with something <a href="http://www.haproxy.org/">simpler</a>. When your system gets complex enough that you've had some other reason to get good at service discovery, then it might be time to take another look at Envoy.</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Envoy is often used with Docker - since it's designed to support <a href="https://lyft.github.io/envoy/docs/intro/arch_overview/terminology.html#terminology">hosts</a> appearing and disappearing at will - but this equally applies to VMs or instances. All Envoy requires is that each host be independently addressable. <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>Through scripts, via automated services like CloudFormation's <a href="http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html">rolling update</a>, by platforms like <a href="http://docs.aws.amazon.com/AmazonECS/latest/developerguide/update-service.html">ECS</a>, etc. <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[Zero-downtime Deploys with CloudFormation]]></title><description><![CDATA[Using an UpdatePolicy with an AWS CloudFormation stack to achieve a zero-downtime deploy correctly is more difficult than you'd think; here's how.]]></description><link>https://daniellanger.com/zero-downtime-deploys-with-cloudformation/</link><guid isPermaLink="false">5c4a858f961d3d40d6026795</guid><category><![CDATA[aws]]></category><category><![CDATA[cloudformation]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Sat, 12 Mar 2016 15:55:51 GMT</pubDate><content:encoded><![CDATA[<p><strong><em>NOTE: This article was written in 2016, and has not been updated since. You should not assume that it's still state-of-the-art or accurate</em></strong></p>
<p>Zero-downtime deploys - the ability to release a new version of your code to production without taking the site down - are a key component of continuous delivery.</p>
<p>In the early days of AWS, this was a pain to do. We had auto-scaling groups (ASGs) that didn't play that well with ELBs, and you often ended up having to build tooling to do what seemed like a simple operation: &quot;Update the instances in this ASG to use the launch configuration it now has&quot;. In theory, this changed with the <a href="https://aws.amazon.com/blogs/aws/three-new-features-for-aws-cloudformation/">release</a> of the <code>UpdatePolicy</code> attribute on an ASG. From the blog post:</p>
<blockquote>
<p>Today’s new feature allows you to perform a rolling deployment of an Auto Scaling Group within a CloudFormation stack. Instead of updating all of the instances in a group at the same time, you can now replace or modify the instances in a step-by-step fashion...This feature will increase availability of your application during an update.</p>
</blockquote>
<p>The part before the ellipsis - updating instances in a step-by-step fashion - works quite well. The part after - increasing availability - doesn't, unless you use this in a very particular way. Before explaining why, I'll step back a second and explain how I expected this to work.</p>
<p>Let's assume I'm building a feature to increase availability during a deploy. My building blocks are:</p>
<ol>
<li>A load-balancer with a <a href="http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-healthchecks.html">robust</a> health-check mechanism</li>
<li>A scaling system which <a href="http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html">knows how to use</a> the health-check of a load balancer to decide if an instance it's managing is healthy or not</li>
<li>A way to <a href="http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html">configure</a> the scaling system to gradually add new instances into the scaling pool, and rotate the old ones out</li>
<li>A desire to <a href="https://aws.amazon.com/blogs/aws/three-new-features-for-aws-cloudformation/">build something</a> called <em>Rolling Deployments of Auto Scaling Groups</em></li>
</ol>
<p>My expectation would be that the scaling system (#2) would make full use of the health-check (#1) when deciding if a new instance has been launched successfully, before moving on (#3) to launching the next one. This would be a rolling deploy (#4), and one that works very hard to &quot;increase availability during an update&quot;.</p>
<p>In concrete terms: when rolling the instances of an ASG that's connected to an ELB in an operation governed by an <code>UpdatePolicy</code>, I'd expect the ASG to use the full power of the ELB's health-check to decide when to move on to the next instance.</p>
<p><strong>This doesn't happen.</strong> If expect it to, you'll likely experience some downtime when doing a CloudFormation <code>UPDATE</code> operation that replaces the instances.</p>
<h1 id="itworkshow">It works how?</h1>
<p>What happens instead is that the ASG adds the instance to the ELB immediately on it getting into the <code>InService</code> state (meaning the instance has booted). The ASG then ignores its own setting for <code>HealthCheckGracePeriod</code>, and starts counting the health-check failures (coming from the ELB health-check). This means that if the time your health-check settings will tolerate a non-responsive instance is less than the time it takes for your instance to be ready to serve requests (after it's done booting), the ASG will drop that newly-created instance. While this is happening, the <code>UpdatePolicy</code> rolling update will continue - which could very easily leave you with no working instances in the ELB.</p>
<p>As AWS support puts it:</p>
<blockquote>
<p>Although you are using an ELB health-check, unfortunately as part of the rolling update process CloudFormation does not check that the instance has been marked as in-service behind the ELB. I do agree that when an environment is configured to use an ELB health-check, just relying on the fact that the instance has been added to the ASG is not a sufficient success criteria for rolling updates. There is currently a feature request logged with regard to this...there is currently no ETA.</p>
</blockquote>
<p>And subsequently:</p>
<blockquote>
<p>As soon as that new instance is started up and marked as in service in the AutoScaling group (fairly quickly), the ELB starts its health-checks.</p>
</blockquote>
<p>What makes this even more frustrating is that all these pieces work together <em>perfectly</em> on non-CloudFormation auto-scaling operations. If one of my instances crashes the ASG will spin up a new one, add it to the ELB, and respect the <code>HealthCheckGracePeriod</code> during start-up.</p>
<p>Way to violate the principle of least-surprise there, AWS.</p>
<h1 id="whatnow">What now?</h1>
<p>Getting past the disappointment this doesn't work, we still need a zero-downtime deploy solution.</p>
<p>The easiest thing to do is to extend the value for <code>PauseTime</code> in your <code>UpdatePolicy</code> to longer than it takes for an instance to move from a &quot;booted&quot; to &quot;ready to serve web requests&quot;. Here, <code>PauseTime</code> governs the wait between adding in new instances and removing the old ones. That transition from &quot;booted&quot; to &quot;serving&quot; still needs to take less time than your &quot;bad-instance&quot; window (which comes from your health-check settings), but if it doesn't, you'll still have the old instances running to serve requests that come in.</p>
<p>The &quot;official&quot; solution is to use <code>WaitOnResourceSignal</code>, which pauses the rolling update until the instance uses <code>cfn-signal</code> to signal that it's in a good state - here's their example <a href="https://s3-us-west-2.amazonaws.com/cloudformation-templates-us-west-2/ELBGuidedAutoScalingRollingUpgrade.template">template</a>.</p>
<h1 id="inclosing">In closing</h1>
<p>This whole piece could be summed up with &quot;it's bad that CloudFormation <code>UpdatePolicy</code> rolling updates don't respect the ELB health check&quot;, and it really is. I can't imagine the product decision that got AWS here, and I'm not staying up late to wait for the fix.</p>
<p>There's something funny in this, though. If you read the example <a href="https://s3-us-west-2.amazonaws.com/cloudformation-templates-us-west-2/ELBGuidedAutoScalingRollingUpgrade.template">template</a> for how to work around this with <code>cfn-signal</code>, their example <code>cloud-init</code> configuration won't sent the OK signal until...a check on instance's ELB health (using the AWS CLI) comes back successful.</p>
<p>It's almost as if they knew how this whole thing should fit together, and then built something else.</p>
]]></content:encoded></item><item><title><![CDATA[Terraform]]></title><description><![CDATA[<p>The first step of using <a href="https://aws.amazon.com/">AWS</a> is to build your servers and your network by hand, using the management console. This works fine...at first. Then you'll end up forgetting how to build a certain <a href="https://blog.engineyard.com/2014/pets-vs-cattle">pet</a>, or your colleague will click the wrong option and take your system down, or</p>]]></description><link>https://daniellanger.com/terraform/</link><guid isPermaLink="false">5c4a858f961d3d40d6026794</guid><category><![CDATA[aws]]></category><category><![CDATA[terraform]]></category><category><![CDATA[devops]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Sun, 31 Jan 2016 23:20:50 GMT</pubDate><content:encoded><![CDATA[<p>The first step of using <a href="https://aws.amazon.com/">AWS</a> is to build your servers and your network by hand, using the management console. This works fine...at first. Then you'll end up forgetting how to build a certain <a href="https://blog.engineyard.com/2014/pets-vs-cattle">pet</a>, or your colleague will click the wrong option and take your system down, or you'll want to have two of something, and you'll realize that it's about time you control this mess in code.</p>
<p>At this point, you'll noticed that AWS has several products for this, which seem to all do almost the same thing. You've got:</p>
<ul>
<li><a href="https://aws.amazon.com/cloudformation/">CloudFormation</a>, which is the combination of a JSON DSL to create templates and a service to realize them</li>
<li><a href="https://aws.amazon.com/opsworks/">OpsWorks</a>, which is <a href="https://www.chef.io/chef/">Chef</a> with some AWS resources added into it</li>
<li><a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/Welcome.html">Elastic Beanstalk</a>, which is AWS' version of Heroku</li>
</ul>
<p>But you've also got <a href="https://www.terraform.io/">Terraform</a>, which is unlike the others in that it's not built by AWS.</p>
<p>I've been using CloudFormation for about a year and a half, having built my own set of libraries and tooling using <a href="https://github.com/cloudtools/troposphere">Troposphere</a> - so I'm working in Python, and then converting to JSON at the end. I've been happy with this, but several of my colleagues have gotten excited about Terraform - which suggested it was time to give it another look.</p>
<p>Having spent a day rebuilding a simplified version of our current infrastructure on it, some thoughts:</p>
<h3 id="thegood">The Good</h3>
<ul>
<li>There was a lot less copy/paste than I expected. Python's list comprehensions are terse enough that I can condense many networking rules down into a few lines. While that's not an option here (no loops in a declarative language), the copy/paste required to get the same rules wasn't that annoying, and would be hidden behind the first layer of modules.</li>
<li>Terraform's ability to undo things you've done in the console is outstanding. One of the weaknesses of CloudFormation is that it ignores any manual changes you've made to the infrastructure once it's been launched, whereas Terraform lets you reset any hand-configured settings back to what the code says.</li>
<li>New AWS products (like <a href="https://aws.amazon.com/blogs/aws/new-managed-nat-network-address-translation-gateway-for-aws/">NAT Gateways</a>) get added into Terraform before CloudFormation, since Terraform uses their vanilla APIs. On the downside, there are a few AWS features that aren't exposed outside of CloudFormation - so Terraform can't use them.</li>
</ul>
<h3 id="theok">The OK</h3>
<ul>
<li>One of the big gripes we have with our in-house libraries is that building things takes a lot of proprietary knowledge. Once you've built up a tier of in-house Terraform modules, though, I suspect you'd end up in the same place.</li>
<li>The documentation is about the same level as CloudFormation's, although I'd often find myself looking at the docs for the matching AWS function to really understand what a particular argument meant.</li>
<li>Most of the cases where we change the system between production and development seem like they could be handled with variables. There are a few that don't have obvious solutions, but that could also be a sign that we shouldn't be doing that.</li>
<li>The workflow (and some of the issues around <code>apply</code>) strongly suggests that Terraform is designed for blue-green deploys, which aren't always the right answer.</li>
<li>Terraform uses the full &quot;path&quot; of a module to track it, meaning that refactoring some code that doesn't change the underlying infrastructure will cause a change so that Terraform can &quot;keep up&quot;. Coming from Troposphere, I was used to the code being an abstraction that generated a plan at the end - as opposed to the code being the plan.</li>
</ul>
<h3 id="thebad">The Bad</h3>
<ul>
<li>Several times I found that I had created a system that I couldn't destroy, which centered around <a href="https://github.com/hashicorp/terraform/issues/2359">this issue</a>. Even following the work-around in there - which seems like a hack - <code>destroy</code> often found cycles which made it necessary for me to manually destroy bits of the system through the console.</li>
<li>The design of the <a href="https://www.terraform.io/docs/modules/usage.html">module system</a> (and tooling - I'm looking at you, <code>terraform get</code>) gets frustrating when you're trying to use them for information-hiding and internal code-reuse, as opposed to for sharable units.</li>
<li>Not being able to pass <a href="https://github.com/hashicorp/terraform/issues/1336">maps to modules</a> got old. I had hoped to use a pattern of passing a mapping (e.g. &quot;environment type to instance size&quot;) and a variable (e.g. &quot;environment type&quot;) to modules and letting them figure out/hide which value to use; instead, this had to be done at the caller level.</li>
<li>When there's an error executing the plan Terraform generates - which happened more than I expected - it doesn't roll back what it was trying to do. This is intentional (and <a href="https://www.terraform.io/intro/getting-started/provision.html">clearly stated</a>) and while I like it intellectually, it puts me at a higher risk of leaving my production system in a half-changed state, and my having to troubleshoot while I'm down. This is doubly worrying because the most common suggestion for how to fix this is &quot;just run it again and see what happens&quot;. I much prefer CloudFormation's automated rollbacks, guaranteeing I end up in a known-good state on a failed change.</li>
<li>Terraform doesn't support <a href="http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html"><code>UpdatePolicy</code></a>, so you need to use a bit of a <a href="https://github.com/hashicorp/terraform/issues/1552">hack</a> to gracefully rotate new instances into an auto-scaling group. This isn't their fault - that API isn't exposed by AWS - but their solution isn't great, and doesn't really work on auto-scaling groups that aren't attached to load balancers.</li>
<li>I'm still not sure how I'd handle stateful things like RDS instances in a Terraform world. There are all sorts of reports that this litters your <code>.tfstate</code> with credentials (although I didn't try it personally), and I'm not confident that the planner wouldn't one day try and destroy the instance as a side-effect to some innocuous change.</li>
</ul>
<h3 id="so">So?</h3>
<p>After all that, I'm still glad I spent the day on Terraform. I used to think it was a bad idea; now I think it's a good idea, albeit one that's not yet ready.</p>
<p>The product is miles better than when I tried it a year ago, and it has - when they work - some seriously compelling features.  But would I use it in production to manage a network? Not yet.</p>
]]></content:encoded></item><item><title><![CDATA[Moving]]></title><description><![CDATA[<p>Moving is a stressful. If there's one thing that <a href="http://camparowhon.com/">Joanne &amp; Co.</a> taught me it's that nesting is important, and even more so when you're an adult and you're moving your entire life around (as opposed to your sleeping bag for a month).</p>
<p>Things I did to make it less</p>]]></description><link>https://daniellanger.com/moving/</link><guid isPermaLink="false">5c4a858f961d3d40d6026792</guid><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Sun, 23 Aug 2015 01:30:53 GMT</pubDate><content:encoded><![CDATA[<p>Moving is a stressful. If there's one thing that <a href="http://camparowhon.com/">Joanne &amp; Co.</a> taught me it's that nesting is important, and even more so when you're an adult and you're moving your entire life around (as opposed to your sleeping bag for a month).</p>
<p>Things I did to make it less stressful:</p>
<ul>
<li>
<p>Used <a href="http://www.augustamovers.ca/">Augusta Movers</a>. They weren't the cheapest of the companies I surveyed, but the owner was super-responsive, it was very easy to set up, the team was punctual and hard-working, and they did a great job packing things up. They also stressed in every email that you have to pay HST even if you're paying cash, which I appreciate. At no point in the process were there any surprises, which is about the highest compliment you can pay to movers.</p>
</li>
<li>
<p>Ordered <a href="http://frogbox.com/toronto">Frogboxes</a> plastic boxes, as opposed to buying or scavenging cardboard ones. You're an adult now; you can do better going to the LCBO every day and getting Alberta Premium boxes. These things are clean, strong, convenient, water-repellent, and easy to move. You can put fragile things in them and not worry they'll be crushed, you can half-fill them and they'll still stack, and they make loading and unloading a breeze - they stack perfectly and uniformly. They'll end up costing a little more than cardboard boxes (~10% in my case), but not having to deal with the mess and cleanup of all that cardboard made it worth it in a second.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[On Coleslaw]]></title><description><![CDATA[<p>Coleslaw is serious business around the Cottage, and is a side-dish for almost every meal we prepare. Pesto with a side of coleslaw? Steak with a side of coleslaw? Pizza with a side of coleslaw? The possibilities are endless.</p>
<p>As a result of this, my father and I have spent</p>]]></description><link>https://daniellanger.com/on-coleslaw/</link><guid isPermaLink="false">5c4a858f961d3d40d6026791</guid><category><![CDATA[bbq]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Sat, 25 Jul 2015 22:45:06 GMT</pubDate><content:encoded><![CDATA[<p>Coleslaw is serious business around the Cottage, and is a side-dish for almost every meal we prepare. Pesto with a side of coleslaw? Steak with a side of coleslaw? Pizza with a side of coleslaw? The possibilities are endless.</p>
<p>As a result of this, my father and I have spent several summers worth of testing all the vinegar-based<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> coleslaw recipes we could find - and our favourite came from, of all places, <a href="https://www.about.com">about.com</a>. It's not overly sweet, it goes (well) with everything you'd want to eat in the summer, and it can stand up to the strong barbecue flavours that come off the grill. It also ages well, which is handy for logistics.</p>
<p>Our coleslaw recipie, modified from <a href="http://southernfood.about.com/od/coleslawcabbagesalads/r/bl90612a.htm">about.com's Carolina Slaw</a>:</p>
<blockquote>
<h4 id="coleslaw">Coleslaw</h4>
</blockquote>
<p>1 large head of cabbage, finely shredded<br>
1 red pepper, finely chopped<br>
1 medium onion, finely chopped<br>
2 carrots, grated<br>
1 Jalapeno pepper, finely sliced</p>
<blockquote>
<p> </p>
</blockquote>
<p>1 cup cider vinegar<br>
2/3 cup vegetable oil<br>
1/2 cup white sugar<br>
1 tsp. salt<br>
3 tsp. celery seed<br>
1 tsp. dry mustard powder<br>
1/4 tsp. pepper</p>
<blockquote>
<p> </p>
<p>Combine all vegetables into a large bowl. Combine all dressing ingredients into a small pot, and simmer until everything except the celery seed has dissolved (about 10 minutes). Pour dressing onto vegetables and refrigerate for at least a day, stirring twice a day.</p>
</blockquote>
<p>This is eminently edible after an hour or two in the fridge, but is at it's best after about two days.</p>
<p>If you're having surprise guests and need more, add some cabbage into what's left in the main bowl and stir it around some. You can also add in any similar fresh vegetables you have - I've had good results adding in half a head of thinly-sliced fennel. Lastly, if you'd like to take your shredding/chopping game up a notch, a <a target="_blank" href="http://www.amazon.ca/gp/product/B003CN6Q1Y/?ie=UTF8&camp=15121&creative=330641&linkCode=ur2&tag=dlanger-20">mandoline</a> makes quick work of all the vegetables here.</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Mayonnaise-based coleslaw isn't something to even bring up here. <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[Miss Piggy Mustard Sauce]]></title><description><![CDATA[<p>I'm not sure why you'd buy barbecue sauce, given that doing it yourself takes 15 minutes, has one basic pattern (ketchup/mustard + vinegar + seasonings), and avoids all the nasty aftertastes you get from store-bought ones.</p>
<p>This is my go-to recipe when I don't want to try something new, only slightly</p>]]></description><link>https://daniellanger.com/miss-piggy-mustard-sauce/</link><guid isPermaLink="false">5c4a858f961d3d40d6026790</guid><category><![CDATA[bbq]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Sun, 19 Jul 2015 19:29:19 GMT</pubDate><content:encoded><![CDATA[<p>I'm not sure why you'd buy barbecue sauce, given that doing it yourself takes 15 minutes, has one basic pattern (ketchup/mustard + vinegar + seasonings), and avoids all the nasty aftertastes you get from store-bought ones.</p>
<p>This is my go-to recipe when I don't want to try something new, only slightly adopted from <a href="http://tvwbb.com/showthread.php?39043-Miss-Piggy-Mustard-Sauce">Virtual Weber Bullet forums</a>:</p>
<blockquote>
<h4 id="misspiggymustardsauce">Miss Piggy Mustard Sauce</h4>
</blockquote>
<p>1 cup generic yellow mustard<br>
1/4 cup white sugar<br>
1/4 cup light brown sugar<br>
1/2 cup cider vinegar<br>
2 tbsp. chili powder<br>
1 tsp. Cayenne pepper<br>
1 tsp. ground black pepper<br>
1 tsp. white pepper<br>
1 tbsp. dark soy sauce<br>
2 tbsp. butter</p>
<blockquote>
<p> </p>
<p>Combine all ingredients except soy sauce and butter, adding vinegar last (to desired thickness). Simmer for 10 minutes, then remove from heat and add butter and soy sauce.</p>
</blockquote>
<p>A couple of notes, for when you're making it your own:</p>
<ul>
<li>I like to use Chipotle chili powder for a bit of a smokey taste, but try all the ones you can find to pick which one works for you.</li>
<li><a href="http://www.chow.com/food-news/138263/whats-the-difference-between-black-and-white-pepper/">Traditionally</a>, white pepper is used to not discolour sauces - which clearly doesn't apply here. You could almost certainly just use more black pepper and not miss much, but the original recipe called for both (so I use both).</li>
</ul>
<p>Despite this being a mustard-based sauce (traditionally from <a href="http://foodformyfamily.com/recipes/homemade-south-carolina-style-mustard-barbecue-sauce-bbq">South Carolina</a>), it'll end up looking almost as dark as a ketchup-based on - but you'll definitely taste the lack of a tomato base.</p>
]]></content:encoded></item><item><title><![CDATA[On "AWS Best Pracices for DDOS Resiliency"]]></title><description><![CDATA[<p><em><strong>2019 Update</strong>: AWS has updated the whitepaper since this post was written, and has introduced a few new features that make life easier - like NAT Gateways and a less-bad interface to CloudWatch logs. Please cross-check this post with more up-to-date resources before making decisions.</em></p>
<p>Amazon recently published a set</p>]]></description><link>https://daniellanger.com/aws-best-pracices-for-ddos-resiliency/</link><guid isPermaLink="false">5c4a858f961d3d40d602678f</guid><category><![CDATA[aws]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Sun, 05 Jul 2015 03:03:12 GMT</pubDate><content:encoded><![CDATA[<p><em><strong>2019 Update</strong>: AWS has updated the whitepaper since this post was written, and has introduced a few new features that make life easier - like NAT Gateways and a less-bad interface to CloudWatch logs. Please cross-check this post with more up-to-date resources before making decisions.</em></p>
<p>Amazon recently published a set of <a href="http://d0.awsstatic.com/whitepapers/DDoS_White_Paper_June2015.pdf">best practices</a> for building your AWS environment in a way to handle DDOS attacks. While the document is a great start and should be required reading when designing an environment, it's lacking in a few meaningful places - each section corresponds to a guideline of the same name.</p>
<h4 id="minimizetheattacksurfacearea">Minimize the Attack Surface Area</h4>
<p>Or put another way, &quot;put the same diligence into designing your AWS network as you would a physical network.&quot; This is a great point and one which shouldn't be ignored, however the only pieces of advice in this section boil down to <em>Use a VPC</em> and <em>Use one of the four <a href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenarios.html">VPC scenarios</a></em>, which are as standard AWS advice as they'll give you anywhere.</p>
<p>So which scenario should you use?</p>
<p>AWS will rarely answer this question directly, because answering it in a way that makes sense for all systems would be <em>really</em> hard. But if you make a few simplifying assumptions - like I will momentarily - the answer becomes much easier. We'll assume:</p>
<ol>
<li>
<p>You're building a pretty standard web application - some app servers, a few workers for async processing, a cache or two, and a database.</p>
</li>
<li>
<p>You don't need a hardware VPN, because your entire application will live inside AWS (or the parts outside can be reached via HTTPS/TLS).</p>
</li>
</ol>
<p>That leaves <a href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenarios.html">scenarios</a> one and two, which could be summarized as <em>Give everything a public IP<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></em> and <em>Have a private subnet where your app servers &amp; workers don't have public IPs<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></em>. In an ideal world, the second solution is better. You can't attack a machine which doesn't have a world-routable IP, you can monitor everything going out of the private network on the NAT, security groups are striaghtforwards, etc. All of these points are true, but they miss one key thing (which I feel AWS does a poor job of highlighting):</p>
<p>AWS NATs aren't first-class objects.</p>
<p>The way they're mentioned in passing and have their own icon in AWS drawings<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>, you could be led to think that they're things you can create in CloudFormation, and maybe you just haven't yet found the docs for them. You'd be wrong if you thought that. AWS NATs are standard EC2 instances which you boot using an <a href="http://thecloudmarket.com/search?search_term=amzn-ami-vpc">AMI</a> provided by AWS, which are really just stock Amazon Linux machines that <a href="http://mike-kirk.blogspot.ca/2013/12/amazon-ec2-vpc-nat-instances.html">run a script</a> on boot. AWS does no management of them for you above and beyond what they do on any other instance you launch.</p>
<p>This is troublesome, as it means that upgrading a NAT is now a downtime event for the app servers behind it (if they reach out to any services outside of your network). It also means that if you're going for an environment that manages itself as much as possible, you need to put that NAT instance into a auto-scaling group, and then do some scripting to update the routing tables when an instance boots<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>. Lastly, if you're in a situation where for compliance (or other) reasons you need to keep an inventory of system components and installed software, these instances will fall under that regime.</p>
<p>So what do I recommend? Sadly, it's what AWS calls <em><a href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario1.html">Scenario 1</a></em>: put all your instances into a public subnet, and then use security groups to make sure that only specific boxes accept connections from outside the network. Your attack surface is larger (as everything has public IPs), but you've mitigated that risk with proper controls.</p>
<h4 id="bereadytoscaleandabsorbtheattack">Be Ready to Scale and Absorb the Attack</h4>
<p>Their advice here could be summarized as <em>Use ELBs<sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup> for your app servers, DNS which won't go down, and a CDN.</em></p>
<p>The DNS and CDN sections aren't worth much further discussion, aside from the fact that AWS CloudFront is only an OK CDN (I much prefer <a href="https://www.fastly.com/">Fastly</a>), and that there are other DNS providers out there beyond Route53 - although it does play extra-nice with ELBs.</p>
<p>Their advice about using an auto-scaling group behind an ELB is well-intentioned and correct, but mentions only in passing that <em>[additional] instances may increase your costs</em> - which is the biggest risk you face using this setup. Unless you're careful with your auto-scaling rules, an auto-scaling group will keep spinning up and spinning up instances in the face of a DDOS attack - and you'll lose if you try and outspend a DDOS attack.</p>
<p>Although they don't talk about it since it's not their product, this is the natural place where the document should suggest looking into vendors like <a href="https://www.cloudflare.com/ddos">CloudFlare</a> or <a href="http://pages.incapsula.com/enterprise-ddos-protection/">Incapsula</a> to handle this for you.</p>
<h4 id="safeguardexposedresources">Safeguard Exposed Resources</h4>
<p>This section is mostly a grab-bag of other product offerings AWS would like you to use.</p>
<p>There's an extensive section about deploying web application firewalls on here, but that suffers from the same risks discussed earlier around trying to outspend a DDOS attach - if you put WAF nodes into an auto-scaling group (as it suggests), you'll spend all your money scaling up that group...as opposed to the app servers. Same result (the attacker makes you spend more, triggered by an auto-scaling rule), but a different and more expensive one, as WAF AMIs generally charge by the hour.</p>
<p>Again, the best advice to safeguard exposed resources would be to put them behind something like CloudFlare, so they're exposed to someone else's network and not yours.</p>
<h4 id="learnnormalbehavior">Learn Normal Behavior</h4>
<p>You should definitely do this, but I've never been satisfied by CloudWatch, their suggested way of doing it.</p>
<p>Does CloudWatch record all the things it says it records? Yes.<br>
Will you have a good time dealing with that data? Nope.</p>
<p>If you're serious about understanding what your system is doing at any point in time, you should find a vendor/product that just focuses on that - they are both hard enough domains as-is. For performance monitoring, I love <a href="http://newrelic.com/">New Relic</a> - it's not cheap, but monitoring instance health is the only thing they focus on, and I've never not felt like I've gotten positive ROI on it (with room to spare). For application-level logging I prefer <a href="https://logentries.com/">LogEntries</a>, but try the demos in this area - there are a few distinct approaches to this problem, and you should pick the one that matches your thinking.</p>
<p>Having said all that, I'll applaud AWS for saying you should put an alert on the <code>EstimatedCharges</code> metric, which tracks your estimated monthly bill. If you do nothing else, <strong>do this right now</strong>.</p>
<h4 id="createaplanforattacks">Create a Plan for Attacks</h4>
<p>This is a great idea, but not in the way they're suggesting.</p>
<p>Sure, having an AWS TAM<sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup> will help a little when you're in the midst of an attack (and paying for <a href="https://aws.amazon.com/premiumsupport/">business-level support</a> is a great investment, especially when getting started), the biggest return will come from having a plan in place before things happen, and having tested it a few times in a tabletop exercise. How this will work is very organization-specifc, but Heroku's <a href="https://blog.heroku.com/archives/2014/5/9/incident-response-at-heroku">incident response framework</a> is a great start.</p>
<h4 id="conclusion">Conclusion</h4>
<p>Building a system that's completely DDOS-resistant is impossible, and likely not worth the time even if it was.</p>
<p>As opposed to trying to beat script kiddies all day every day, you're much better off accepting that a successful DDOS attack<sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup> will eventually happen, and coming up with a plan about what to do when that day comes. I'd start with making sure that all parts of your organization can agree on answers to the following questions, focusing on when you're being attacked:</p>
<ul>
<li>Who's in control internally, and what do we expect of them?</li>
<li>How much of an attack do we expect to be able to stand up against?</li>
<li>How open will we be with our users, and what will their experience be?</li>
<li>How can other parts of the organization support the effort?</li>
</ul>
<p>It's worth highlighting that none of the points above have much to do with technology, which is intentional. DDOS attacks are scary and stressful times, and your societal/interpersonal problems will be the dominant factors. Get those right - with practice, honestly, and communication - and you'll have the space needed to deal with the technical ones.</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><a href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario1.html">Scenario 1: VPC with a Public Subnet Only</a> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p><a href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario2.html">Scenario 2: VPC with Public and Private Subnets</a> <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p>Like <a href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/images/nat-instance-diagram.png">this one</a>, from scenario 2 <a href="#fnref3" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn4" class="footnote-item"><p>There's a <a href="http://aws.amazon.com/articles/6079781443936876">CloudFormation template</a> available to build an HA NAT, but it's always seemed like overkill to me <a href="#fnref4" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn5" class="footnote-item"><p><a href="http://aws.amazon.com/elasticloadbalancing/">Elastic Load Balancers</a>; the AWS managed load balancer product <a href="#fnref5" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn6" class="footnote-item"><p>Technical Account Manager; the person who manages your relationship with AWS paid support <a href="#fnref6" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn7" class="footnote-item"><p>Or any kind, really - the advice doesn't change <a href="#fnref7" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[Upgrading Ghost on WebFaction]]></title><description><![CDATA[<p>This installation is running on WebFaction (using their automated installer), and I often forget how to do minor version bumps.</p>
<p>From <a href="http://legobot.uk/2013/10/29/installing-ghost-on-webfaction/">Craig Butcher</a>, whose site goes up and down:</p>
<blockquote>
<ol>
<li>Jump the directory where Ghost is installed -<br>
<code>cd ~/webapps/appname/ghost</code></li>
<li><code>wget</code> the <a href="https://ghost.org/download/">newest release</a> and unzip it - <code>unzip</code></li></ol></blockquote>]]></description><link>https://daniellanger.com/upgrading-ghost-on-webfaction/</link><guid isPermaLink="false">5c4a858f961d3d40d602678e</guid><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Sun, 28 Jun 2015 19:01:40 GMT</pubDate><content:encoded><![CDATA[<p>This installation is running on WebFaction (using their automated installer), and I often forget how to do minor version bumps.</p>
<p>From <a href="http://legobot.uk/2013/10/29/installing-ghost-on-webfaction/">Craig Butcher</a>, whose site goes up and down:</p>
<blockquote>
<ol>
<li>Jump the directory where Ghost is installed -<br>
<code>cd ~/webapps/appname/ghost</code></li>
<li><code>wget</code> the <a href="https://ghost.org/download/">newest release</a> and unzip it - <code>unzip -uo ghost-0.6.5.zip</code></li>
<li>Update <code>npm</code> - <code>../bin/npm install --production</code> (and don't worry if you get a warning that <code>forever</code> should be installed globally with <code>-g</code> - WebFaction already did this for you)</li>
<li>Restart Ghost - <code>../bin/stop &amp;&amp; ../bin/start</code></li>
</ol>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[PyCon 2014]]></title><description><![CDATA[<p>Ever wonder how a request gets from your computer, out to the internet, and then back as a response? I did, so I decided to talk about it at PyCon 2014</p>
<p>This is the story (<a href="https://speakerdeck.com/dlanger/a-scenic-drive-through-the-django-request-response-cycle">slides</a>) of how pressing &quot;Enter&quot; on a <code>curl</code> command gets you something back.</p>]]></description><link>https://daniellanger.com/pycon-2014/</link><guid isPermaLink="false">5c4a858f961d3d40d6026793</guid><category><![CDATA[python]]></category><dc:creator><![CDATA[Daniel Langer]]></dc:creator><pubDate>Wed, 23 Apr 2014 16:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Ever wonder how a request gets from your computer, out to the internet, and then back as a response? I did, so I decided to talk about it at PyCon 2014</p>
<p>This is the story (<a href="https://speakerdeck.com/dlanger/a-scenic-drive-through-the-django-request-response-cycle">slides</a>) of how pressing &quot;Enter&quot; on a <code>curl</code> command gets you something back.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/q0YqAbI7rw4?start=148" frameborder="0" allowfullscreen></iframe>]]></content:encoded></item></channel></rss>