<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oleg Chursin</title>
    <description>The latest articles on DEV Community by Oleg Chursin (@olegchursin).</description>
    <link>https://dev.to/olegchursin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F142811%2F6f4ef624-3f7b-4684-9156-470980ed0732.png</url>
      <title>DEV Community: Oleg Chursin</title>
      <link>https://dev.to/olegchursin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olegchursin"/>
    <language>en</language>
    <item>
      <title>Mastering CSS Balance: "text-wrap: balance"</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Mon, 23 Oct 2023 14:44:51 +0000</pubDate>
      <link>https://dev.to/olegchursin/mastering-css-balance-text-wrap-balance-3g21</link>
      <guid>https://dev.to/olegchursin/mastering-css-balance-text-wrap-balance-3g21</guid>
      <description>&lt;p&gt;When it comes to web design, one aspect that often requires careful consideration is how text flows within a layout. While CSS offers various properties to control text wrapping and line breaking, the &lt;code&gt;text-wrap&lt;/code&gt; property stands out for its unique approach to handling long strings of text. In this blog post, we'll delve into the &lt;code&gt;text-wrap&lt;/code&gt; property, with a specific focus on &lt;code&gt;text-wrap: balance&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Text-Wrap
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;text-wrap&lt;/code&gt; property, introduced in CSS3, is a valuable tool for controlling how text wraps within its containing element. It allows you to specify how text should break and wrap when it encounters the edge of its container. The property can take several values, including &lt;code&gt;wrap&lt;/code&gt;, &lt;code&gt;nowrap&lt;/code&gt;, &lt;code&gt;balance&lt;/code&gt;, &lt;code&gt;stable&lt;/code&gt;, &lt;code&gt;pretty&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text-wrap = 
  wrap     |
  nowrap   |
  balance  |
  stable   |
  pretty   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap#formal_syntax"&gt;MDN: text-wrap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Chursin/embed/ExraamB?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;text-wrap: balance&lt;/code&gt; Value
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;text-wrap: balance&lt;/code&gt; value is a relatively lesser-known aspect of the &lt;code&gt;text-wrap&lt;/code&gt; property, but it can significantly impact how text is presented on your web page. This value is especially useful when dealing with narrow columns of text, as it optimizes the text distribution to maintain a balanced appearance.&lt;/p&gt;

&lt;p&gt;By setting &lt;code&gt;text-wrap&lt;/code&gt; to &lt;code&gt;balance&lt;/code&gt;, you are instructing the browser to distribute the text within the container, avoiding uneven gaps between lines and achieving a more uniform appearance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of &lt;code&gt;text-wrap: balance&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Now, let's explore some of the key advantages of using &lt;code&gt;text-wrap: balance&lt;/code&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Improved Readability
&lt;/h3&gt;

&lt;p&gt;Balanced text wrapping helps enhance the readability of your content. By minimizing uneven gaps and preventing overly long lines, users can smoothly read through your text without feeling overwhelmed or distracted.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Enhanced Aesthetics
&lt;/h3&gt;

&lt;p&gt;Aesthetics are crucial in web design, and balanced text wrapping plays a significant role in achieving a polished and professional look. It prevents the visual clutter that can occur with irregular text distribution.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Consistency Across Devices
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;text-wrap: balance&lt;/code&gt; can be particularly helpful in creating a consistent reading experience across different devices and screen sizes. It ensures that text remains visually appealing and legible, whether your audience is viewing your content on a large desktop monitor or a small mobile screen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pretty vs. Balance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;text-wrap:pretty&lt;/code&gt; avoids typographic orphans,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text-wrap:balance&lt;/code&gt; tries to make the lengths of all lines balanced as much as possible.
Source: &lt;a href="https://docs.google.com/document/d/1jJFD8nAUuiUX6ArFZQqQo8yTsvg8IuAq7oFrNQxPeqI/edit"&gt;Design docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Browser Compatibility
&lt;/h2&gt;

&lt;p&gt;Before fully implementing &lt;code&gt;text-wrap: balance&lt;/code&gt;, it's essential to check the browser compatibility. &lt;code&gt;text-wrap: balance&lt;/code&gt; property is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap#browser_compatibility"&gt;not widely supported&lt;/a&gt;. Let's hope this changes as browsers catch up with with &lt;a href="https://www.w3.org/TR/css-text-4/#text-wrap"&gt;CSS Text Level 4&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;text-wrap: balance&lt;/code&gt; CSS property is a valuable addition to your web design toolkit, especially when aiming for a clean and professional text layout. By using &lt;code&gt;text-wrap: balance&lt;/code&gt;, you can ensure that text is distributed in an eye-pleasing way, improving readability and enhancing the overall aesthetics of your web pages. Keep in mind that while this property offers aesthetics benefits, it's crucial to verify its compatibility with your target audience's browsers to ensure a seamless user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  More information
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap#balance"&gt;MDN&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.chrome.com/blog/css-text-wrap-balance/"&gt;CSS text-wrap: balance&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.w3.org/TR/css-text-4/#text-wrap"&gt;CSS Text Level 4&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.google.com/document/d/1jJFD8nAUuiUX6ArFZQqQo8yTsvg8IuAq7oFrNQxPeqI/edit#heading=h.cqq9czoal00g"&gt;Score-based Paragraph-level Line Breaking&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>typography</category>
    </item>
    <item>
      <title>Communicate Risk with Git Commits</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Wed, 19 Oct 2022 18:44:00 +0000</pubDate>
      <link>https://dev.to/olegchursin/communicate-risk-with-git-commits-2ak</link>
      <guid>https://dev.to/olegchursin/communicate-risk-with-git-commits-2ak</guid>
      <description>&lt;p&gt;Our web dev team at &lt;a href="https://www.aon.com/cyber-solutions/solutions/"&gt;Aon Cyber Solutions&lt;/a&gt; uses &lt;strong&gt;Tagging as a Process (TaaP)&lt;/strong&gt; flow as introduced in &lt;a href="https://www.digdeeproots.com/"&gt;DigDeepRoots&lt;/a&gt; training. This post is a go-to gist. &lt;/p&gt;

&lt;p&gt;Following the principles below will help you become more risk aware by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reviewing code in minutes instead of hours/days.&lt;/li&gt;
&lt;li&gt;Knowing which code reviews/commits require attention.&lt;/li&gt;
&lt;li&gt;Introducing fewer bugs on the most common refactorings.&lt;/li&gt;
&lt;li&gt;Becoming more aware of the risks that lead to bugs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Work in movements. Make smaller commits inside a movement (8-10 LOC).&lt;/li&gt;
&lt;li&gt;Merge commit should state the purpose of the overall movement/PR.&lt;/li&gt;
&lt;li&gt;Communicate risk with a one-letter prefix (e.g. &lt;code&gt;F - Added new feature&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Increase risk sensitivity with bangs (e.g. &lt;code&gt;F!! - Added a potentially risky feature. Reviewer beware.&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Use provable refactorings (e.g. &lt;code&gt;r - Extracted method&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cheatsheets
&lt;/h3&gt;

&lt;h4&gt;
  
  
  MD Table
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;May Change Behavior&lt;/th&gt;
&lt;th&gt;Won't Change Behavior&lt;/th&gt;
&lt;th&gt;High Risk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;F - Feature (&amp;lt; 9 LOC)&lt;/td&gt;
&lt;td&gt;t - Test&lt;/td&gt;
&lt;td&gt;F!! Feature (&amp;gt; 8 LOC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B - Bug (&amp;lt; 9 LOC&amp;gt;)&lt;/td&gt;
&lt;td&gt;d - Documentation&lt;/td&gt;
&lt;td&gt;B!! Bug (&amp;gt; 8 LOC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R - Test Supported Refactoring&lt;/td&gt;
&lt;td&gt;a - Auto-tool&lt;/td&gt;
&lt;td&gt;R!! Non-provable Refactoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;r - Provable Refactoring&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Image
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9rju1eaqphe9cque4v7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9rju1eaqphe9cque4v7.png" alt="Using commits to communicate risk" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;:::info Conventional commits&lt;/p&gt;

&lt;p&gt;Yes, our team loves &lt;a href="https://www.conventionalcommits.org/"&gt;conventional commits&lt;/a&gt;, but found that they do not communicate risk&lt;/p&gt;

&lt;p&gt;:::&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduce Risk with Micro-Commits
&lt;/h2&gt;

&lt;p&gt;Accomplish each purpose with a sequence of micro-commits. Put a series of micro-commits on a branch, then merge them in with a commit that states the purpose you achieved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practice
&lt;/h3&gt;

&lt;p&gt;Make safer commits by checking in smaller chunks of code per commit. 8-10 lines of code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;: 3+ commit chain within 5m at least 1x day&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2&lt;/strong&gt;: 5+ commit chain within 3m at least 3x day&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 3&lt;/strong&gt;: 10+ commit chain within 2m at least 8x day&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Insights
&lt;/h3&gt;

&lt;p&gt;Most of this value comes from increasing your focus. You can deeply focus on one tiny thing at a time, then come back up to re-gain your context and pick the next thing to do. Each commit allows you to finish one step, the branch provides your context, and the final merge commit allows you to verify that you completed your objective. You can enhance this effect by naming the branch after your intention and renaming it each time you learn something that shifts your intention.&lt;/p&gt;

&lt;p&gt;These branches also allow you to make commits smaller while conveying intention more clearly. Smaller commits reduce your error rate, and both small commits and clear intention speed up code review. Now you can start each review by understanding the intention and then assess whether the steps make sense. You can also focus more on the ones that need individual review (risky or surprising steps).&lt;/p&gt;

&lt;h2&gt;
  
  
  Make Risks Obvious
&lt;/h2&gt;

&lt;p&gt;Communicate the intention behind each change with your team. You will use a simple letter code in each commit message to indicate which one type of change you made in that commit.&lt;/p&gt;

&lt;p&gt;Tagging each commit provides 3 distinct pieces of value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You write fewer bugs.&lt;/li&gt;
&lt;li&gt;You become more aware of risk.&lt;/li&gt;
&lt;li&gt;Code review is faster and more useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practice
&lt;/h3&gt;

&lt;p&gt;Every time you commit, start the commit message with one of these six letters followed by &lt;code&gt;space dash space&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;F - Feature
B - Bug
R - Refactor
t - Test
d - Documentation
a - Auto-tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Insights
&lt;/h3&gt;

&lt;p&gt;Just writing the risk codes provides significant value. It makes you stop to think about the intention of your commit (either before making the change or before committing). This will usually cause you to separate refactorings and test-only changes from bug fixes and features. Small commits that each complete one clear intention are less likely to have bugs than larger commits with multiple intentions.&lt;/p&gt;

&lt;p&gt;Risk codes also provide value when you see your own commit log. Before it was not always obvious when you were taking on a small (or large) risk. Now each commit shows the risk, and your log shows how risky your coding approach is. Later shifts in this habit will build on this new awareness, helping you do something about the now-visible risks.&lt;/p&gt;

&lt;p&gt;Finally, the codes help you quickly understand others’ code. Knowing the author’s intention allows you to assess each commit differently. You can have one mindset when checking a refactoring, another for a behavior change, and a third for a test-only change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Increase Risk Sensitivity
&lt;/h2&gt;

&lt;p&gt;Use new tags to denote high risk commits. Start using F!!, B!!, and R!! to denote commits, unless you have evidence to prove you did it in a lower-risk way.&lt;/p&gt;

&lt;p&gt;Tagging high-risk commits provides two important but higher-level sources of value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make better choices about risk.&lt;/li&gt;
&lt;li&gt;See opportunities to increase safety.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practice
&lt;/h3&gt;

&lt;p&gt;Perform the following tasks when committing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace all &lt;code&gt;R&lt;/code&gt;‘s with &lt;code&gt;R!!&lt;/code&gt; unless you have strong test support and follow the written steps for that refactoring.&lt;/li&gt;
&lt;li&gt;Replace any &lt;code&gt;F&lt;/code&gt;‘s or &lt;code&gt;B&lt;/code&gt;‘s that have more than 8 lines of change with &lt;code&gt;F!!&lt;/code&gt; or &lt;code&gt;B!!&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Any times you have to notate with a &lt;code&gt;X!!&lt;/code&gt; (high risk), consider alternatives that avoid the &lt;code&gt;!!&lt;/code&gt; commit flag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;:::tip&lt;br&gt;
There is only one space after a &lt;code&gt;X!!&lt;/code&gt; code, so your log lines up like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;R - Extract Method
F!! I should have refactored more
R!! Edited a bunch trying to refactor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;:::&lt;/p&gt;

&lt;h3&gt;
  
  
  Insights
&lt;/h3&gt;

&lt;p&gt;It might take you and your teammates time to really start using &lt;code&gt;X!!&lt;/code&gt; whenever it applies. However, even as you get started, each &lt;code&gt;X!!&lt;/code&gt; gives the team a chance to find and fix an obstacle. Something in your code, process, or skills makes it hard to do the lower-risk route, so the higher-risk option made sense in this case. Fix that obstacle so everyone will take lower-risk options in the future.&lt;/p&gt;

&lt;p&gt;There will always be some &lt;code&gt;!!&lt;/code&gt; commits in the log, and there will always be some commits that are marked with a capital letter that should be !!. Both of these provide ongoing opportunities for your team to make its practice and environment safer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Increase Safety
&lt;/h2&gt;

&lt;p&gt;Perform safe and provable refactoring. Use provable &lt;code&gt;r&lt;/code&gt; refactorings instead of test-supported &lt;code&gt;R&lt;/code&gt; or unprovable &lt;code&gt;R!!&lt;/code&gt; refactorings.&lt;/p&gt;

&lt;p&gt;Using provable refactorings makes refactoring safe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactor without writing bugs.&lt;/li&gt;
&lt;li&gt;Get untestable code under test without writing bugs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practice
&lt;/h3&gt;

&lt;p&gt;Consider &lt;code&gt;R!!&lt;/code&gt; and &lt;code&gt;R&lt;/code&gt; commits, and try a safe refactoring &lt;code&gt;r&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recipe Option: &lt;a href="https://github.com/digdeeproots/provable-refactorings/tree/master/recipes/core-6/extract-function"&gt;Extract Method&lt;/a&gt;, &lt;a href="https://github.com/digdeeproots/provable-refactorings/tree/master/recipes/core-6/rename"&gt;Rename&lt;/a&gt;, others, or &lt;a href="https://github.com/digdeeproots/provable-refactorings"&gt;extend the catalog&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Tool Option: JetBrains IDEs and plugins, Visual Studio, or some others.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Read by Refactoring
&lt;/h3&gt;

&lt;p&gt;In addition to solving this critical problem, provable refactorings are the foundation of &lt;strong&gt;Read by Refactoring&lt;/strong&gt;. Read by Refactoring is a technique for reading code by first safely refactoring it to make it easy to understand, and then reading the result. This works because you can prove that your refactorings are safe even though you don’t understand the code you are refactoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  Insights
&lt;/h3&gt;

&lt;p&gt;The provable refactorings fundamentally prevent bugs, allowing an entirely different approach to coding. Right now we will use that to get code under test without introducing bugs in the process.&lt;/p&gt;

&lt;p&gt;Future habits will apply provable refactoring to address a wide variety to architectural and design problems. This shift familiarizes you with a widely-applicable technique.&lt;/p&gt;

&lt;h2&gt;
  
  
  External Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.digdeeproots.com/"&gt;Code by Refactroring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/digdeeproots/provable-refactorings"&gt;Provable Refactorings&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cleancode</category>
      <category>softwaredevelopment</category>
      <category>risk</category>
      <category>git</category>
    </item>
    <item>
      <title>Notes on Better User Stories Course</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Thu, 17 Feb 2022 01:25:59 +0000</pubDate>
      <link>https://dev.to/olegchursin/notes-on-better-user-stories-course-3kp2</link>
      <guid>https://dev.to/olegchursin/notes-on-better-user-stories-course-3kp2</guid>
      <description>&lt;p&gt;Better User Stories is a video course from Mike Cohn of Mountain Goat Software designed to help you with user stories in your organization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.mountaingoatsoftware.com/training/courses/better-user-stories"&gt;https://www.mountaingoatsoftware.com/training/courses/better-user-stories&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below are my notes on this course.&lt;/p&gt;

&lt;h2&gt;
  
  
  Course Modules
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What Stories Are&lt;/li&gt;
&lt;li&gt;Users, User Roles and Personas&lt;/li&gt;
&lt;li&gt;Story Mapping and Story-Writing Workshops&lt;/li&gt;
&lt;li&gt;Adding Detail with Conditions of Satisfaction or Acceptance Criteria&lt;/li&gt;
&lt;li&gt;INVEST in Good Stories&lt;/li&gt;
&lt;li&gt;Splitting Stories&lt;/li&gt;
&lt;li&gt;Overcoming Common Problems&lt;/li&gt;
&lt;li&gt;Things That Are Not User Stories&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What Stories Are
&lt;/h2&gt;

&lt;p&gt;User story - short simple statement told from the perspective of a user.&lt;/p&gt;

&lt;p&gt;A story can be improved with a &lt;code&gt;so that&lt;/code&gt; clause.&lt;/p&gt;

&lt;h3&gt;
  
  
  Story template:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;As a &amp;lt;type of user&amp;gt;,
I &amp;lt;want/can/need/am required to&amp;gt; &amp;lt;some goal&amp;gt;
so that &amp;lt;some reason&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Qs answered by using the template:&lt;br&gt;
    1. Who wants it?&lt;br&gt;
    2. What is it they want?&lt;br&gt;
    3. Why?&lt;/p&gt;
&lt;h3&gt;
  
  
  3Cs of a user Story
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Card&lt;/li&gt;
&lt;li&gt;Conversation&lt;/li&gt;
&lt;li&gt;Confirmation&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Card
&lt;/h4&gt;

&lt;p&gt;A starting point of a story.&lt;br&gt;
Represents the following: &lt;br&gt;
    * A promise from the development team to ask questions&lt;br&gt;
    * A promise from the product owner to be available for clarification&lt;br&gt;
    * An opportunity for the product owner to avoid writing long specification documents&lt;/p&gt;
&lt;h4&gt;
  
  
  Conversation
&lt;/h4&gt;

&lt;p&gt;Starts with a two-way promise represented by a story Card:&lt;br&gt;
    - from the dev team - a promise to ask Qs&lt;br&gt;
    - from the product owner - a promise to be available to answer Qs (As a product owner, I write just enough that the team and I have good conversation so that we can be agile.)&lt;/p&gt;
&lt;h4&gt;
  
  
  Confirmation
&lt;/h4&gt;

&lt;p&gt;Product owner’s way of telling the team what needs to be done in order for the story to be considered complete.&lt;br&gt;
    - what are conditions of satisfactions&lt;/p&gt;
&lt;h3&gt;
  
  
  Adding detail to a user story
&lt;/h3&gt;

&lt;p&gt;Multiple ways of doing it:&lt;br&gt;
    1. split the story into smaller stories&lt;br&gt;
    2. addict to a story a list of the things that a product owner expects to be true about the completed story (acceptance criteria)&lt;/p&gt;
&lt;h3&gt;
  
  
  A story is a pointer to a requirement
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- attach additional supporting information/diagrams to the story
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Users, User Roles and Personas
&lt;/h2&gt;

&lt;p&gt;User role is:&lt;br&gt;
    - a collection of characteristic needs, interests, expectations, and behaviors in relation to a particular system&lt;br&gt;
    - users who share common needs, interests or behaviors&lt;br&gt;
    - combination of users who have enough in common that we may think of their needs as largely similar&lt;/p&gt;
&lt;h3&gt;
  
  
  Context, Characteristics, and Criteria
&lt;/h3&gt;

&lt;p&gt;To identify user roles, consider user similarities in:&lt;br&gt;
    - context&lt;br&gt;
        - physical environment&lt;br&gt;
        - social environment&lt;br&gt;
        - domain knowledge&lt;br&gt;
        - proficiency (developer vs grandma)&lt;br&gt;
        - system access (slow vs high internet connection speed)&lt;br&gt;
    - characteristics&lt;br&gt;
        - frequency of interaction with the system&lt;br&gt;
        - regularity of interaction&lt;br&gt;
        - complexity of work performed&lt;br&gt;
        - the volume of work performed&lt;br&gt;
        - user’s mental state (using the system under stress vs not)&lt;br&gt;
    - criteria&lt;br&gt;
        - user’s main goal&lt;br&gt;
        - secondary goals&lt;br&gt;
        - ease of use&lt;br&gt;
        - reliability&lt;br&gt;
        - accuracy of results&lt;/p&gt;
&lt;h3&gt;
  
  
  How to Do User Role Modeling
&lt;/h3&gt;

&lt;p&gt;The process will provide meaningful; insights into who the product users are, how they differ, and what functionality they need&lt;/p&gt;

&lt;p&gt;4 Role Modeling Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Brainstorm an initial set of users roles

&lt;ul&gt;
&lt;li&gt;done once in the beginning of the project&lt;/li&gt;
&lt;li&gt;the whole team is present&lt;/li&gt;
&lt;li&gt;fast and furious - no judgement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Organize the initial set

&lt;ul&gt;
&lt;li&gt;group similar roles together&lt;/li&gt;
&lt;li&gt;identify aggregate roles&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Consolidate

&lt;ul&gt;
&lt;li&gt;look at each role and see if they can be combined&lt;/li&gt;
&lt;li&gt;rename the combined role&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Refine

&lt;ul&gt;
&lt;li&gt;eliminate roles that are unimportant for the product &lt;/li&gt;
&lt;li&gt;remove roles that are too broad&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Documenting a User Role Model
&lt;/h3&gt;

&lt;p&gt;Outcome documents include:&lt;br&gt;
    - model itself - a diagram representing hierarchal relationship among user roles&lt;br&gt;
    - one page description for each role&lt;br&gt;
    Structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    User role title
        - Context (category 1)
            - attribute 1.1
                - description
            - attribute 1.2
                - description
            - attribute 1.3
                - description
        - Characteristics (category 2)
            - attribute 2.1
                - description
            - attribute 2.2
                - description
            - attribute 2.3
                - description
        - Criteria (category 3)
            - attribute 3.1
                - description
            - attribute 3.2
                - description
            - attribute 3.3
                - description
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;User role template link [].&lt;/p&gt;

&lt;h3&gt;
  
  
  Personas (Intro)
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Highly descriptive and detail archetypes representing each user role.
- user role on steroids
- it’s given a name, specific goals, attitudes, and an environment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;IMPORTANT:&lt;br&gt;
    - If you get a persona wrong, you end up building the absolutely right product for the absolutely wrong type of person.&lt;br&gt;
    - Without the data to backup the details, a persona is just a guess&lt;/p&gt;

&lt;p&gt;Create a persona when:&lt;br&gt;
    1. You are creating a high-consideration product.&lt;br&gt;
        - a product the requires a lot of thought either before a user buys it or while using it&lt;br&gt;
    2. You aren’t guessing at the extra detail.&lt;br&gt;
        - use data on users of current products&lt;br&gt;
        - do research on likely users of a product&lt;br&gt;
        - talk to actual users&lt;br&gt;
        - observe real users&lt;/p&gt;
&lt;h3&gt;
  
  
  Attributes to Consider When Creating a Persona
&lt;/h3&gt;

&lt;p&gt;Consider ONLY the attributes that are important for your product.&lt;/p&gt;

&lt;p&gt;Set of attributes to look at when defining a persona:&lt;br&gt;
    - Demographic (quantitative)&lt;br&gt;
        - age&lt;br&gt;
        - gender&lt;br&gt;
        - geography&lt;br&gt;
        - income level&lt;br&gt;
        - education&lt;br&gt;
    - Psychographic (qualitative)&lt;br&gt;
        - fears&lt;br&gt;
        - preferences&lt;br&gt;
        - attitudes&lt;br&gt;
        - opinions&lt;br&gt;
        - lifestyle&lt;br&gt;
        - values&lt;/p&gt;
&lt;h3&gt;
  
  
  Documenting a Persona
&lt;/h3&gt;

&lt;p&gt;Give persona a name, you may also attach a photo, and a dd a quote from real user interviews.&lt;/p&gt;

&lt;p&gt;Describe their: &lt;br&gt;
    - Demographics&lt;br&gt;
    - Personal&lt;br&gt;
    - Goals&lt;br&gt;
    - Skills or experience&lt;br&gt;
    - Fears&lt;br&gt;
    - Attitudes and feelings&lt;br&gt;
    - Environment&lt;/p&gt;

&lt;p&gt;Persona template link [].&lt;/p&gt;
&lt;h3&gt;
  
  
  Decorated User Roles
&lt;/h3&gt;

&lt;p&gt;User role types:&lt;br&gt;
    - first-class citizens&lt;br&gt;
    - decorated user roles (as in decorated symbols in maths)&lt;br&gt;
        - create by adding a descriptive introduction to a first-class citizen name, as in:&lt;br&gt;
            - first-time user, first-time visitor, first-time registered member&lt;br&gt;
            - forgetful registered member&lt;br&gt;
            - as a user who has completed CyQu, I can download a report&lt;/p&gt;
&lt;h3&gt;
  
  
  Writing User Stories for the Right User
&lt;/h3&gt;

&lt;p&gt;Principles:&lt;br&gt;
    - do not write all stories using the role at the top of the hierarchy (aggregate role)&lt;br&gt;
    - use a role most likely to perform a story. This:&lt;br&gt;
        - prevents every story from being “As a user, …”&lt;br&gt;
        - puts us in the mindset of that user&lt;br&gt;
    - if you feel constantly compelled to write the same story for different user roles, this could be an indicator that you should rethink the user roles you have identified&lt;br&gt;
    - put multiple roles into the story when:&lt;br&gt;
        - roles are equally likely to perform the story&lt;br&gt;
        - roles are so different that one may be forgotten&lt;br&gt;
        - roles will use the functionality in slightly different ways&lt;/p&gt;


&lt;h2&gt;
  
  
  Story Mapping and Story-Writing
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Four Times to Write Stories
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Whenever a new idea occurs to you
2. During iteration review meetings
3. During product backlog refinement/grooming meetings
4. During story-writing workshop - the most strategic
    - attended by the whole team
    - attended by important stakeholders
    - being help quarterly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  A Significant Objective Focuses the Scope of a Story-Writing Workshop
&lt;/h3&gt;

&lt;p&gt;Define a significant objective for the quarter: an MVP or an MMF&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MVP vs MMF (Minimum Marketable Feature)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MMF - a chunk of functionality that delivers a subset of the customer’s requirements, and that s capable of returning value to the customer when released as an independent entity.&lt;/p&gt;

&lt;p&gt;Significant objective includes:&lt;br&gt;
    - business objective&lt;br&gt;
    - user objective&lt;/p&gt;

&lt;p&gt;Significant objective:&lt;br&gt;
    - provides focus&lt;br&gt;
    - leads to greater creativity&lt;/p&gt;
&lt;h3&gt;
  
  
  Story-Writing Workshop Attendees, Duration and Preparation
&lt;/h3&gt;

&lt;p&gt;Important Qs:&lt;br&gt;
    1. Who runs the workshop?&lt;br&gt;
        - scrum master/coach&lt;br&gt;
    2. Who attends?&lt;br&gt;
        - product owner&lt;br&gt;
        - entire dev team&lt;br&gt;
        - stakeholders&lt;br&gt;
        - users/customers&lt;br&gt;
    3. How long does it last?&lt;br&gt;
        - 4-5 hours with breaks&lt;br&gt;
        - influenced by:&lt;br&gt;
            - number of participants&lt;br&gt;
            - whether there’s a shared vision&lt;br&gt;
            - whether the work is new&lt;br&gt;
    4. What preparation is done in advance?&lt;br&gt;
        - basic meeting stuff&lt;br&gt;
        - product should already have user roles/personas identified&lt;br&gt;
        - print out user roles/personas and attach them to the wall&lt;br&gt;
        - product owner should be ready to present the significant objective for the quarter&lt;br&gt;
        - sticky notes, pens, markers&lt;/p&gt;
&lt;h3&gt;
  
  
  The Story-Writing Workshop Agenda
&lt;/h3&gt;

&lt;p&gt;5 Steps:&lt;br&gt;
    1. Product owner presents the significant objective&lt;br&gt;
    2. Discuss user roles and personas relevant to the goals of the workshop&lt;br&gt;
    3. Story generation - all stories that achieve the significant objective&lt;br&gt;
    4. Story selection - which stories will best fulfill the significant objective&lt;br&gt;
    5. Schedule follow-up sessions if needed&lt;/p&gt;
&lt;h3&gt;
  
  
  Story Mapping
&lt;/h3&gt;

&lt;p&gt;Adding a second dimension (sequence/narrative) to the backlog list (usually unidirectional and prioritized from most to least important)&lt;/p&gt;

&lt;p&gt;Story map concepts/terms:&lt;br&gt;
    - Narrative - a sequence of items read across the story map&lt;br&gt;
    - Backbone - the topmost one or two narratives&lt;br&gt;
    - Step - any item on the map&lt;br&gt;
    - Activity - a collection of steps that are performed to achieve a goal&lt;/p&gt;
&lt;h3&gt;
  
  
  Making Decisions with a Story Map
&lt;/h3&gt;

&lt;p&gt;Story maps can help:&lt;br&gt;
    - identify missing functionality&lt;br&gt;
    - plan a release to determine an MVP&lt;br&gt;
    - create a product road map&lt;/p&gt;

&lt;p&gt;Qs to ask in regards to each step:&lt;br&gt;
    1. What else might a user want to do?&lt;br&gt;
    2. What additional info might a user find helpful?&lt;br&gt;
    3. What could go wrong?&lt;/p&gt;


&lt;h2&gt;
  
  
  Adding Detail with Conditions of Satisfaction or Acceptance Criteria
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Progressive Refinement - Adding Detail over Time
&lt;/h3&gt;

&lt;p&gt;Stories are initially vague on purpose. They open up a conversation.&lt;/p&gt;

&lt;p&gt;When starting a project, include large, placeholder stories for functionality you are aware will need to be built but which will not be started until well into the future. Then refine those stories into progressively smaller and smaller stories over the course of the entire project. Going through a list of stories only once at the start of a project will not be sufficient.&lt;/p&gt;

&lt;p&gt;Progressive refinement of a story includes:&lt;br&gt;
    - splitting story into smaller stories&lt;br&gt;
    - adding details to a story&lt;/p&gt;
&lt;h3&gt;
  
  
  Epics and Themes
&lt;/h3&gt;

&lt;p&gt;Epic - single large user story. A story that is bigger than one team can do in one iteration.&lt;/p&gt;

&lt;p&gt;Theme - a collection of related stories.&lt;br&gt;
    - a story can be in two themes at the same time&lt;/p&gt;
&lt;h3&gt;
  
  
  Two Ways of Adding Detail to a Story
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Ask product owner questions and split into smaller stories accordingly
2. Add tests to the stories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Both approaches are functionally equivalent. Anything that can be written as test to a story, could be written as a substory and vice versa.&lt;/p&gt;

&lt;p&gt;When chose one over the other? &lt;br&gt;
    - When you have a bigger story, split it.&lt;br&gt;
    - When you have a small enough story already, add tests.&lt;/p&gt;
&lt;h3&gt;
  
  
  Condition of Satisfaction
&lt;/h3&gt;

&lt;p&gt;To be considered done, a user story must fulfill the product owner’s expectations. The best way to determine those is through one or more conversations with the product owner. If team members have specific needs from a story, it is fine to meet and discuss the story with them, too, but a first step should be a conversation with the product owner.&lt;/p&gt;
&lt;h3&gt;
  
  
  How Much Detail Is Appropriate
&lt;/h3&gt;

&lt;p&gt;Just enough detail that the team can finish the story in the iteration.&lt;/p&gt;
&lt;h3&gt;
  
  
  Working with a Team That Wants too Much Detail
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Product owners should not specify every small detail.
- Product owner may not be the best person to make a decision.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  A Definition of Ready and Why Having One Could Be Dangerous
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- A **Definition of Ready** enables a team to specify certain pre-conditions that must be fulfilled before a story is admitted into an iteration.
- Goal - prevent problems before they start.
- Each team decided on their own Definition of Ready for each story to be included into an iteration.
- Some of the rules can cause trouble and prevent the team from being agile locking it into a stage-gate flow (one thing cannot start until another thing is done).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;If a Definition of Ready is needed, it will be best if it focuses on guidelines rather than hard-and-fast rules. And with a Definition of Ready, the team will need to take care to emphasize working concurrently. For example, a little coding is going on even while some design is still occurring. This avoids creating a stage-gate process in which all of one activity must be completed before ANY of the next activity can begin.&lt;/p&gt;

&lt;p&gt;Agile teams should practice concurrent engineering in which activities overlap -&amp;gt; most teams should not even use the definition of ready.&lt;/p&gt;


&lt;h2&gt;
  
  
  INVEST in Good Stories
&lt;/h2&gt;

&lt;p&gt;Attributes of a good story:&lt;br&gt;
     - Independent&lt;br&gt;
     - Negotiable&lt;br&gt;
         - a story opens up a conversation between product owner and dev team&lt;br&gt;
     - Valuable&lt;br&gt;
         - to customer&lt;br&gt;
         - to user&lt;br&gt;
         - to stakeholder&lt;br&gt;
     - Estimatable&lt;br&gt;
         - a story should not be too big to estimate&lt;br&gt;
         - if a story is not estimable today, leave it and come back to it later&lt;br&gt;
     - Sized appropriately or Small&lt;br&gt;
         - top of the backlog always contained smaller stories that are ready to go into the next iteration&lt;br&gt;
     - Testable&lt;br&gt;
         - being able to identify confirmation criteria&lt;/p&gt;


&lt;h2&gt;
  
  
  Splitting Stories
&lt;/h2&gt;

&lt;p&gt;Why split a story?&lt;br&gt;
    - different priorities&lt;br&gt;
    - lack of time&lt;br&gt;
    - size - too big to be completed in one iteration&lt;/p&gt;

&lt;p&gt;2 types of large story:&lt;br&gt;
    - complex - fundamentally large and cannot be split: these are rare&lt;br&gt;
    - compound - combines multiple user actions into one: can be split&lt;/p&gt;
&lt;h3&gt;
  
  
  The SPIDR Approach to Splitting Stories
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Spikes
    - research activity intended to build knowledge
    - timeboxed
    - should only be used to remove excess uncertainty from a story -&amp;gt; do not overuse spikes
- Paths
    - drill down to find underlying steps/paths
- Interfaces
    - story that has multiple user interfaces
- Data
    - split by the data handled by the story
- Rules
    - look at the conditions of satisfaction and pull out any rules that make the story too big
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Tracer Bullet Story
&lt;/h3&gt;

&lt;p&gt;A story is a tracer bullet through a system technology stack&lt;/p&gt;

&lt;p&gt;Advantages:&lt;br&gt;
    - reduce architectural risk&lt;br&gt;
    - easier to prioritize&lt;br&gt;
    - make early releases possible&lt;/p&gt;
&lt;h3&gt;
  
  
  Closed Stories
&lt;/h3&gt;

&lt;p&gt;When splitting stories try to create a closed story&lt;/p&gt;

&lt;p&gt;Closed story - the one that finishes with the user having achieved a meaningful goal&lt;/p&gt;
&lt;h3&gt;
  
  
  Three Things to Do when You Can’t Split a Story
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Try harder
    - most stories are compound rather than complex
    - walk through the SPIDR approach
2. Let it take more than one iteration
3. Feel guilty
    - if you allow a story to span more than one iteration, feel guilty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Overcoming Common Problems
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Managing Dependencies Between Stories
&lt;/h3&gt;

&lt;p&gt;Techniques for dealing with dependencies between stories:&lt;br&gt;
    1. Combine stories&lt;br&gt;
    2. Split stories as late as possible&lt;br&gt;
    3. Reconsider the way in which stories were split&lt;br&gt;
    4. Annotate stories with important dependencies&lt;/p&gt;

&lt;p&gt;Do not document obvious dependencies&lt;/p&gt;
&lt;h3&gt;
  
  
  Stories with Too Much Detail
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- when you first write the story, focus on WHAT the user wants to achieve and HOW they want to achieve it
- initially leave UI assumptions out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Just in time and Just enough&lt;br&gt;
    - developers need just enough information provided to them  just in time&lt;/p&gt;
&lt;h3&gt;
  
  
  Spending Too Much Time Splitting Stories
&lt;/h3&gt;

&lt;p&gt;If you spend too much time splitting stories, consider the following:&lt;br&gt;
    - assess whether stories are too detailed&lt;br&gt;
    - consider whether stories are small enough already&lt;br&gt;
    - consider changing to a longer iteration length (avoid iterations longer than 4 weeks)&lt;/p&gt;
&lt;h3&gt;
  
  
  Stories Involving More than One Team
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Indicate all the team need/can work on a story
- mark appropriate dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Stories that Are Really Tasks
&lt;/h3&gt;

&lt;p&gt;Bad habit - creating tasks that masquerade as stories&lt;/p&gt;

&lt;p&gt;Stories vs Tasks&lt;br&gt;
    - story&lt;br&gt;
        -  generally something that is worked on by more than one person&lt;br&gt;
        - contains multiple types of work&lt;br&gt;
    - task&lt;br&gt;
        - generally worked on by just one person&lt;br&gt;
        - contains single type of work&lt;/p&gt;

&lt;p&gt;Stories that are really tasks create problems:&lt;br&gt;
    1. The duo not deliver value&lt;br&gt;
    2. They are risky&lt;br&gt;
    3. They lead to phased development&lt;/p&gt;


&lt;h2&gt;
  
  
  Not Everything Needs to Be a User Story
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Nonfunctional Requirements
&lt;/h3&gt;

&lt;p&gt;Requirements that have to do with operation of the system rather than its specific behaviors &lt;/p&gt;

&lt;p&gt;Often called —ilities&lt;br&gt;
    - portability&lt;br&gt;
    - maintainability&lt;br&gt;
    - testability&lt;br&gt;
    - scalability&lt;br&gt;
    - usability&lt;/p&gt;

&lt;p&gt;They are constraints on how the system is developed&lt;/p&gt;
&lt;h3&gt;
  
  
  Stories and Bugs
&lt;/h3&gt;

&lt;p&gt;Reporting a bug and asking for a new feature is fundamentally/conceptually the same thing - a desire to introduce changes to the system&lt;/p&gt;

&lt;p&gt;Bugs should not be written in a story syntax.&lt;/p&gt;
&lt;h3&gt;
  
  
  Features from Feature-Driven Development
&lt;/h3&gt;

&lt;p&gt;FDD - feature driven development&lt;br&gt;
    - feature list = Scrum’s product backlog&lt;br&gt;
    - syntax: &lt;code&gt;&amp;lt;action&amp;gt; the &amp;lt;result&amp;gt; &amp;lt;by|for|of|to&amp;gt; a(n) &amp;lt;object&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;FDD feature syntax can be helpful:&lt;br&gt;
    - when the is no immediate user present.&lt;br&gt;
    - for more technical parts of the system&lt;br&gt;
    - for API development tasks&lt;/p&gt;
&lt;h3&gt;
  
  
  Job Stories
&lt;/h3&gt;

&lt;p&gt;Variation on User stories&lt;/p&gt;

&lt;p&gt;Job stories are addressing two problems identified with user stories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Many users have the same goal&lt;/li&gt;
&lt;li&gt;Users do not know the solution to their problem&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Template for Job stories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;When ______ I want to ______ so I can ______ .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When to use job stories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When knowing a user’s motivation is more important than knowing details about the user&lt;/li&gt;
&lt;li&gt;When dev team members and user already talk often&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>userstories</category>
      <category>projectmanagement</category>
      <category>scrum</category>
      <category>agile</category>
    </item>
    <item>
      <title>Native datetime formatter</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Thu, 16 Dec 2021 07:47:12 +0000</pubDate>
      <link>https://dev.to/olegchursin/native-datetime-formatter-430m</link>
      <guid>https://dev.to/olegchursin/native-datetime-formatter-430m</guid>
      <description>&lt;p&gt;The simpler the better. Here's a dead simple date formatter snippet that works in all modern browsers as well as node apps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// define formatter&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// use&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formattedDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Typed version is also here:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;What's going on above? We grab the current date with &lt;code&gt;new Date()&lt;/code&gt;, instantiate the formatter with &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; providing the locale string and date format options object.&lt;/p&gt;

&lt;p&gt;Tiny playground file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;datetime-format.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-GB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-CA&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formattedDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`formattedDate: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; --&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formattedDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running it in node will produce the following result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/dev/node-playground » node datetime-format.js
formattedDate: en-US &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Dec 16, 2021, 2:28 AM
formattedDate: en-GB &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 16 Dec 2021, 2:28
formattedDate: en-CA &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Dec. 16, 2021, 2:28 a.m.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sweet. No deps. Just using the platform.&lt;/p&gt;




&lt;p&gt;More info on MDN: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat"&gt;DateTimeFormat&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codesnippet</category>
      <category>node</category>
      <category>datetime</category>
      <category>intl</category>
    </item>
    <item>
      <title>AWS Certified Security Specialty Exam - Practice Questions</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Tue, 14 Dec 2021 16:52:22 +0000</pubDate>
      <link>https://dev.to/olegchursin/aws-certified-security-specialty-exam-practice-questions-38gl</link>
      <guid>https://dev.to/olegchursin/aws-certified-security-specialty-exam-practice-questions-38gl</guid>
      <description>&lt;p&gt;A list of practice questions with answers to help prepping yourself for AWS Certified Security Specialty Exam.&lt;/p&gt;

&lt;h3&gt;
  
  
  A security engineer must ensure that all infrastructure that is launched in the company AWS account is monitored for changes from the compliance rules. All Amazon EC2 instances must be launched from one of a specified list of Amazon Machine Images (AMIs), and all attached Amazon Elastic Block Storage (Amazon EBS) volumes must be encrypted. Instances that are not in compliance must be terminated. Which combination of steps should the security engineer implement to meet these requirements?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitor compliance with AWS Config rules.&lt;/strong&gt; AWS Config is used to monitor the configuration of AWS resources in your AWS account. It ensures compliance with internal policies and best practices by auditing and troubleshooting configuration changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a custom remediation action by using AWS Systems Manager Automation runbooks.&lt;/strong&gt; You can set up remediation actions through the AWS Config console or API. Choose the remediation action you want to associate from a pre-populated list, or create your own custom remediation actions by using Systems Manager Automation runbooks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information about using AWS Config rules for automatic remediation, see  &lt;a href="https://aws.amazon.com/about-aws/whats-new/2019/09/use-aws-config-rules-to-automatically-remediate-non-compliant-resources/"&gt;Use AWS Config Rules to Automatically Remediate Non-compliant Resources&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For more information about AWS Systems Manager Automation runbooks, see  &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-automation.html"&gt;AWS System Manger Automation&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For more information about how to create runbooks, see  &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/automation-document-script-console.html"&gt;Creating a runbook that runs a script (console)&lt;/a&gt; .&lt;/p&gt;




&lt;h3&gt;
  
  
  A company policy requires that no insecure server protocols are used on its Amazon EC2 instances. These protocols include FTP, Telnet, and HTTP. The company’s security team wants to evaluate compliance with this requirement by using a scheduled Amazon EventBridge (Amazon CloudWatch Events) event to review the current infrastructure and create a regular report about the EC2 instances. Which process will check the compliance of the company’s EC2 instances?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Run an Amazon Inspector assessment by using the Network Reachability rules package against the instances.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Amazon Inspector tests the network accessibility of your EC2 instances and the security state of your applications that run on those instances. Amazon Inspector assesses applications for exposure, vulnerabilities, and deviations from best practices. The rules in the Network Reachability package analyze your network configurations to find security vulnerabilities of your EC2 instances.&lt;/p&gt;

&lt;p&gt;For more information about Amazon Inspector, see  &lt;a href="https://docs.aws.amazon.com/inspector/latest/userguide/inspector_introduction.html"&gt;What is Amazon Inspector?&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;For more information about the Network Reachability rules for Amazon Inspector, see  &lt;a href="https://docs.aws.amazon.com/inspector/latest/userguide/inspector_network-reachability.html"&gt;Network Reachability&lt;/a&gt; .&lt;/p&gt;




&lt;h3&gt;
  
  
  A company has a legacy application that outputs all logs to a local text file. Logs from all applications that run on AWS must be continually monitored for security related messages. What should the company do to deploy the legacy application on Amazon EC2 and still meet the monitoring requirement?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Send the local text log files to Amazon CloudWatch Logs, and configure a CloudWatch metric filter. Set CloudWatch alarms based on the metrics.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can see all of your logs, regardless of their source, as a single and consistent flow of events ordered in time by using CloudWatch Logs. You can query and sort your logs based on other dimensions, group them by specific fields, create custom computations by using a query language, and visualize log data on the dashboards.&lt;/p&gt;

&lt;p&gt;For more information about CloudWatch Logs, see  &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html"&gt;What is Amazon CloudWatch Logs?&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;For more information about CloudWatch metric filters, see  &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/MonitoringLogData.html"&gt;Creating metrics from log events using filters&lt;/a&gt; .&lt;/p&gt;




&lt;h3&gt;
  
  
  A company is using AWS CloudTrail to log all AWS API activity for all AWS Regions in all of its accounts. The company wants to protect the integrity of the log files in a central location. Which combination of steps will protect the log files from alteration? (TWO)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create a central Amazon S3 bucket in a dedicated log account. In the member accounts, grant CloudTrail access to write logs to this bucket.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This solution meets the requirement to log all AWS API activity to a central location by providing all the AWS accounts the ability to push their logs to a central S3 bucket.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Enable AWS Organizations for all AWS accounts. Enable CloudTrail with log file integrity validation while creating an organization trail. Direct logs from this trail to a central Amazon S3 bucket.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a central S3 bucket in a dedicated log account. To determine whether a log file was modified, deleted, or unchanged after CloudTrail delivered it, you can use CloudTrail log file integrity validation. CloudTrail log file integrity validation ensures the integrity of the log files by reporting if a log file has been deleted or changed. When you set up an organization trail within Organizations, you can enable log file integrity validation. The trail logs activity for all organization accounts in the same S3 bucket. Member accounts will not be able to delete or modify the organization trail. Only the management account will be able to delete or modify the trail for the organization.&lt;/p&gt;




&lt;h3&gt;
  
  
  A company has an external vendor that must deliver files to the company. The vendor has cross-account access that gives them permission to upload objects to an Amazon S3 bucket owned by the company. The company wants to have complete control of the objects after they have been uploaded by the vendor. Which combination of steps must the vendor follow to successfully deliver a file to the company? (TWO)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Configure S3 Object Ownership for the S3 upload bucket.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;S3 Object Ownership is an S3 feature that enables bucket owners to automatically assume ownership of objects that are uploaded to their buckets by other AWS accounts.&lt;br&gt;
For more information about S3 Object Ownership, see  &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html"&gt;Controlling ownership of uploaded objects using S3 Object Ownership&lt;/a&gt; .&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Upload the file to the company's S3 bucket as an object by using the Write-S3Object command.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use the Write-S3Object Tools for Windows PowerShell command to upload an object.&lt;/p&gt;

&lt;p&gt;For more information about granting object permissions, see  &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-walkthroughs-managing-access-example3.html"&gt;Bucket owner granting permissions to objects it does not own&lt;/a&gt; .&lt;/p&gt;


&lt;h3&gt;
  
  
  A company will deploy a new application on Amazon EC2 instances in private subnets. The application will transfer sensitive data to and from an Amazon S3 bucket. According to compliance requirements, the data must not traverse the public internet. Which solution meets the compliance requirement?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Access the S3 bucket through a VPC endpoint for S3.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A VPC endpoint is correct because it enables you to privately connect your VPC to supported AWS services. A VPC endpoint, powered by AWS PrivateLink, does not require the use of an internet gateway, NAT device, VPN connection, or AWS Direct Connect.&lt;/p&gt;


&lt;h3&gt;
  
  
  An application that runs on Amazon EC2 instances in a VPC must access sensitive data in an on-premises data center. No network connections are present other than the internet. The connection must be encrypted with IPsec encryption in transit and have consistent low latency. Which hybrid architecture meets these requirements?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Set up a VPN between the VPC and the data center over an AWS Direct Connect connection.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This solution combines the benefits of the secure IPsec connection with the low latency and increased bandwidth of Direct Connect. This solution provides a more consistent network experience than internet-based VPN connections. A BGP connection is established between Direct Connect and your router on the public VIF. Another BGP session or a static router will be established between the virtual private gateway and your router on the IPsec VPN tunnel.&lt;/p&gt;


&lt;h3&gt;
  
  
  An AWS customer performs DDoS testing with a large simulated attack on its web application, which is running on Amazon EC2 instances. Later, AWS contacts the customer and informs the customer that the testing violated the AWS Customer Agreement. How can the customer perform future testing without violating the agreement?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Work with an AWS Partner Network (APN) Partner to perform the simulation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A DDoS simulation can only be performed with the assistance of an APN Partner. If a customer conducts a simulation without the APN Partner, the customer is in violation of the AWS Customer Agreement.&lt;/p&gt;

&lt;p&gt;For more information about DDoS simulations, see  &lt;a href="https://aws.amazon.com/security/ddos-simulation-testing/"&gt;DDoS Simulation Testing Policy&lt;/a&gt; .&lt;/p&gt;


&lt;h3&gt;
  
  
  An application that runs on Amazon EC2 instances in a VPC must call an external web service by using TLS (port 443). The EC2 instances run in public subnets. Which configurations allow the application to function and minimize the exposure of the instances? (TWO)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A network ACL with rules that allow outgoing traffic on port 443 and incoming traffic on the ephemeral ports&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A network ACL is an optional layer of security for your VPC that acts as a firewall for controlling traffic in and out of one or more subnets. Network ACLs are stateless. Responses to allowed inbound traffic are subject to the rules for outbound traffic, and responses to allowed outbound traffic are subject to the rules for inbound traffic. Based on its stateless property, outgoing traffic on port 443 and incoming traffic on ephemeral ports must be allowed. Ephemeral ports are for the return traffic to the client.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A security group with a rule that allows outgoing traffic on port 443&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A security group acts as a virtual firewall for your instance to control inbound and outbound traffic. A security group is stateful, which means that if you send a request from your instance, the response traffic for that request is allowed to flow in regardless of inbound security group rules. So, you need to only allow outgoing traffic on port 443.&lt;/p&gt;


&lt;h3&gt;
  
  
  A company wants to make available an Amazon S3 bucket to a vendor so that the vendor can analyze the log files in the S3 bucket. The company has created an IAM role that grants access to the S3 bucket. The company also has to set up a trust policy that specifies the vendor account. Which pieces of information are required as arguments in the API calls to access the S3 bucket? (TWO)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Amazon Resource Name (ARN) of the IAM role in the company's account&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ARN of the IAM role you want to assume needs to be specified as an argument in the API call. The IAM role is created in the company’s account. A trust policy is established and attached to the IAM role so that the vendor can assume the role.&lt;/p&gt;

&lt;p&gt;For more information about assuming an IAM role, see  &lt;a href="https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html"&gt;AssumeRole&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For more information about delegating access across AWS accounts by using IAM roles, see  &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html"&gt;IAM tutorial: Delegate access across AWS accounts using IAM roles&lt;/a&gt; .&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;An external ID originally provided by the vendor to the company&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You must always specify the external ID in your AssumeRole API calls. The external ID allows the user that is assuming the role to assert the circumstances in which they are operating. It also provides a way for the account owner to permit the role to be assumed only under specific circumstances.&lt;/p&gt;

&lt;p&gt;For more information about using an external ID when granting access to your AWS resources, see  &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html"&gt;How to use an external ID when granting access to your AWS resources to a third party&lt;/a&gt; .&lt;/p&gt;


&lt;h3&gt;
  
  
  Every application in a company’s portfolio has a separate AWS account for development and production. These accounts are centrally managed and governed within AWS Organizations. The security team wants to make sure all IAM users in the production accounts are not allowed to manually modify or update the AWS Key Management Service (AWS KMS) encryption keys. How can the security team control this functionality?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Create an SCP that denies access to the services. Assemble all production accounts in an OU. Apply the policy to that OU.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SCPs are a type of organization policy that you can use to manage permissions in your organization. By using an SCP, your accounts stay within your organization’s access control guidelines. Because the requirement is for all IAM users in the production accounts, the policy should be applied to the hierarchy OU of those production accounts.&lt;/p&gt;

&lt;p&gt;For more information about SCPs, see  &lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_accounts.html"&gt;Managing the AWS accounts in your organization&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For more information about Organizations, see  &lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html"&gt;What is AWS Organizations?&lt;/a&gt; &lt;/p&gt;


&lt;h3&gt;
  
  
  An AWS Lambda function reads metadata from an Amazon S3 object and stores the metadata in an Amazon DynamoDB table. The function runs whenever an object is stored within the S3 bucket. How should a security engineer give the Lambda function access to the DynamoDB table?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create an IAM service role with permissions to write to the DynamoDB table. Associate that role with the Lambda function.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This method is a valid way to create an IAM role that has the required permissions and to associate the IAM role with the Lambda function. You specify the IAM role when you create your Lambda function. You can choose an existing managed policy or create your own policy with permissions. The permissions you grant to this role determine what the Lambda function can do when it assumes the role.&lt;/p&gt;

&lt;p&gt;For more information about the Lambda execution role, see  &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html"&gt;AWS Lambda execution role&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For more information about resource-based policies for Lambda, see  &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html"&gt;Using resource-based policies for AWS Lambda&lt;/a&gt; .&lt;/p&gt;


&lt;h3&gt;
  
  
  A company wants to enable SSO so that its employees can sign in to the AWS Management Console by using the company’s SAML provider. Which combination of steps are required as part of the process? (TWO)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create IAM policies that can be mapped to group memberships in the corporate directory.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The IAM policies are assigned to the IAM role that is authenticated by the SAML assertion.&lt;/p&gt;

&lt;p&gt;For more information about assuming a role with SAML, see  &lt;a href="https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithSAML.html"&gt;AssumeRoleWithSAML&lt;/a&gt; .&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create an IAM role that establishes a trust relationship between IAM and the corporate SAML identity provider (IdP).&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This step is to create an IAM role that establishes a trust relationship between IAM and your IdP. This role must identify your IdP as a principal (trusted entity) for purposes of federation.&lt;/p&gt;

&lt;p&gt;For more information about the trust relationship, see  &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html"&gt;Enabling SAML 2.0 federated users to access the AWS Management Console&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For more information about the federation IAM role, see  &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html#idp_saml_Prerequisites"&gt;Prerequisites for creating a role for SAML&lt;/a&gt; .&lt;/p&gt;


&lt;h3&gt;
  
  
  A company generates sensitive records that it stores in an Amazon S3 bucket. The company encrypts all objects in the S3 bucket by using one of the company’s CMKs for server-side encryption with AWS KMS managed encryption keys (SSE-KMS). Compliance policies require the company to use a different encryption key for each month of data. Which solution will meet these requirements?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use Amazon EventBridge (Amazon CloudWatch Events) to schedule a monthly AWS Lambda function that creates a new CMK and updates the S3 bucket to use the new CMK as an S3 Bucket Key.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EventBridge (CloudWatch Events) is a serverless event bus service that makes it easy to connect your applications with data from a variety of sources. A Lambda function can be invoked by EventBridge (CloudWatch Events) to create a new CMK.&lt;/p&gt;

&lt;p&gt;For more information about S3 Bucket Keys, see  &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-key.html"&gt;Reducing the cost of SSE-KMS with Amazon S3 Bucket Keys&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For more information about EventBridge (CloudWatch Events), see  &lt;a href="https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html"&gt;What is Amazon EventBridge?&lt;/a&gt; &lt;/p&gt;


&lt;h3&gt;
  
  
  A company has several CMKs. Some of the CMKs have imported key material. The company’s security team must rotate each CMK annually. Which methods can the security team use to rotate each CMK? (TWO)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Enable automatic key rotation for a CMK.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Automatic key rotation is disabled by default on customer managed CMKs. When you enable (or re-enable) key rotation, AWS KMS automatically rotates the CMK 365 days after the enable date and every 365 days thereafter. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Import new key material to a new CMK. Point the key alias to reference the new CMK.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can either rotate the key automatically or manually. To rotate the key manually, import new key material to a new CMK and update the alias to the new CMK.&lt;/p&gt;

&lt;p&gt;For more information about rotating CMKs, see  &lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html"&gt;Rotating AWS KMS keys&lt;/a&gt; .&lt;/p&gt;


&lt;h3&gt;
  
  
  An application that runs on Amazon EC2 instances must use a user name and password to access a legacy application. A developer has stored those secrets in AWS Systems Manager Parameter Store with type SecureString by using the default AWS Key Management Service (AWS KMS) CMK. Which combination of configuration steps will allow the application to access the secrets through the API? (TWO)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Add a permission to the EC2 instance role that allows it to read the Systems Manager parameter.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the application to use the credentials, the following IAM policies are assigned to the instance role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;“Version”:”&lt;/span&gt;&lt;span class="mi"&gt;2012-10-17&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;“Statement”:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;“Effect”:”Allow”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;“Action”:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="err"&gt;“ssm:GetParameters”&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;“Resource”:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="err"&gt;“arn:aws:ssm:region:account-id:parameter/prod-*”&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;“Effect”:”Allow”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;“Action”:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="err"&gt;“kms:Decrypt”&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;“Resource”:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="err"&gt;“arn:aws:kms:region:account-id:key/KMSkey”&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The policies grant permission to the EC2 instance role so that it can read the Systems Manager parameter and decrypt the parameter with the KMS encryption key.&lt;/p&gt;

&lt;p&gt;For more information about how to restrict access to Systems Manager parameters by using IAM policies, see  &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-access.html"&gt;Restricting access to Systems Manager parameters using IAM policies&lt;/a&gt; .&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Add a permission to the EC2 instance role that allows it to decrypt the KMS encryption key.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Original source: &lt;strong&gt;&lt;a href="https://amazonwebservices.benchprep.com/"&gt;https://amazonwebservices.benchprep.com/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>security</category>
      <category>awscertification</category>
    </item>
    <item>
      <title>AWS Certified Security - Specialty | Infrastructure Security (notes)</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Sat, 11 Dec 2021 16:15:11 +0000</pubDate>
      <link>https://dev.to/olegchursin/aws-certified-security-specialty-infrastructure-security-notes-15d7</link>
      <guid>https://dev.to/olegchursin/aws-certified-security-specialty-infrastructure-security-notes-15d7</guid>
      <description>&lt;p&gt;While getting ready to sit AWS Certified Security - Specialty exam, I jotted down a few notes. Breaking them into sections corresponding to the exam domains. Here's Infrastructure Security domain.&lt;/p&gt;

&lt;p&gt;Each note starts with a problem/situation statement in bold followed up with either a service description or a list of practical actions to be taken in response to the stated problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Migrating an application from on-prem to AWS (two regions). What to do with custom SSL certs?
&lt;/h3&gt;

&lt;p&gt;Import the existing certificate and private key into Certificate Manager in both regions. Assign that imported certificate to the Application Load Balancers using their respective regionally imported certificate.&lt;/p&gt;

&lt;p&gt;You can import private certificates into Certificate Manager and assign them to all the same resources you can with generated certificates, including an ALB. Also note that Certificate Manager is a regional service so certificates must be imported in each region where they will be used. &lt;/p&gt;

&lt;h3&gt;
  
  
  Solution to protect your website against DDoS attacks, SQL injection and cross-site scripting attacks.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS WAF to protect against SQL injection&lt;/li&gt;
&lt;li&gt;Use AWS Shield to protect against DDoS attacks&lt;/li&gt;
&lt;li&gt;Use AWS WAF to protect against cross-site scripting&lt;/li&gt;
&lt;li&gt;Use AWS WAF to protect against DDoS attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  You would like to protect your application from attacks such as SQL injection and cross-site scripting.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;CloudFront&lt;/li&gt;
&lt;li&gt;AWS WAF&lt;/li&gt;
&lt;li&gt;Application Load Balancer
&lt;em&gt;AWS WAF protects websites against SQL injection and cross-site scripting attacks. WAF is closely integrated with CloudFront and Application Load Balancer.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuring the bastion host.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Limit inbound connections to the bastion host to the CIDR range that will be used by your administrators&lt;/li&gt;
&lt;li&gt;Deploy the bastion host in the public subnet of your VPC&lt;/li&gt;
&lt;li&gt;Configure your Security Group to allow inbound connections on port 22
&lt;em&gt;Access to bastion hosts should be locked down to known CIDR ranges for ingress. Ports should be limited to allow only the necessary access to the bastion hosts. For Linux bastion hosts, TCP port 22 for SSH connections is typically the only port allowed. Bastion hosts are deployed in the public subnets of the VPC.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Replacing A Lost Key Pair
&lt;/h3&gt;

&lt;p&gt;Stop the instance, detach its root volume and attach it to another instance as a data volume, modify the authorized_keys file, move the volume back to the original instance. Restart the instance.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you lose the private key for an EBS-backed instance, you can regain access to your instance. You must stop the instance, detach its root volume and attach it to another instance as a data volume, modify the authorized_keys file, move the volume back to the original instance, and restart the instance.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test failover capability of Multi-AZ RDS instance. Initiated a reboot with failover expecting only a short outage while the standby instance was promoted and the DNS path was updated. After the failover, DB was unreachable rom on-prem network despite being in an “Available” state.
&lt;/h3&gt;

&lt;p&gt;The subnets in the subnet group did not have the same routing rules. The standby subnet did not have a valid route back to the on-prem network so the database could not be reached despite being available.&lt;/p&gt;

&lt;h3&gt;
  
  
  A compromised Linux based EC2 instance has initiated a DOS attack. Steps to isolate the instance and perform additional analysis.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Update the security group to prevent all outbound traffic.&lt;/li&gt;
&lt;li&gt;Update the instances’ security group to only allow inbound traffic on port 22 and limit incoming traffic from only your internal IP addresses for analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting up a new VPC from scratch. Not able to reach the Amazon Linux web server instance launched in VPC from on-prem network using a web browser. You have verified the internet gateway is attached and the main route table is configured to route 0.0.0.0/0 to the internet gateway properly. What’s going on?
&lt;/h3&gt;

&lt;p&gt;The instance is deployed in a subnet associated with a network ACL that only allows outbound traffic on port 80 ad 22.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For an HTTP connection to be successful, you need to allow port 80 inbound and allow the ephemeral ports outbound. Additionally, it is possible that the subnet is not associated with the route table containing the default route to the internet.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Design a solution to perform deep packet inspection.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS Network Firewall&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;You can filter network traffic at the perimeter of your VPC using AWS Network Firewall. Network Firewall is a stateful, managed, network firewall and intrusion detection and prevention service. Rule groups in AWS Network Firewall provide detailed criteria for packet inspection and specify what to do when a packet matches the criteria. When Network Firewall finds a match between the criteria and a packet, the packet matches the rule group.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement end-to-end encryption in transit for all network communication between your users and your application servers.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use a Network Load Balancer and terminate TLS on the EC2 instance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Application Load Balancers load balance at the HTTP and HTTPS level. Network Load Balancers work at the TCP and TLS level. For end-to-end encryption, you need to terminate SSL /TLS on the EC2 instance and this is only possible using the Network Load Balancer or Classic Load Balancer.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deliver content over HTTPS and users will only be able to access the website using CloudFront. In which region do you request an SSL cert?
&lt;/h3&gt;

&lt;p&gt;If you want to require HTTPS between viewers and CloudFront, you must change the AWS region to US East 1 (N. Virginia) in the AWS Certificate Manager console before you request or import a certificate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Protecting against SQL injection and cross-site scripting attacks.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AWS WAF&lt;/strong&gt; is a web application firewall that helps protect web applications from attacks by allowing you to configure rules that allow, block, or monitor web requests based on conditions that you define. These conditions include IP addresses, HTTP headers, HTTP body, URI strings, SQL injection and cross-site scripting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement a solution to help protect the website from DDoS attacks. Services to use:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AWS Shield&lt;/li&gt;
&lt;li&gt;AWS WAF&lt;/li&gt;
&lt;li&gt;Amazon CloudFront&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When attempting to protect your application against DDoS attacks, services such as Route 53, Amazon CloudFront, Elastic Load Balancing, and AWS WAF can all be used to control and absorb traffic, and deflect unwanted requests. AWS Shield is a managed Distributed Denial of Service (DDoS) protection service that safeguards applications running on AWS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Help an IT organization meet security audit requirements imposed on them by a prospective customer.
&lt;/h3&gt;

&lt;p&gt;Employ &lt;strong&gt;Amazon Inspector&lt;/strong&gt; to periodically assess applications for vulnerabilities or deviations from best practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Most efficiently protect against SQL injection attacks.
&lt;/h3&gt;

&lt;p&gt;Use &lt;strong&gt;AWS WAF&lt;/strong&gt; to deny requests that contain SQL code&lt;/p&gt;

&lt;h3&gt;
  
  
  Website uses an S3 bucket configured as a website endpoint behind a CloudFront distribution, using a custom domain name. Make sure users are only allowed to access the website using HTTPS.
&lt;/h3&gt;

&lt;p&gt;Provide a custom SSL Certificate in CloudFront and configure CloudFront to use HTTPS to get files from your S3 bucket (origin)&lt;/p&gt;

&lt;h3&gt;
  
  
  Stateful/stateless sec groups and ACLs.
&lt;/h3&gt;

&lt;p&gt;Security Groups are stateful, so only an outbound rule is required. Network ACLs are stateless, so both an inbound and outbound rule is required. The third party will not reply using the same port, instead it will use ephemeral ports. So the Network ACL will need to allow the reply to come through using ephemeral ports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto patches of  Windows Server EC2 instance.
&lt;/h3&gt;

&lt;p&gt;Make use of Patch Manager and the AWS-DefaultPatchBaseline pre-defined baseline&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The default predefined patch baseline for Windows servers in Patch Manager is AWS-DefaultPatchBaseline.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bucket policy keys used in a conditional to test for encrypted connections.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;aws:SecureTransport&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key &lt;code&gt;aws:SecureTransport&lt;/code&gt; can be used in a conditional statement to determine if the connection is encrypted (&lt;code&gt;Condition: {Bool: {aws:SecureTransport: true}}&lt;/code&gt; for example). &lt;/p&gt;

&lt;h3&gt;
  
  
  Protect your website against DDoS attacks, SQL injection and cross-site scripting attacks. Services to be used:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS WAF to protect against SQL injection&lt;/li&gt;
&lt;li&gt;Use AWS WAF to protect against DDoS attacks&lt;/li&gt;
&lt;li&gt;Use AWS WAF to protect against cross-site scripting&lt;/li&gt;
&lt;li&gt;Use AWS Shield to protect against DDoS attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;AWS Shield protects against DDoS, AWS WAF protects against SQL injection and cross-site scripting. AWS WAF rules can block common web-based attacks.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>cloudinfrastructure</category>
      <category>security</category>
    </item>
    <item>
      <title>AWS Certified Security - Specialty | Logging and Monitoring (notes)</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Mon, 06 Dec 2021 21:58:19 +0000</pubDate>
      <link>https://dev.to/olegchursin/aws-certified-security-specialty-logging-and-monitoring-notes-3li7</link>
      <guid>https://dev.to/olegchursin/aws-certified-security-specialty-logging-and-monitoring-notes-3li7</guid>
      <description>&lt;p&gt;While getting ready to sit AWS Certified Security - Specialty exams, I jotted down a few notes. Breaking them into sections corresponding to the exam domains. Here's Logging and Monitoring domain.&lt;/p&gt;

&lt;p&gt;Each note starts with a problem/situation statement in bold followed up with either a service description or a list of practical actions to be taken in response to the stated problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application crashed but no logs exist for this application. What’s going on?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The CloudWatch Logs agent is not installed&lt;/li&gt;
&lt;li&gt;The CloudWatch Logs agent is not running&lt;/li&gt;
&lt;li&gt;The Instance role does not have permission to write to CloudWatch Logs
&lt;em&gt;Access to AWS resources requires permissions. You need to create an IAM role that includes the permissions you need for the CloudWatch agent to write logs to CloudWatch. The CloudWatch agent must be installed and running in order for the EC2 instance to send application logs to CloudWatch Logs.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The existing trail configuration needs to be modified to stop management events from being logged in the S3 bucket
&lt;/h3&gt;

&lt;p&gt;Update the Management Events option to None. Since a trail configuration can only reference a single S3 bucket, a new trail must be created. The new trail needs to be configured to log only management events to a different S3 bucket. Additionally, a bucket policy is required to give CloudTrail the necessary permissions to write logs to the specified S3 bucket. CloudTrail trail configurations do not inherit from other trails and editing a trail configuration is not against best practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  You are not able to access the application from the internet, from your other VPC or from your own data centre. Security groups and network ACLs are configured  correctly.
&lt;/h3&gt;

&lt;p&gt;Use &lt;strong&gt;VPC Flow Logs&lt;/strong&gt; to analyze the traffic. VPC Flow Logs enables you to capture information about the IP traffic going to and from network interfaces in your VPC. Flow logs can help you with a number of tasks; for example, to troubleshoot why specific traffic is not reaching an instance, which in turn helps you diagnose overly restrictive security group rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  You need to create a new AWS account to stream all important CloudWatch events from various AWS accounts to a single account to centralize security efforts.
&lt;/h3&gt;

&lt;p&gt;You can deliver the events to other accounts through a new &lt;strong&gt;CloudWatch Events&lt;/strong&gt; resource called &lt;strong&gt;Event Bus&lt;/strong&gt;. All AWS accounts have one default event bus. To send events to another account, you simply write rules to match the events of interest and attach an event bus in the receiving account as the target to the rule. CloudWatch Event Rules are used to trigger predefined actions based on a given type of event and are not used to send events to other accounts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data events for Lambda and S3 are not available in Amazon CloudWatch Events. What could be the reason for this?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your Lambda function and S3 resources haven’t been added to a CloudTrail trail.&lt;/li&gt;
&lt;li&gt;Data events are not logged by default.
&lt;em&gt;Data events provide visibility into the resource operations performed on or within a resource. Data events are not logged by default when you create a trail. To record CloudTrail data events, you must explicitly add the supported resources or resource types for which you want to collect activity to a trail.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Analyze the API activity in your AWS account and have the ability to isolate activity by attributes, such as source IP address and user. Which services can you use?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Athena&lt;/li&gt;
&lt;li&gt;CloudTrail
&lt;em&gt;CloudTrail is used to record all API activity in your account. Using Athena with CloudTrail logs is a powerful way to enhance your analysis of AWS service activity. For example, you can use standard SQL queries to identify trends and further query activity by attributes, such as source IP address or user.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  You are unable to access CloudTrail logs. You have checked your IAM permissions, and your user account is allowed to describe CloudTrail logs and look up events. What could be the problem?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You do not have read permission for the S3 bucket.&lt;/li&gt;
&lt;li&gt;You do not have permission to use the CMK to decrypt the logs.
&lt;em&gt;You must have S3 read permission on the bucket. If you are using KMS to encrypt the logs, any user who accesses the logs must be granted decrypt permission by the CMK policy.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Multiple separate AWS accounts are configured to send CloudTrail logs to the same S3 bucket. However some of the accounts have not been sending any logs. What is the problem?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The accounts do not have permission to write to the S3 bucket
&lt;em&gt;You can have CloudTrail deliver log files from multiple AWS accounts into a single Amazon S3 bucket. To accomplish this, turn on CloudTrail in the account where the destination bucket will belong, configure the bucket policy to allow cross-account permission. Turn on CloudTrail in the other accounts, configure all accounts to log to the destination bucket.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Which AWS CLI fragment command can be used to determine the integrity of the CloudTrail log files.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;aws cloudtrail validate-logs&lt;/code&gt;
The CLI command fragment, &lt;code&gt;aws cloudtrail validate-logs&lt;/code&gt; will identify if any of the CloudTrail logs have been modified or deleted. The other choices are incorrect.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  You have noticed some unusual activity in your AWS account. You need to quickly assess the situation, understand the extent of the problem and would like to continually monitor your infrastructure.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;GuardDuty&lt;/strong&gt; is a continuous security monitoring service that analyzes and processes the following data sources: VPC Flow Logs, AWS CloudTrail event logs, and DNS logs. It uses threat intelligence feeds, such as lists of malicious IPs and domains, and machine learning to identify malicious activity. For example, GuardDuty can detect unusual behavior like sending spam emails, querying a domain name associated with a known command and control server, generating a large volume of outbound TCP traffic - all signs that the instance is being controlled by a malicious actor.&lt;/p&gt;

&lt;h3&gt;
  
  
  You need to separate data and management events in CloudTrail logs. What is the best way to configure this so that everyone gets the access they need on a least privilege basis?
&lt;/h3&gt;

&lt;p&gt;Configure two CloudTrails, one to log data events and one to log management events with each trail logging to a different S3 bucket. Create 2 different IAM policies and attach them to the appropriate groups, one allowing read only access to the data events CloudTrail and associated S3 bucket and one allowing read only access to the management events CloudTrail and associated S3 bucket.&lt;/p&gt;

&lt;p&gt;Management and Data events are handled by separate CloudTrails. You should log the events to separate buckets, then configure access to the CloudTrail and read only access to the S3 bucket using an IAM policy attached to the user or group. Give each class of user only the access they need. Log Groups are related to CloudWatch not CloudTrail.&lt;/p&gt;

&lt;h3&gt;
  
  
  You suspect that one of your instances has been compromised and is attempting to communicate with a command and control server. Which services can you use to investigate this?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Amazon Inspector&lt;/li&gt;
&lt;li&gt;VPC Flow Logs&lt;/li&gt;
&lt;li&gt;GuardDuty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use &lt;strong&gt;Amazon Inspector&lt;/strong&gt; to assess your assessment targets (collections of AWS resources) for potential security issues and vulnerabilities. Amazon Inspector compares the behavior and the security configuration of the assessment targets to selected security rules packages. In the context of Amazon Inspector, a rule is a security check that Amazon Inspector performs during the assessment run. The rules in the Network Reachability package analyze your network configurations to find security vulnerabilities of your EC2 instances. These rules help automate the monitoring of your AWS networks and identify where network access to your EC2 instances might be misconfigured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VPC Flow Logs&lt;/strong&gt; can be used as a security tool to monitor the traffic that is reaching your instance, to profile your network traffic, and to look for abnormal traffic behaviors. You can use VPC Flow Logs to watch for abnormal and unexpected denied outbound connection requests, which could be an indication of a misconfigured or compromised EC2 instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GuardDuty&lt;/strong&gt; continuously analyzes VPC Flow Logs and DNS requests and responses to identify malicious, unauthorized, or unexpected behavior in your AWS accounts and workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Have CloudTrail deliver log files from multiple AWS accounts into a single Amazon S3 bucket. Two approaches.
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To accomplish this, turn on CloudTrail in the account where the destination bucket will belong, configure the bucket policy to allow cross-account permission. Turn on CloudTrail in the other accounts, configure all accounts to log to the destination bucket. You cannot configure cross account access using the bucket ACL.&lt;/li&gt;
&lt;li&gt;Use AWS CloudTrail and a user in a management account to create an organization trail that logs all events for all AWS accounts in that organization in the same Amazon S3 bucket.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Determine if any EC2 instances are used for bitcoin mining.
&lt;/h3&gt;

&lt;p&gt;Use AWS GuardDuty to see if any of your instances are querying a domain name that is associated with cryptocurrency-related activity&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GuardDuty is a continuous security monitoring service that analyzes and processes the following data sources: VPC Flow Logs, AWS CloudTrail event logs, and DNS logs. It uses threat intelligence feeds, such as lists of malicious IPs and domains, and machine learning to identify malicious activity. This can include issues like escalations of privileges, uses of exposed credentials, or communication with malicious IPs, URLs, or domains. For example, GuardDuty can detect compromised EC2 instances serving malware or mining bitcoin.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>logging</category>
      <category>security</category>
    </item>
    <item>
      <title>AWS Certified Security - Specialty | Incident response (notes)</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Mon, 06 Dec 2021 17:39:34 +0000</pubDate>
      <link>https://dev.to/olegchursin/aws-certified-security-specialty-incident-response-notes-19em</link>
      <guid>https://dev.to/olegchursin/aws-certified-security-specialty-incident-response-notes-19em</guid>
      <description>&lt;p&gt;While getting ready to sit AWS Certified Security - Specialty exams, I jotted down a few notes. Breaking them into sections corresponding to the exam domains. Let's start with Incident Response in this post. &lt;/p&gt;

&lt;p&gt;Each note starts with a &lt;strong&gt;problem/situation statement in bold&lt;/strong&gt; followed up with either a service description or a list of practical actions to be taken in response to the stated problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your AWS account has been compromised. Your immediate actions.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Change your AWS account root user password. &lt;/li&gt;
&lt;li&gt;Delete or rotate all root and AWS Identity and Access Management (IAM) access keys. &lt;/li&gt;
&lt;li&gt;Delete any potentially compromised IAM users, and change the password for all other IAM users. &lt;/li&gt;
&lt;li&gt;Delete any resources on your account you didn’t create, such as EC2 instances and AMIs, EBS volumes and snapshots, and IAM users.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Isolate any compromised instances so that they cannot communicate with any other instances in your VPC or with any third party command and control server.
&lt;/h3&gt;

&lt;p&gt;Create a restrictive &lt;strong&gt;Security Group&lt;/strong&gt; which only allows SSH from a single forensic workstation. Use &lt;strong&gt;Lambda&lt;/strong&gt; to replace the existing Security Group with the newly created restrictive Security Group as soon as the instance is detected as being compromised. You cannot apply a Network ACL to an instance because ACLs apply to the whole subnet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enable CloudTrail logging in all regions where you currently have AWS infrastructure
&lt;/h3&gt;

&lt;p&gt;Enable &lt;strong&gt;multi-region CloudTrail&lt;/strong&gt;. You can configure CloudTrail to deliver log files from multiple regions to a single S3 bucket for a single account. When a new region launches in the AWS partition, CloudTrail automatically creates a trail for you in the new region with the same settings as your original trail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service that uses machine learning to help monitor malicious activity and unauthorized behavior to protect your AWS accounts, workloads, and data stored in S3.
&lt;/h3&gt;

&lt;p&gt;Amazon &lt;strong&gt;GuardDuty&lt;/strong&gt; is the only solution that that uses machine learning to help monitor malicious activity and unauthorized behavior to protect your AWS accounts, workloads, and data stored in S3. It has a build-in list of suspect IP addresses and you can also upload your own lists of IPs. GuardDuty can trigger CloudWatch events which can then be used for a variety of activities like notifications or automatically responding to a threat. AWS Macie is a service to discovery and classify potentially sensitive information. CloudWatch alone lacks the business rules that are provided with GuardDuty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quickly block this malicious activity from a specific range of IP addresses.
&lt;/h3&gt;

&lt;p&gt;Create a &lt;strong&gt;Network ACL&lt;/strong&gt; to deny access to any traffic coming from this IP range. A Network Access Control List is an optional layer of security for your VPC which acts as a firewall, controlling traffic in and out of one or more subnets. Security Groups cannot be used to explicitly deny traffic from a known IP range. Flow Logs are used to monitor network traffic, but cannot be used to block traffic. GuardDuty only detects malicious activity, it cannot block traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restrict user ability to launch EC2 instances and change Security Group settings at any time.
&lt;/h3&gt;

&lt;p&gt;Implement event based security using &lt;strong&gt;CloudTrail&lt;/strong&gt; and &lt;strong&gt;CloudWatch Events&lt;/strong&gt; which alerts when a user performs an action which is against company policy and sends an SNS notification. With CloudTrail, you can log, continuously monitor, and retain account activity related to actions across your AWS infrastructure. CloudTrail provides event history of your AWS account activity, including actions taken through the AWS Management Console, AWS SDKs, command line tools, and other AWS services. This event history simplifies security analysis, resource change tracking, and troubleshooting. In addition, you can use CloudTrail to detect unusual activity in your AWS accounts. CloudWatch Events can respond to unauthorized actions detected by CloudTrail and send SNS notifications to report security breaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  IDS/IPS - intrusion detection systems, intrusion prevention systems.
&lt;/h3&gt;

&lt;p&gt;If you are running a third-party IDS/IPS on EC2 and want to configure your IDS system to trigger an automated response to contain an attack by immediately shutting down affected systems if an intrusion is detected, you should send the &lt;strong&gt;IDS application logs&lt;/strong&gt; to &lt;strong&gt;CloudWatch Logs&lt;/strong&gt;, use CloudWatch to send an &lt;strong&gt;SNS&lt;/strong&gt; notification alerting you of any incidents. Use Lambda to shut down affected systems.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>ir</category>
      <category>security</category>
    </item>
    <item>
      <title>How To Export Data to Excel in Angular</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Wed, 17 Jun 2020 19:30:09 +0000</pubDate>
      <link>https://dev.to/olegchursin/how-to-export-data-to-excel-in-angular-1od0</link>
      <guid>https://dev.to/olegchursin/how-to-export-data-to-excel-in-angular-1od0</guid>
      <description>&lt;p&gt;Data export to Excel is a common task in modern business-facing apps and of course we have npm packages to help us do just that. An amazing one to consider is &lt;a href="https://www.npmjs.com/package/mat-table-exporter"&gt;Angular Material Table Exporter&lt;/a&gt;. But there are a big prerequisite to use it. Your data has to be rendered using Material Table. If you are OK with it, then follow the docs for the mat-table-exporter package for a painless integration - it works like a charm. One gotcha that you may face is the bundle size. If you follow the default integration steps and add &lt;strong&gt;MatTableExporterModule&lt;/strong&gt; to &lt;code&gt;shared.module.ts&lt;/code&gt;, your bundle size may gain 1.5Mb. Of course you can lazy-load it, move to the server completely, or use the method below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet excel-export Service
&lt;/h2&gt;

&lt;p&gt;We will be using only one fairly low-level dependency - &lt;code&gt;xlsx&lt;/code&gt; and go from there. Let’s make sure we have the latter installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i xlsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have access to a plethora of methods and options provided by this awesome package which will be integrated into &lt;code&gt;excel-export.service.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;TLDR: Here’s what the service looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// excel-export.service.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;utils&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;XLSXUtils&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;writeFile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xlsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WorkBook&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;WorkSheet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xlsx/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IExportAsExcelProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;sheetName&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExcelExportService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fileExtension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.xlsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;exportAsExcel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;sheetName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;
  &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;IExportAsExcelProps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;WorkBook&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;wb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;XLSXUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table_to_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;WorkSheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;XLSXUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json_to_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="nx"&gt;wb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;XLSXUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;book_new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;XLSXUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;book_append_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sheetName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fileExtension&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  What’s going on above?
&lt;/h4&gt;

&lt;p&gt;First, official xlsx docs tell you to import everything from &lt;code&gt;xlsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;XLSX&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xlsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works, but my personal preference is to import individual methods, interfaces, types, and not pull the whole library along. Hence the adjusted import declarations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;utils&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;XLSXUtils&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;writeFile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xlsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WorkBook&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;WorkSheet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xlsx/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will have only one public method &lt;code&gt;exportAsExcel&lt;/code&gt; that takes the following props: &lt;code&gt;data, fileName, sheetName, header, table&lt;/code&gt; with the following interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IExportAsExcelProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;sheetName&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;data&lt;/code&gt; has to be in JSON format to make &lt;code&gt;json_to_sheet&lt;/code&gt; util method happy. Read more about it in the docs: &lt;a href="https://www.npmjs.com/package/xlsx#array-of-objects-input"&gt;json_to_sheet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you prefer to grab the DOM’s &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; Element and convert its contents into Excel doc, just pass the desired HTMLElement through and our service will use &lt;code&gt;table_to_book&lt;/code&gt; method. More info on that in the docs: &lt;a href="https://www.npmjs.com/package/xlsx#html-table-input"&gt;table_to_book&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, &lt;code&gt;fileName&lt;/code&gt; and &lt;code&gt;sheetName&lt;/code&gt; are self-explanatory, se we are left with the last optional prop: &lt;code&gt;header&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This is an array of keys from your data Object that controls the column order. If you don’t explicitly pass it, xlsx defaults to &lt;code&gt;Object.keys&lt;/code&gt;. Read more on &lt;code&gt;header&lt;/code&gt;: &lt;a href="https://github.com/SheetJS/sheetjs#array-of-objects-input"&gt;https://github.com/SheetJS/sheetjs#array-of-objects-input&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I believe this is all. Just massage the data you want to send down or play with the &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; contents and you have a working &lt;strong&gt;Export as Excel&lt;/strong&gt; service you can call whenever you need it.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>excel</category>
    </item>
    <item>
      <title>Browser Security Headers with Gatsby and Netlify</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Thu, 21 May 2020 14:48:13 +0000</pubDate>
      <link>https://dev.to/olegchursin/browser-security-headers-with-gatsby-and-netlify-4f5m</link>
      <guid>https://dev.to/olegchursin/browser-security-headers-with-gatsby-and-netlify-4f5m</guid>
      <description>&lt;p&gt;&lt;em&gt;Our goals:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a simple website (blog)&lt;/li&gt;
&lt;li&gt;add a new blog post&lt;/li&gt;
&lt;li&gt;push it to GitHub&lt;/li&gt;
&lt;li&gt;publish our website to Netlify&lt;/li&gt;
&lt;li&gt;secure it with browser security headers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Your takeaways:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;step-by-step guide on how to publish a website with Netlify&lt;/li&gt;
&lt;li&gt;Netlify config file with working config for basic browser security headers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let’s go
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1. Create a simple website (blog).
&lt;/h3&gt;

&lt;p&gt;Question 0 - which tech stack to use. We will be working with GatsbyJS (&lt;a href="https://www.gatsbyjs.org/"&gt;GatsbyJS&lt;/a&gt;) which is an amazing static site generator allowing to create blazing fast websites at almost no time. I will not waste time enumerating all of the Gatsby features, but do make sure that you play with it. And if you happen to like the result, feel free to join GatsbyNYC Meetup (&lt;a href="https://www.meetup.com/Gatsby-NYC/"&gt;Gatsby NYC (New York, NY) | Meetup&lt;/a&gt;) that I have an honor to co-host.&lt;/p&gt;

&lt;p&gt;Make sure you have &lt;code&gt;gatsby-cli&lt;/code&gt; installed by running &lt;code&gt;gatsby —v&lt;/code&gt;. If not install Gatsby globally with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; gatsby-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GatsbyJS has a concept they call starters. And for our needs we will chose &lt;em&gt;gatsby-starter-blog&lt;/em&gt; (&lt;a href="https://www.gatsbyjs.org/starters/gatsbyjs/gatsby-starter-blog/"&gt;gatsby-starter-blog: Gatsby Starter | GatsbyJS&lt;/a&gt;) that will leave us with a simple setup to jump-start a blog. By the way, this starter was inspired by Dan Abramov’s blog - Overreacted, which in it’s own turn is a Gatsby website (&lt;a href="https://overreacted.io/"&gt;Overreacted — A blog by Dan Abramov&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Let’s create a new project with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gatsby new our-blog-name https://github.com/gatsbyjs/gatsby-starter-blog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And open it in your favorite text-editor.  You will get the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; content
&amp;gt; node_modules
&amp;gt; src
&amp;gt; static
  .gitignore
  .prettierignore
  .prettierrc
  gatsby-browser.js
  gatsby-config.js
  gatsby-node.js
  LICENSE
  package-lock.json
  package.json
  README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The folder that is of interest to us is &lt;code&gt;content&lt;/code&gt; - that’s where our blog posts live in the for of markdown files. And that’s where we will be adding our new blog post.&lt;/p&gt;

&lt;p&gt;It’s high time to see something in the browser. Fire up your newly created blog with  &lt;code&gt;npm start&lt;/code&gt; or &lt;code&gt;yarn start&lt;/code&gt;. This will run &lt;code&gt;gatsby develop&lt;/code&gt; command under the hood which will do it’s magic and make your blog available at &lt;code&gt;http://localhost:8000/&lt;/code&gt; by default. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2. Add a new blog post
&lt;/h3&gt;

&lt;p&gt;You may have noticed that Gatsby gives you some magic to play with. Folders (folder-names) in &lt;code&gt;content &amp;gt; blog&lt;/code&gt; automagically become routes. The same thing happens with folders in &lt;code&gt;pages&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Therefore, we will create a new folder in &lt;code&gt;blog&lt;/code&gt;. Let’s name it &lt;code&gt;deploy-and-secure&lt;/code&gt;. Inside the newly created folder we will touch &lt;code&gt;index.md&lt;/code&gt;file with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy Your Site Securely and Easily with Netlify and Browser Headers&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2020-05-20T22:12:03.284Z"&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Site&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Securely&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Easily&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Netlify&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Browser&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Headers"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="ge"&gt;*Our goals:*&lt;/span&gt;
&lt;span class="p"&gt;*&lt;/span&gt; create a simple website (blog)
&lt;span class="p"&gt;*&lt;/span&gt; add a new blog post
&lt;span class="p"&gt;*&lt;/span&gt; push it to GitHub
&lt;span class="p"&gt;*&lt;/span&gt; publish our website to Netlify
&lt;span class="p"&gt;*&lt;/span&gt; secure it with browser security headers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The part in between &lt;code&gt;---&lt;/code&gt; is called the front matter.  You may have come across it if you have a blog on DEV.to. The rest is a good old markdown file. Just add your content and publish.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3. Publish our blog with Netlify.
&lt;/h3&gt;

&lt;p&gt;There are numerous ways to publish your static site these days, but Netlify is probably one of the coolest.&lt;/p&gt;

&lt;p&gt;Things we need to be successful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a website&lt;/li&gt;
&lt;li&gt;GitHub repo&lt;/li&gt;
&lt;li&gt;Netlify account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We already have our new and shiny website. You don’t need my help to push it to a GitHub repo. Let’s do the Netlify part. &lt;/p&gt;

&lt;p&gt;Next steps are taken under assumption that you created a Netlify account and connected it to your GitHub account. Easy.&lt;/p&gt;

&lt;p&gt;So, within Netlify we click on &lt;code&gt;New site from Git&lt;/code&gt; to setup our CD flow. Netlify will prompt us with the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Continuous Deployment
&lt;/h2&gt;

&lt;p&gt;Choose the Git provider where your site’s source code is hosted. When you push to Git, we run your build tool of choice on our servers and deploy the result.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We chose GitHub, search for the needed repo and select it.&lt;/p&gt;

&lt;p&gt;Then we specify &lt;code&gt;branch to deploy&lt;/code&gt;. In our case let’s stick to default &lt;code&gt;master&lt;/code&gt; , although for most of my personal projects I prefer to have a separate &lt;code&gt;prod&lt;/code&gt; branch. Netlify is crazy smart so it already knows that we have a Gatsby site, so in &lt;strong&gt;Basic build settings&lt;/strong&gt; section it gives us all the needed defaults for &lt;code&gt;build command&lt;/code&gt; and &lt;code&gt;publish directory&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hit &lt;strong&gt;Deploy site&lt;/strong&gt; now. Wait… and wait again. Once it’s done you site is available under netlify-generated url. Let’s change that. &lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;Domain settings&lt;/strong&gt; and under Custom domains click on &lt;strong&gt;Options&lt;/strong&gt; and &lt;strong&gt;Edit this name&lt;/strong&gt;. Save your changes and voila you have your site on &lt;a href="https://your-site-name.netlify.com"&gt;https://your-site-name.netlify.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4. Secure your website with browser security headers
&lt;/h3&gt;

&lt;p&gt;Always start with definition:&lt;br&gt;
Browser security headers - HTTP response headers that your application can use to increase the security of your application. Once set, these HTTP response headers can restrict modern browsers from running into easily preventable vulnerabilities.&lt;/p&gt;
&lt;h4&gt;
  
  
  More information on headers:
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;OWASP Secure Headers Project&lt;/em&gt;&lt;br&gt;
bit.ly/owasp-security-headers&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MDN docs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strict-Transport-Security // &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security"&gt;Strict-Transport-Security - HTTP | MDN&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Content Security Policy (CSP) // &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP"&gt;Content Security Policy (CSP) - HTTP | MDN&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;X-Frame-Options // &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options"&gt;X-Frame-Options - HTTP | MDN&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;X-Content-Type-Options // &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options"&gt;X-Content-Type-Options - HTTP | MDN&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Referrer-Policy // &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy"&gt;Referrer-Policy - HTTP | MDN&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Feature-Policy // &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy"&gt;Feature-Policy - HTTP | MDN&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Course on Pluralsight&lt;/strong&gt;&lt;br&gt;
Introduction to Browser Security Headers by Troy Hunt&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source: &lt;a href="https://www.pluralsight.com/courses/browser-security-headers"&gt;Introduction to Browser Security Headers | Pluralsight&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  How to add headers in Netlify
&lt;/h4&gt;

&lt;p&gt;RTFM. Netlify docs on custom headers: &lt;a href="https://docs.netlify.com/routing/headers/"&gt;Custom headers | Netlify Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Straightforward, right? Let’s do it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;netlify.toml&lt;/code&gt; to the root.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[[headers]]&lt;/span&gt;
  &lt;span class="py"&gt;for&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/*"&lt;/span&gt;
  &lt;span class="nn"&gt;[headers.values]&lt;/span&gt;
    &lt;span class="py"&gt;Strict-Transport-Security&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;"max-age&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;63072000&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt; &lt;span class="err"&gt;includeSubDomains;&lt;/span&gt; &lt;span class="err"&gt;preload&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    &lt;span class="py"&gt;Content-Security-Policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"default-src data: 'unsafe-inline' 'unsafe-eval' https:; script-src data: 'unsafe-inline' 'unsafe-eval' https: blob:; style-src data: 'unsafe-inline' https:; img-src data: https: blob:; font-src data: https:; connect-src https: wss: blob:; media-src https: blob:; object-src https:; child-src https: data: blob:; form-action https:; block-all-mixed-content"&lt;/span&gt;
    &lt;span class="py"&gt;X-Frame-Options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"DENY"&lt;/span&gt;
    &lt;span class="py"&gt;X-Content-Type-Options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"nosniff"&lt;/span&gt;
    &lt;span class="py"&gt;Referrer-Policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"no-referrer"&lt;/span&gt;
    &lt;span class="py"&gt;Feature-Policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"microphone 'none'; geolocation 'none'"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be extra careful with &lt;code&gt;Content-Security-Policy&lt;/code&gt; header. You may end up breaking your site by blocking your end-users from being able to load your content. You may find this tool helpful in generating CSP for you: &lt;a href="https://report-uri.com/home/generate"&gt;Report URI: Generate your Content Security Policy&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Take you HSTS setup step further with Chromium project
&lt;/h4&gt;

&lt;p&gt;The HSTS value needs to be:&lt;br&gt;
&lt;code&gt;Strict-Transport-Security: max-age=31536000; includeSubdomains; preload&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can make sure that your site is preloaded into Chromium browsers as the one that is always served over &lt;code&gt;https&lt;/code&gt;. Use this tool to do it: &lt;a href="https://hstspreload.org/"&gt;HSTS Preload List Submission&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is it. We’ve gone through all the steps and have successfully created, deployed, and secured our website with browser security headers on Netlify.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>netlify</category>
      <category>security</category>
    </item>
    <item>
      <title>How to squash Git commits</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Mon, 02 Mar 2020 16:05:15 +0000</pubDate>
      <link>https://dev.to/olegchursin/how-to-squash-git-commits-16lf</link>
      <guid>https://dev.to/olegchursin/how-to-squash-git-commits-16lf</guid>
      <description>&lt;p&gt;A really quick step-by-step guide on how to squash Git commits to make your PRs concise, easy to read, and hence easy to review.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure your branch is up to date with the &lt;code&gt;main&lt;/code&gt; branch.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;git rebase -i main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You should see a list of commits, each commit starting with the word "pick".&lt;/li&gt;
&lt;li&gt;Make sure the first commit says "pick" and change the rest from "pick" to "squash". -- This will squash each commit into the previous commit, which will continue until every commit is squashed into the first commit.&lt;/li&gt;
&lt;li&gt;Save and close the editor (press &lt;code&gt;Esc&lt;/code&gt; key, type &lt;code&gt;:w&lt;/code&gt; and hit &lt;code&gt;Enter&lt;/code&gt; key) -- save a file and quit vim / Vi by pressing &lt;code&gt;Esc&lt;/code&gt; key, type &lt;code&gt;:x&lt;/code&gt; and hit &lt;code&gt;Enter&lt;/code&gt; key.&lt;/li&gt;
&lt;li&gt;It will give you the opportunity to change the commit message.&lt;/li&gt;
&lt;li&gt;Save and close the editor again.&lt;/li&gt;
&lt;li&gt;Force push the squashed commit: &lt;code&gt;git push --force-with-lease origin&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/olegchursin/fd0d6b3d3893be3b58c48036d5be118f"&gt;GitHub gist of the steps above&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>commits</category>
    </item>
    <item>
      <title>Gatsby Auth with AWS Amplify</title>
      <dc:creator>Oleg Chursin</dc:creator>
      <pubDate>Fri, 14 Feb 2020 00:22:22 +0000</pubDate>
      <link>https://dev.to/olegchursin/gatsby-auth-with-aws-amplify-pfa</link>
      <guid>https://dev.to/olegchursin/gatsby-auth-with-aws-amplify-pfa</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR:&lt;/em&gt; GitHub repo: &lt;a href="https://github.com/olegchursin/gatsby-auth-amplify"&gt;https://github.com/olegchursin/gatsby-auth-amplify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Steps to follow along:&lt;/p&gt;

&lt;h2&gt;
  
  
  Create new Gatsby project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gatsby new gatsby-auth-amplify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add TS (optional)
&lt;/h2&gt;

&lt;p&gt;This step is optional but highly recommended&lt;/p&gt;

&lt;h3&gt;
  
  
  Add TS plugin
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add gatsby-plugin-typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add TypeScript definitions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; @types/react @types/react-dom @types/node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Change files extensions
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;.js&lt;/code&gt; —&amp;gt; &lt;code&gt;.tsx&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hook up AWS Amplify Framework
&lt;/h2&gt;

&lt;p&gt;Auth is handled by AWS Cognito&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install AWS Amplify CLI&lt;/li&gt;
&lt;li&gt;Configure Amplify&lt;/li&gt;
&lt;li&gt;Initialize inside Gatsby project&lt;/li&gt;
&lt;li&gt;Add Auth API&lt;/li&gt;
&lt;li&gt;Deploy the config to AWS&lt;/li&gt;
&lt;li&gt;Protect the ‘protected-page’&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1. Install AWS Amplify CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @aws-amplify/cli
amplify &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Amplify
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;amplify configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actionable bash response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Sign &lt;span class="k"&gt;in &lt;/span&gt;to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actionable bash response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Specify the AWS Region
? region:  &lt;span class="o"&gt;(&lt;/span&gt;Use arrow keys&lt;span class="o"&gt;)&lt;/span&gt;
❯ us-east-1
  us-east-2
  us-west-2
  eu-west-1
  eu-west-2
  eu-central-1
  ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will also need to provide user name and configure IAM user within the console.&lt;br&gt;
NB: Save you credentials (download .csv or copy access keys)&lt;/p&gt;

&lt;p&gt;Actionable bash response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Enter the access key of the newly created user:
? accessKeyId:  AKIA355I4O&lt;span class="k"&gt;**********&lt;/span&gt;
? secretAccessKey:  ehf7gWSzPULXtNN0d0v&lt;span class="k"&gt;******************&lt;/span&gt;
This would update/create the AWS Profile &lt;span class="k"&gt;in &lt;/span&gt;your &lt;span class="nb"&gt;local &lt;/span&gt;machine
? Profile Name:  olegchursin

Successfully &lt;span class="nb"&gt;set &lt;/span&gt;up the new user.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2. Initialize inside Gatsby project
&lt;/h3&gt;

&lt;p&gt;from the root of your project run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;amplify init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actionable bash response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;? Enter a name &lt;span class="k"&gt;for &lt;/span&gt;the project gatsby-auth-amplify
? Enter a name &lt;span class="k"&gt;for &lt;/span&gt;the environment dev
? Choose your default editor: Visual Studio Code
? Choose the &lt;span class="nb"&gt;type &lt;/span&gt;of app that you&lt;span class="s1"&gt;'re building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actionable bash response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default
Adding backend environment dev to AWS Amplify Console app: d1mhcdbiatabfc
⠧ Initializing project &lt;span class="k"&gt;in &lt;/span&gt;the cloud...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explore the newly generated &lt;code&gt;amplify&lt;/code&gt; folder: &lt;a href="https://share.getcloudapp.com/mXuqRmY2"&gt;Screenshot: amplify folder structure&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3. Add Auth API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;amplify add auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actionable bash response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Do you want to use the default authentication and security configuration? Default configuration
 Warning: you will not be able to edit these selections. 
 How &lt;span class="k"&gt;do &lt;/span&gt;you want &lt;span class="nb"&gt;users &lt;/span&gt;to be able to sign &lt;span class="k"&gt;in&lt;/span&gt;? Username
 Do you want to configure advanced settings? No, I am &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Successfully added resource gatsbyauthamplifycba7570a locally
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4. Deploy the config to AWS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;amplify push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actionable bash response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category | Resource name             | Operation | Provider plugin   |
| &lt;span class="nt"&gt;--------&lt;/span&gt; | &lt;span class="nt"&gt;-------------------------&lt;/span&gt; | &lt;span class="nt"&gt;---------&lt;/span&gt; | &lt;span class="nt"&gt;-----------------&lt;/span&gt; |
| Auth     | gatsbyauthamplifycba7570a | Create    | awscloudformation |
? Are you sure you want to &lt;span class="k"&gt;continue&lt;/span&gt;? &lt;span class="o"&gt;(&lt;/span&gt;Y/n&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should have a new &lt;code&gt;auth&lt;/code&gt; folder inside &lt;code&gt;amplify/backend&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Go to AWS console &lt;code&gt;Cognito —&amp;gt; User Pools&lt;/code&gt; and make sure your generated pool is there as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5. Protect the ‘protected-page’
&lt;/h3&gt;

&lt;p&gt;Install new libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add aws-amplify aws-amplify-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following to &lt;code&gt;gatsby-browser.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Amplify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Auth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-amplify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;awsConfig&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/aws-exports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;Amplify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;awsConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;withAuthenticator&lt;/code&gt; to your protected-page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;import it:&lt;br&gt;
&lt;code&gt;import { withAuthenticator } from “aws-amplify-react”&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;wrap the export:&lt;br&gt;
&lt;code&gt;export default withAuthenticator(ProtectedPage)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you should be greeted with the login view: &lt;a href="https://share.getcloudapp.com/BluBLZLk"&gt;Screenshot: Login view&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;code&gt;Create account&lt;/code&gt;, provide an email address that you have access to (for a confirmation code), have fun!&lt;/p&gt;

&lt;h4&gt;
  
  
  Resources
&lt;/h4&gt;

&lt;p&gt;Gatsby Auth Amplify Starter by nadir Dabit: &lt;a href="https://www.gatsbyjs.org/starters/dabit3/gatsby-auth-starter-aws-amplify/"&gt;gatsby-auth-starter-aws-amplify: Gatsby Starter | GatsbyJS&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Video tutorial by Arbaoui Mehdi: &lt;a href="https://www.youtube.com/watch?v=Rrv_rYhAQw0"&gt;Gatsby and AWS Amplify Authentication - YouTube&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploying to AWS Amplify: &lt;a href="https://www.gatsbyjs.org/docs/deploying-to-aws-amplify/"&gt;Deploying to AWS Amplify | GatsbyJS&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;#GatsbyNYC&lt;/code&gt;&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>aws</category>
      <category>amplify</category>
    </item>
  </channel>
</rss>
