<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://cromwellhaus.com/">
  <title>Ryan Cromwell</title>
  <subtitle>Software, teams, and the craft of building things — writing since 2005.</subtitle>
  <link href="https://cromwellhaus.com/feed.xml" rel="self"/>
  <link href="https://cromwellhaus.com/"/>
  <updated>2021-08-06T00:00:00Z</updated>
  <id>https://cromwellhaus.com/</id>
  <author><name>Ryan Cromwell</name></author>
  <entry>
    <title>Using Terraform to automate the creation and deprovisioning of AWS Member Accounts</title>
    <link href="https://cromwellhaus.com/2021/08/leaving-aws-subaccounts-behind/"/>
    <updated>2021-08-06T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2021/08/leaving-aws-subaccounts-behind/</id>
    <content type="html">&lt;p&gt;We &lt;a href=&quot;https://github.com/sparkbox/aws-infrastructure/tree/main/modules/development-team&quot;&gt;automate provisioning developer AWS sandbox accounts&lt;/a&gt; for our team at Sparkbox. These accounts are paid for by the parent organization. This gives our team full access to learn and prototype with all of AWS&#39; services. We use Billing threshold notifications to keep things from spinning out of control.&lt;/p&gt;
&lt;p&gt;It&#39;s relatively easy to create the organizations, users, and AWS accounts. The code fits in a nice module. The challenge we face comes when a team member leaves. When they leave, we need to quickly remove access to Sparkbox resources per our security policy.&lt;/p&gt;
&lt;p&gt;Terraform makes this seeming simple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sparkbox/aws-infrastructure/commit/6ace68ae4fce1f76e45769c3de6d5a8fbd8f9a71#diff-4b9b83568bdde9f27a3f6763676955c22280a5a7bb9fde8a1ca9e17212b73506&quot;&gt;Remove the user from teammembers.auto.tfvars&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Push the commit to Github&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.terraform.io/cloud&quot;&gt;Terraform Cloud&lt;/a&gt; kicks off a new run, planing and auto applying the changes necessary&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Simple! User, policies, login profile, etc are all destroyed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remove Access to Sandbox Accounts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, &lt;a href=&quot;https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/consolidated-billing.html&quot;&gt;consolidated billing&lt;/a&gt; throws a wrench in the situation. Deleting an account really just removes it from the organization. To do this, the account must have a payment method configured. This isn&#39;t an option to automate.&lt;/p&gt;
&lt;p&gt;Our goal is to remove former team members&#39; access to Sparkbox resources. Our Terraform automation was conflating this with deleting their accounts. It&#39;s reasonable think that, but not necessary. So instead, we&#39;ll separate the concepts of &lt;em&gt;enabled users that should have access&lt;/em&gt; from &lt;em&gt;all users that we have created accounts&lt;/em&gt; in our Terraform code:&lt;/p&gt;
&lt;pre class=&quot;language-hcl&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-hcl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;locals&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;enabled_user_names&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    for user in var.users : user.name
    if user.is_enabled
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;all_user_names&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; toset(&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    for user in var.users : user.name
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;)
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can use these individually local variables for their unique purposes:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/sparkbox/aws-infrastructure/blob/24e4796315876292b4562bd2aa39efc6d85771a7/modules/development-team/main.tf#L46-L50&quot;&gt;&lt;em&gt;Users that should exist:&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-hcl&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-hcl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;resource &lt;span class=&quot;token type variable&quot;&gt;&quot;aws_iam_user&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;user&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;for_each&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; toset(local.enabled_user_names)
  &lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; each.value
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/sparkbox/aws-infrastructure/blob/24e4796315876292b4562bd2aa39efc6d85771a7/modules/development-team/main.tf#L59-L66&quot;&gt;&lt;em&gt;Accounts that should exist:&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-hcl&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-hcl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;resource &lt;span class=&quot;token type variable&quot;&gt;&quot;aws_organizations_account&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;account&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;for_each&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; local.all_user_names
  &lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;      &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Dev Sandbox &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;each&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;email&lt;/span&gt;     &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;each&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;@heysparkbox.com&quot;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;role_name&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Administrator&quot;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;parent_id&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; aws_organizations_organizational_unit.dev_team_ou.id
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cromwellhaus.com/images/contentful/1BPX0t7CimxM9AetetXujM-image.png&quot; alt=&quot;Terraform Cloud run showing the planning and apply of a team member being removed from AWS infrastructure.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;With this setup, former Sparkboxers no longer have accounts, login profiles, or any access to Sparkbox resources. We can still gain access to their sub account for whatever purpose we might have. And, if we choose, &lt;a href=&quot;https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_accounts_remove.html&quot;&gt;remove and delete the member account&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Making the Leap to Tech Lead</title>
    <link href="https://youtu.be/Lx8BepRpfvg"/>
    <updated>2021-06-23T00:00:00Z</updated>
    <id>https://youtu.be/Lx8BepRpfvg</id>
    <content type="html">&lt;p&gt;Building a healthy, sustainable development organization involves defining technical leadership. In 2019, I shared my thoughts on the tech lead role at the Solidus conference in Utah. Shortly after, I hiked City Creek Canyon and fell in love with the area.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Traits of a Build and Deployment Pipeline</title>
    <link href="https://sparkbox.com/foundry/successful_software_build_and_deployment_pipelines"/>
    <updated>2021-06-23T00:00:00Z</updated>
    <id>https://sparkbox.com/foundry/successful_software_build_and_deployment_pipelines</id>
    <content type="html">&lt;p&gt;I believe that a team&#39;s release cadence has an incredible impact on their success and enjoyment. I wrote a little about the traits that make up a successful build and deploy pipeline for our team at Sparkbox.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Architecting the Progressive Web</title>
    <link href="https://cromwellhaus.com/2017/08/architecting-the-progressive-web/"/>
    <updated>2017-08-26T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2017/08/architecting-the-progressive-web/</id>
    <content type="html">&lt;p&gt;Building a great web is something the &lt;a href=&quot;https://seesparkbox.com/&quot;&gt;Sparkbox&lt;/a&gt; takes very personally. We built what we believe is one of the first RWD e-commerce sites. We constantly battle to improve performance while delivering a great experience, even &lt;a href=&quot;https://twitter.com/cromwellryan/status/748328361441771521&quot;&gt;for those with a terrible connection&lt;/a&gt;. We know we will always be swimming up stream, but today, we believe we have a reasonable architecture for building a progressive web experience that is blazing fast and works for even the most lame devices and connections.&lt;/p&gt;
&lt;p&gt;The crazy thing about this architecture is that it’s not terribly interesting. Essentially, we let the web do it’s thing. Javascript not happing, because you stepped into an elevator or happen to run a super old version of IE (we made that choice)? No worries. We server render all the things, accept form POSTs for all mutating interactions, and serve up PNGs instead of SVGs. &lt;a href=&quot;https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive&quot;&gt;Time to First Interaction&lt;/a&gt; a little slow? No problem – we’ll disable certain elements to save up for the important stuff.&lt;/p&gt;
&lt;p&gt;We’ve been exploring parts of this architecture for a few years now, but this past year we’ve been able to put it all together. Throughout the next year, we’re going to be sharing how we’ve done so in the hopes that we can spur on great experiences across the web.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>We forgot a Pull Request when Splitting a Repo</title>
    <link href="https://cromwellhaus.com/2016/08/we-forgot-a-pull-request-when-splitting-a-repo/"/>
    <updated>2016-08-31T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2016/08/we-forgot-a-pull-request-when-splitting-a-repo/</id>
    <content type="html">&lt;p&gt;We’re working on a little skunk works project at the office and it involved splitting a Github repository in two. After a successful split, I noticed we’d missed a PR that now impacts both repositories.&lt;/p&gt;
&lt;p&gt;My head went to &lt;code&gt;git format-patch &amp;lt;sha&amp;gt;&lt;/code&gt;, but I didn’t recall an option to target a file spec and at first glance it generates a patch for every commit after that SHA.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git show&lt;/code&gt; on the other hand definitely advertises an option to filter&lt;code&gt;git show &amp;lt;sha&amp;gt; -- path/that/moved&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Format that as &lt;code&gt;--pretty=email&lt;/code&gt; and you can direct the output to a patch for&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; show &lt;span class=&quot;token parameter variable&quot;&gt;--pretty&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;email &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;sha&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; -- path/that/moved&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; pr-for-other-repo.patch&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can pull that into our other repo with  &lt;code&gt;git am -3 pr-for-other-repo.patch&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Turns out that &lt;code&gt;-- path/that/moved&lt;/code&gt; semantic does work with &lt;code&gt;git format-patch&lt;/code&gt;. So in the end, we could have just used&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; format-patch &lt;span class=&quot;token parameter variable&quot;&gt;-1&lt;/span&gt; -- path/that/moved
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; am &lt;span class=&quot;token parameter variable&quot;&gt;-3&lt;/span&gt; partial-pr.patch&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>#startYourShift How to Make the Web Better</title>
    <link href="https://cromwellhaus.com/2016/01/startyourshift-how-to-make-the-web-better/"/>
    <updated>2016-01-29T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2016/01/startyourshift-how-to-make-the-web-better/</id>
    <content type="html">&lt;p&gt;My contribution to &lt;a href=&quot;https://twitter.com/startYourShift&quot;&gt;theShift:&lt;/a&gt; a writing project designed to help us produce and consume unique perspectives on topics relevant to the web industry.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://twitter.com/hashtag/startYourShift&quot;&gt;&lt;img src=&quot;https://www.dropbox.com/sh/pkm6qnumqwc73qo/AAAnPxEhE0r-D7yjIK3QQs4Ja/post-image_The-Shift_gray.jpg?raw=1&quot; alt=&quot;a writing project designed to help us produce and consume unique perspectives on topics relevant to the web industry.&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A little over 2 years ago I joined Sparkbox. The focus on community, learning, and teaching were all contributors to &lt;a href=&quot;https://cromwellhaus.com/2013/10/hello-sparkbox/&quot;&gt;that decision&lt;/a&gt;. Today we have 4 apprentices (Cat, Bennett, Brittany, and Nate) sitting among our team, double the &lt;a href=&quot;http://apprentices.seesparkbox.com/#version-3&quot;&gt;2014 cohort&lt;/a&gt; and 1 more &lt;a href=&quot;http://apprentices.seesparkbox.com/#version-4&quot;&gt;than 2015&lt;/a&gt;. &lt;a href=&quot;http://buildright.io/maker-series/&quot;&gt;Build Right: Maker Series&lt;/a&gt; is looking to broaden our horizons by looking beyond HTML, CSS, and even tech to talk about &lt;a href=&quot;http://buildright.io/maker-series/2016/sara-chipps&quot;&gt;wearables&lt;/a&gt;, &lt;a href=&quot;http://buildright.io/maker-series/2016/jason-harrison&quot;&gt;physical health&lt;/a&gt;, and &lt;a href=&quot;http://buildright.io/maker-series/2016/jenn-lukas&quot;&gt;getting things done&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At home, we ask of our 4 awesome kids to learn an instrument, play a sport, write books or comics, and learn the skills of Scouts. They fight us all the time, but we know that breadth and awareness is as much an ingredient to success as depth.&lt;/p&gt;
&lt;p&gt;Personally, I’ve found myself this last year “without the time” to explore things beyond my comfort zone. I’ve not shipped a personal project in over a year. This is my first personal blog post since *2014!*I’ve found a rut.&lt;/p&gt;
&lt;p&gt;The Web is a reflection of those building it – after all The Web is a collection rather than a singular item. As a matter of building a better web, I’d like to once again make the time to &lt;a href=&quot;https://cromwellhaus.com/2012/01/expand-your-normal/&quot;&gt;expand my normal&lt;/a&gt; by looking outside the web.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Installing Erlang 17 for Elixir 0.13 the easy way (Mac)</title>
    <link href="https://cromwellhaus.com/2014/04/installing-erlang-17-for-elixir-0-13-the-easy-way/"/>
    <updated>2014-04-25T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2014/04/installing-erlang-17-for-elixir-0-13-the-easy-way/</id>
    <content type="html">&lt;p&gt;As of Elixir 0.13, you’ll need to have Erlang 17 installed.  If you use brew to install erlang then elixir you’ll find this message awaiting you:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ERROR: OTP release R16B03-1 does not match required regex (17).*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The current Erlang brew formula is still at R16B03-1.  BUT! the development version IS 17.  So here you go:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--devel&lt;/span&gt; erlang&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’m sure this will change soon, but until then this’ll get you going again.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Find Contact Shortcut in Skype for Mac</title>
    <link href="https://cromwellhaus.com/2013/11/find-contact-shortcut-in-skype-for-mac/"/>
    <updated>2013-11-26T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/11/find-contact-shortcut-in-skype-for-mac/</id>
    <content type="html">&lt;p&gt;It’s well understood that Skype does not advocate usability, but I won’t take it anymore.  They have &lt;a href=&quot;https://support.skype.com/en/faq/FA12074/what-keyboard-shortcuts-can-i-use-with-skype-for-mac-os-x?&amp;amp;site_preference=normal&quot;&gt;some shortcuts&lt;/a&gt;, but they’re pretty pitiful.&lt;/p&gt;
&lt;p&gt;I’m a left hand dominant shortcut-er.  Say what you will about me, but I can’t make my fingers use &lt;code&gt;CMD+OPTION+F&lt;/code&gt; for finding a contact to start a new conversation.  So I created the following shortcut.&lt;br /&gt;
&lt;a href=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/11/2013-11-26_11-28-45.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/11/2013-11-26_11-28-45.png&quot; alt=&quot;mac-skype-find-shortcut&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Hello Sparkbox!</title>
    <link href="https://cromwellhaus.com/2013/10/hello-sparkbox/"/>
    <updated>2013-10-30T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/10/hello-sparkbox/</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/10/logo-buildright-dark.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/10/logo-buildright-dark.png&quot; alt=&quot;sb-logo-buildright-dark&quot; /&gt;&lt;/a&gt;Back when &lt;a href=&quot;https://cromwellhaus.com/2011/03/cincy-clean-coders-code-you-can-show-your-friends/&quot; title=&quot;Cincy Clean Coders – Code You Can Show Your Friends&quot;&gt;I started Cincy Clean Coders&lt;/a&gt;, it felt like the Dayton community was nearly nonexistent.  It seemed like I needed to head down to the big city to attract a community of Clean Coders.&lt;/p&gt;
&lt;p&gt;Fast forward 2 years… the Cincy group has stopped meeting, &lt;a href=&quot;http://daytoncleancoders.com/&quot; title=&quot;Dayton Clean Coders&quot;&gt;Dayton Clean Coders&lt;/a&gt; is going strong (with &lt;a href=&quot;https://cromwellhaus.com/images/external/content.screencast.com/users/cromwellryan/folders/Snagit/media/fe56c6ba-1631-427c-acd6-bd5ef4f03c42/10.30.2013-15.19.png&quot;&gt;a bad-ass logo&lt;/a&gt;), an &lt;a href=&quot;http://elixir-lang.org/&quot; title=&quot;Elixir&quot;&gt;Elixir&lt;/a&gt; Group is forming, and &lt;a href=&quot;http://gemcityjs.com/&quot; title=&quot;GemCityJS&quot;&gt;GemCityJS&lt;/a&gt; is growing.  There’s &lt;a href=&quot;http://dayton.buildguild.org/&quot;&gt;Build Guild&lt;/a&gt; and others as well.  The Dayton tech scene is thriving!&lt;/p&gt;
&lt;p&gt;It turns out the people at the center of making much of this happen are also doing great things for the web at &lt;a href=&quot;http://seesparkbox.com/&quot; title=&quot;SparkBox&quot;&gt;Sparkbox&lt;/a&gt; by leading the world in responsive web design.&lt;/p&gt;
&lt;p&gt;Starting next week I’m excited to join the awesome Sparkbox team, focusing hard on making the web and Dayton community an even more amazing place!&lt;/p&gt;
&lt;p&gt;Between the platform shift to open source, Ruby, Rails, etc. and the challenge of working with some of the most passion devs I’ve met, this looks to be an exciting challenge just to keep up!&lt;/p&gt;
&lt;h4&gt;Microsoft ALM &amp;amp; MVP Community&lt;/h4&gt;
&lt;p&gt;This move likely means stepping away from the Microsoft ALM &amp;amp; MVP community.  These have been some of the most passionate and hard working people I’ve met.  They give an immense amount of their time towards helping build great software.&lt;/p&gt;
&lt;p&gt;While TFS has it’s fair share of critics, they’re moving in &lt;a href=&quot;http://blogs.msdn.com/b/bharry/archive/2013/01/30/git-init-vs.aspx&quot; title=&quot;Git Init VS&quot;&gt;a great direction&lt;/a&gt;, &lt;a href=&quot;http://blogs.msdn.com/b/bharry/archive/2012/08/28/tfs-shipping-cadence.aspx&quot; title=&quot;TFS Shipping Cadence&quot;&gt;fast&lt;/a&gt;. And with a leader like Brian Harry making comments like this in private email lists…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m not horribly worried about being copied.  If we can make the whole world provide better services, I’m happy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;…I have no doubt that set of tools will be in a great place in the coming years.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Elixir needs at least 4 JSON parsers</title>
    <link href="https://cromwellhaus.com/2013/08/elixir-needs-at-least-4-json-parsers/"/>
    <updated>2013-08-27T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/08/elixir-needs-at-least-4-json-parsers/</id>
    <content type="html">&lt;p&gt;Elixir has, at the time of this post, 3 JSON parsers hosted on &lt;a href=&quot;http://expm.co/?q=json&quot; title=&quot;JSON libs on expm.io&quot;&gt;expm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Some time back I went looking for one and started exploring &lt;a href=&quot;http://expm.co/json&quot; title=&quot;elixir-json&quot;&gt;elixir-json&lt;/a&gt;, including the &lt;a href=&quot;https://github.com/cblage/elixir-json&quot; title=&quot;elixir-json code&quot;&gt;github repo&lt;/a&gt;.  I loved how the &lt;a href=&quot;https://github.com/cblage/elixir-json/blob/master/lib/json/encode.ex&quot; title=&quot;elixir-json encoder&quot;&gt;encoder&lt;/a&gt; used &lt;a href=&quot;http://elixir-lang.org/getting_started/4.html&quot; title=&quot;elixir procotols&quot;&gt;protocols&lt;/a&gt; to implement the encoding of different types.  It’s beautiful.  Kudos to &lt;a href=&quot;https://twitter.com/carloslage&quot; title=&quot;carloslage on twitter&quot;&gt;@carloslage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then I looked at the &lt;a href=&quot;https://github.com/cblage/elixir-json/blob/master/lib/json/decode.ex&quot; title=&quot;elixir-lang decoder&quot;&gt;decoder&lt;/a&gt;.  It’s full of elixir-isms… tuples, binary pattern matching, etc.  Over the last few nights I decided to implement &lt;a href=&quot;https://gist.github.com/cromwellryan/6349503&quot; title=&quot;json parser in elixir gist&quot;&gt;my own JSON parser&lt;/a&gt; learning from Carlos were I ran aground.&lt;/p&gt;
&lt;p&gt;I don’t like the use of HashDict for objects, but spaces rule out most options like Keyword lists.  I’m also not a huge fan of the nested case for dealing with the &lt;em&gt;what’s next?&lt;/em&gt; of key/value pairs.&lt;/p&gt;
&lt;pre class=&quot;language-elixir&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parse_object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; acc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; binary &lt;span class=&quot;token punctuation&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parse_content rest
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; parse_object_value 

  acc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; acc &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; 

  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; ?&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; binary &lt;span class=&quot;token punctuation&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;HashDict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;acc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; ?&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; binary &lt;span class=&quot;token punctuation&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; parse_object acc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Overall it feels very cohesive.  You can see clearly how the pieces compose after being dispatched from the parse_content.&lt;/p&gt;
&lt;pre class=&quot;language-elixir&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parse_content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; binary &lt;span class=&quot;token punctuation&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; m &lt;span class=&quot;token operator&quot;&gt;in&lt;/span&gt; ?&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;?&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; parse_number &lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; binary &lt;span class=&quot;token punctuation&quot;&gt;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parse_content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; ?&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; binary &lt;span class=&quot;token punctuation&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; parse_string
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parse_content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; ?&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; binary &lt;span class=&quot;token punctuation&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; parse_object
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parse_content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; ?&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; binary &lt;span class=&quot;token punctuation&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; parse_array&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I also do nothing to support invalid JSON content as with elixir-json.  Oh well, it was a learning tool.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Restoring TFS 2012 to Sandbox</title>
    <link href="https://cromwellhaus.com/2013/08/restoring-tfs-2012-to-sandbox/"/>
    <updated>2013-08-16T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/08/restoring-tfs-2012-to-sandbox/</id>
    <content type="html">&lt;p&gt;One of my clients recently asked for some help with getting their TFS server up to snuff.  After getting the software itself in line, I needed to restore a TFS installation in a sandbox environment to plan and test out some significant changes to their Work Item data.  It’s not exactly a smooth experience so lets hope this eases the day of some other poor soul.  As with all things – SSDs make this a bearable duration of time.&lt;/p&gt;
&lt;h4&gt;&lt;/h4&gt;
&lt;h4&gt;Step 1: Install, but don’t configure TFS 2012 Update 3&lt;/h4&gt;
&lt;p&gt;TFS server components have levels of installation doneness.  Since this is a sandbox, I’m not worried about scaling out and will just install a single server.  To do this I:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(15 min) Install Windows Server 2012 Standard on a VM&lt;/li&gt;
&lt;li&gt;(60 min) Windows Updates… oh mighty Zeus the Updates&lt;/li&gt;
&lt;li&gt;(10 min) Wipe sweat from brow and walk around office cursing while fuming over what appears to be update 9,123,758 not budging&lt;/li&gt;
&lt;li&gt;(15 min) Lay down SQL Server 2012 even though production runs on 2008 R2.  Details can be found on &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/vstudio/dd578652.aspx&quot;&gt;Manually Install SQL Server for Team Foundation Server&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;(10 min) Install &lt;a href=&quot;http://www.microsoft.com/en-us/download/details.aspx?id=38185&quot;&gt;TFS 2012 with Update 3&lt;/a&gt;.  Don’t run the configuration wizard!!!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point you should have all the pieces of TFS, but nothing configured.  TFS Administration console looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Step 2: Restore TFS Databases&lt;/h4&gt;
&lt;p&gt;You can use the Administration console to restore your backups if made from a scheduled TFS backup.  You could also use the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/jj620932.aspx&quot;&gt;tfsrestore.exe&lt;/a&gt; tool.  In my case, I had some SQL Service permissions problems and disk space limitations that required me to manually restore each of the databases.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image1.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image_thumb1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Step 3: Change Server IDs&lt;/h4&gt;
&lt;p&gt;Since I’ll be connecting to these in a non-isolated environment and I don’t want tools getting confused I am going to be safe and change server IDs.  TFS uses Guids to identify Servers and Collections.  Visual Studio and other tools using the SDKs will get confused regarding local settings and caches so this is a safeguard against black magic.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TfsConfig.exe ChangeServerID /sqlinstance:localhost /databasename:Tfs_Configuration
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Step 4: Fix Accounts&lt;/h4&gt;
&lt;p&gt;My new server is not attached to any domain, let alone the one used for the production TFS.  With this in mind, I need to update some accounts embedded in TFS.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TFSConfig.exe accounts /resetowner /sqlinstance:WIN-4jsv8rkkbki /databasename:Tfs_Configuration
TFSConfig.exe accounts /add /accounttype:applicationtier /account:tfsservice &amp;quot;/password:shhhhhh&amp;quot; /sqlinstance:localhost /databasename:Tfs_Configuration
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Step 5: Configure TFS Application Tier&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;http://cromwellhaus.com/wp-content/uploads/2013/08/image2.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image_thumb2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From the TFS Administration Console click Application Tier and then Configure Installed Features.  This will give you a number of types of configuration scenarios.  We want Application Tier only which well hook up to our now restored Tfs_Configuration database (and friends).&lt;/p&gt;
&lt;p&gt;Make sure you choose the SQL Server to which you restored your databases (localhost for me).  Once you get to the Application Tier settings page, this should show the service account we added in Step 4: Fix Accounts.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://cromwellhaus.com/wp-content/uploads/2013/08/image3.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image_thumb3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Everything should come out green upon Verification and you can let it rip.  If not, invoke Google &lt;a href=&quot;http://duckduckgo.com/&quot;&gt;duckduckgo.com&lt;/a&gt;-fu.&lt;/p&gt;
&lt;h4&gt;Step 6: Update Remaining Settings&lt;/h4&gt;
&lt;p&gt;There will still be a number of settings that refer to the old topology.&lt;/p&gt;
&lt;p&gt;Change the Urls to your new server:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://cromwellhaus.com/wp-content/uploads/2013/08/image4.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image_thumb4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this sandbox I have no need of Reporting Services or SharePoint.  I just disabled both:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://cromwellhaus.com/wp-content/uploads/2013/08/image5.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image_thumb5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;    &lt;a href=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image6.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/08/image_thumb6.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;&lt;/h4&gt;
&lt;h4&gt;Step 7: Rest&lt;/h4&gt;
&lt;p&gt;It’s certainly not straight forward, but it’s much better than in past versions.&lt;/p&gt;
&lt;p&gt;At this point you should be able to connect to your newly restored TPC and TPs.  If you find that a previously connected Visual Studio pre-selects Team Projects that were also selected in production you likely skipped Step 3.  This could result in weird behavior for you in the future against production.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Using HashDict.update for Keyed Reductions (aka group by) in Elixir</title>
    <link href="https://cromwellhaus.com/2013/07/using-hashdict-update-for-keyed-reductions-aka-group-by-in-elixir/"/>
    <updated>2013-07-22T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/07/using-hashdict-update-for-keyed-reductions-aka-group-by-in-elixir/</id>
    <content type="html">&lt;p&gt;I wanted to start playing with Elixir’s Map and Reduce functions to get a better feel for collection transformations in the language.  For this I grabbed some movie &lt;a href=&quot;https://github.com/tadams/MapReduce/blob/master/src/main/data/movies.txt&quot; title=&quot;tadams&#39; movie data&quot;&gt;data here&lt;/a&gt; and planned on grabbing some perspectives.&lt;/p&gt;
&lt;p&gt;First problem, we need to turn the data into a list of tuples.  The pseudo-transformation we want to apply:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;file -&amp;gt; lines
lines -&amp;gt; parts
parts -&amp;gt; tuples
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The results ended up looking like this&lt;/p&gt;
&lt;p&gt;[gist id=”6051117″ file=”movies.exs”]&lt;/p&gt;
&lt;p&gt;For our data perspectives, lets start small.  The number of movies per year.  This is still a transformation, but it’s not going to be a one-for-one.  We’re instead going to reduce the results after mapping.  Why would we map?  Turns out the only thing you need to know is a full list of the movie years… with dups.  With that we can do an “Add or Update” to a hash for each year.&lt;/p&gt;
&lt;p&gt;[gist id=”6051117″ file=”uniqueness.exs”]&lt;/p&gt;
&lt;p&gt;What we’re doing is providing an entry point for count_unique which takes a collection.  This creates a new HashDict which seeds our {year, count} and then recursively calls down into a variant of HashDict.update.  This variant will insert a new key if not found with the 3rd parameter being the seed value.  If the key is found HashDict.update will call our anonymous function to increment the value already found.&lt;/p&gt;
&lt;p&gt;This pattern seems to work well to get the sum also.  Here we map our collection to pull the year and rating.  I adjusted my original to_movies to use String.to_float so that I have a numeric rating.  From there I use the same HashDict pattern with the rating being our seed and accumulator.&lt;/p&gt;
&lt;p&gt;[gist id=”6051117″ file=”sumations.exs”]&lt;/p&gt;
&lt;p&gt;Next we’ll look at doing something a little more interesting by calculating an average and distributing the effort across nodes using our&lt;a href=&quot;https://cromwellhaus.com/2013/07/triangle-kata-in-elixir-using-erlang-processes-for-parallel-maps/&quot; title=&quot;Triangle Kata in Elixir using Erlang processes for Parallel Maps&quot;&gt;previous parallel map&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Triangle Kata in Elixir using Erlang processes for Parallel Maps</title>
    <link href="https://cromwellhaus.com/2013/07/triangle-kata-in-elixir-using-erlang-processes-for-parallel-maps/"/>
    <updated>2013-07-17T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/07/triangle-kata-in-elixir-using-erlang-processes-for-parallel-maps/</id>
    <content type="html">&lt;p&gt;Last time I described &lt;a href=&quot;https://cromwellhaus.com/2013/07/my-learning-elixir-erlang-setup/&quot; title=&quot;My Learning Elixir (erlang) Setup&quot;&gt;my setup for learning Elixir&lt;/a&gt;, the language built on top of Erlang with a Ruby bent.  Today I wanted to get a hang of processes and mailboxes which are so important to both languages.  To do this I chose the Triangle Kata as my background story.  &lt;a href=&quot;https://gist.github.com/cromwellryan/6024862&quot;&gt;Take a look&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; You might wonder what that &lt;code&gt;slow&lt;/code&gt; function is all about. I added that in there to clarify the parallelism. You would expect the slowest classifications to appears at the end of the resultant list.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>My Learning Elixir (erlang) Setup</title>
    <link href="https://cromwellhaus.com/2013/07/my-learning-elixir-erlang-setup/"/>
    <updated>2013-07-04T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/07/my-learning-elixir-erlang-setup/</id>
    <content type="html">&lt;p&gt;The last &lt;a href=&quot;http://daytoncleancoders.com/&quot; title=&quot;Dayton Clean Coders&quot;&gt;Dayton Clean Coders&lt;/a&gt; meeting spiked my squirrel sense as &lt;a href=&quot;http://twitter.com/chris_mccord&quot; title=&quot;Chris McCord on Twitter&quot;&gt;Chris McCord&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/mattsears&quot; title=&quot;Matt Sears on Twitter&quot;&gt;Matt Sears&lt;/a&gt; of our awesome host &lt;a href=&quot;http://littlelines.com/&quot; title=&quot;Little Lines&quot;&gt;Little Lines&lt;/a&gt; talked about their excitement for &lt;a href=&quot;http://elixir-lang.org/&quot; title=&quot;Elixir Language on Erlang&quot;&gt;Elixir&lt;/a&gt;. Of course, I’ve hung my several dozen half baked projects up for the moment as I scratch that itch.&lt;/p&gt;
&lt;p&gt;Elixir is a Ruby inspired language that compiles down to Erlang bitcode. You can fall back to any Erlang library and many of the syntaxes, but the language is crazy easy to pick up if you’ve tried any of the other Ruby inspired languages like Coffeescript.&lt;/p&gt;
&lt;p&gt;Here’s my setup for walking through the &lt;a href=&quot;http://elixir-lang.org/getting_started/1.html&quot; title=&quot;Elixir Getting Started&quot;&gt;Elixir Getting Started&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;vim with my &lt;a href=&quot;http://github.com/cromwellryan/vim-config&quot; title=&quot;My Vim configuration&quot;&gt;vim-config&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iex, interactive elixir will load compiled elixir modules found in the same directory. This means I can put bigger functions, modules, protocols, etc. into *.ex files and then explore and play with them using iex.  You need to run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;r(ModuleName)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to reload after compiles.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Guard running this &lt;a href=&quot;https://gist.github.com/cromwellryan/5924636&quot; title=&quot;Guardfile for elixirc&quot;&gt;Guardfile&lt;/a&gt; for automatically compiling the *.ex files.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/07/2013-07-04_08-30-09.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/07/2013-07-04_08-30-09.png&quot; alt=&quot;vim + iex + guard = flatting the curve&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;vim + iex + guard = flatting the curve&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Moving Blob Storage Between Azure Subscriptions</title>
    <link href="https://cromwellhaus.com/2013/04/moving-blob-storage-between-azure-subscriptions/"/>
    <updated>2013-04-10T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/04/moving-blob-storage-between-azure-subscriptions/</id>
    <content type="html">&lt;p&gt;We recently had some delays getting some Azure accounts coordinated for a client and chose to use a team subscription instead.  After some work, the delays were resolved and we had the client managed subscription in place.&lt;/p&gt;
&lt;p&gt;The work done using the team subscription included uploading many gigabytes of sysprepped Virtual Machine images that would stand as the template for scaling up a set of services.  Once the client subscription was in place, we knew we would need to move the images over.&lt;/p&gt;
&lt;p&gt;We were a little concerned that moving between subscriptions would take a long time.  Moving between containers isn’t hard, but could you rely on the same mechanism to move between subscriptions?  Turns out the answer is yes if you make the blob or container public during the move.&lt;/p&gt;
&lt;p&gt;After you pull in your Azure Subscription into PowerShell (we used Import-AzurePublishSettingsFile) you can do this pretty easily.&lt;/p&gt;
&lt;p&gt;Here’s an example of the Posh to do this with a public to private blob using the Azure &lt;a href=&quot;https://www.windowsazure.com/en-us/downloads/?fb=en-us&quot;&gt;PowerShell Cmdlets&lt;/a&gt;:&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Release Cadence: You’re Not Agile If You’re Not Shipping</title>
    <link href="https://cromwellhaus.com/2013/03/release-cadence-youre-not-agile-if-youre-not-shipping/"/>
    <updated>2013-03-08T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/03/release-cadence-youre-not-agile-if-youre-not-shipping/</id>
    <content type="html">&lt;p&gt;I’ve spent the last 3 years exploring the in’s and out’s of different Agile frameworks and methodologies.  I’ve worked with large commercial firms, government contractors, and small ISVs to adopt one set of Agile practices or another.&lt;/p&gt;
&lt;p&gt;In the beginning things are generally amazing.  There’s a new level of transparency, excitement and shared motivation.  At some point, though, the question always comes up: Are we ready to ship?&lt;/p&gt;
&lt;p&gt;This is the moment where organizations either head down the Scrum-erfall path or learn what Agile was meant to be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…satisfy the customer&lt;br /&gt;
through early and continuous delivery&lt;br /&gt;
of valuable software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Path to&lt;/strong&gt; &lt;a href=&quot;http://scrum.org/&quot;&gt;&lt;strong&gt;Scrum&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;-erfall&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, too many organizations have taken hold of the rules and ceremonies of Kanban, Scrum, XP, and the rest, but ignore these &lt;a href=&quot;http://agilemanifesto.org/principles.html&quot;&gt;two principles&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Working software is the primary measure of progress.&lt;/li&gt;
&lt;li&gt;Deliver working software frequently, from a couple of weeks to a couple of months, with a&lt;br /&gt;
preference to the shorter timescale.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Does Shipping Heal All Wounds?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;On March 4th, I opened what I hope will replace the State of Agile report: &lt;a href=&quot;http://releasecadencereport.com/&quot;&gt;Release Cadence Report&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/03/logo-vertical.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/03/logo-vertical_thumb.png&quot; alt=&quot;logo-vertical&quot; title=&quot;logo-vertical&quot; /&gt;&lt;/a&gt;This survey and publication was created to refocus our industries attention back on shipping software frequently to the delight and benefit of our customers, team members, and companies.  It is an attempt to relieve our software developers of ineffective anecdotal stories of Facebook and Flickr shipping dozens of times per day.  Instead I want you to have the evidence to take to leaders in your organization so that you can have a serious conversation about the implications of release cadence.&lt;/p&gt;
&lt;p&gt;Please take 10 minutes and complete this survey and you will receive an early copy of the report.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://releasecadencereport.com/survey/&quot;&gt;Take the Survey&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also get yourself or your organization listed as being part of this movement by referring your coworkers, peers, friend.  &lt;a href=&quot;http://releasecadencereport.com/partnerships/&quot;&gt;Sign up here&lt;/a&gt; and be a part of bringing shipping back to Agile.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Creating an Offline Web Platform Installer for Service Bus 1.0</title>
    <link href="https://cromwellhaus.com/2013/01/creating-an-offline-web-platform-installer-for-service-bus-1-0/"/>
    <updated>2013-01-02T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2013/01/creating-an-offline-web-platform-installer-for-service-bus-1-0/</id>
    <content type="html">&lt;p&gt;One of my clients is evaluating a number of Service Bus tools.  One of those includes the Azure Service Bus which is now available for on-premise deployment.&lt;/p&gt;
&lt;p&gt;Service Bus 1.0 is available only through Web Platform Installer at this time and it’s not readily apparent how you might use WPI for a network isolated environment.  Hopefully this will help:&lt;/p&gt;
&lt;h4&gt;WebpiCmd.exe to find the Service Bus AppId&lt;/h4&gt;
&lt;p&gt;Web Platform Installer comes with a command line tool called &lt;a href=&quot;http://www.iis.net/learn/install/web-platform-installer/web-platform-installer-v4-command-line-webpicmdexe-preview-release_1072&quot;&gt;WebpiCmd.exe&lt;/a&gt;.  With it you can list and install packages.  You can also create an offline WPI feed which is what we’ll do.&lt;/p&gt;
&lt;p&gt;To list available products at the default Microsoft feed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;webpicmd /List /ListOption:Available&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Somewhere in that mess is Service Bus 1.0 and it’s AppId which we’ll need to create a private, offline cache of the product and it’s dependencies.  I’m using &lt;a href=&quot;http://sourceforge.net/projects/console/&quot;&gt;Console2 with a PowerShell tab&lt;/a&gt; so I can do this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;webpicmd /List /ListOption:Available | ? { $_.Contains(“Service Bus”) }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://cromwellhaus.com/wp-content/uploads/2013/01/image.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/01/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since WebpiCmd is just writing dumb lines of text, I can’t interrogate the Product attributes, so I’m using the &lt;a href=&quot;http://technet.microsoft.com/en-us/library/ee177028.aspx&quot;&gt;where-object&lt;/a&gt;, aliased to ?, to see which line contains the string “Service Bus”.  WebPI really should be a better PS citizen.&lt;/p&gt;
&lt;h4&gt;Creating an Offline Feed&lt;/h4&gt;
&lt;p&gt;WPI works against feeds, so we’re going to create our own feed just for this product.  You might maintain a growing list of products in this feed, but that’s beyond this post.  To create your offline feed we’ll use the (drum roll) /Offline option:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WebpiCmd.exe /offline /Products:ServiceBusBeta /Path:C:&#92;wpi-offline&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;NOTE: The Service Bus 1.0 entry in WPI seems like it has a problem with the App Fabric dependency.  I’m told that’s fixed now.&lt;/p&gt;
&lt;h4&gt;Installing from the Offline Feed&lt;/h4&gt;
&lt;p&gt;Once everything is resolved and downloaded, you can use it with WPI GUI or WebpiCmd.exe.&lt;/p&gt;
&lt;p&gt;You can not automate-all-the-things with:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;webpicmd /install /Products:ServiceBus /xml:c:&#92;wpi-offline&#92;feeds&#92;latest&#92;webproductlist.xml&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or do the GUI thing by checking out WPI options:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://cromwellhaus.com/wp-content/uploads/2013/01/image1.png&quot;&gt;&lt;img src=&quot;https://cromwellhaus.com/images/wp-content/uploads/2013/01/image_thumb1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Adaptive Problems Require Responding to Change Over Following a Plan</title>
    <link href="https://cromwellhaus.com/2012/10/adaptive-problems-require-responding-to-change-over-following-a-plan/"/>
    <updated>2012-10-22T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2012/10/adaptive-problems-require-responding-to-change-over-following-a-plan/</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://www.scrum.org/tabid/96/aft/191/&quot;&gt;Feedback was recently posed&lt;/a&gt; on the &lt;a href=&quot;http://scrum.org/&quot;&gt;Scrum.org&lt;/a&gt; community forums regarding the Webster-ish definition provided for Scrum by Ken and Jeff.  If you don’t recall from the &lt;a href=&quot;https://www.scrum.org/Scrum-Guides&quot;&gt;Scrum Guide&lt;/a&gt;, the Scrum Overview definition reads:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum (n): A framework within which people can address complex adaptive problems, while productively and creatively delivering products of the highest possible value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mario Čop, in his &lt;a href=&quot;https://www.scrum.org/tabid/96/aft/191/&quot;&gt;feedback&lt;/a&gt;, suggests problems cannot be &lt;em&gt;adaptive.&lt;/em&gt;  He provides some definitions of his own to remove the subjective influences around the words “adapt”, “adaptive” and “problem.”  In the end, Mario says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’d say that the process of solving problems can be adaptive. When solving problems you can have adaptive approach and adaptive execution of it, but it makes no sense saying that problems itself are adaptive.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Whether successfully conveyed or not, the intent is that complex problems are not always clearly understood.  As we approach and attempt to solve a complex problem, our understanding of that problem becomes clearer.  What this means is that as we examine a problem, our understanding of it adapts.  In this way we must reevaluate both the problem and the solution.  Continuous planning allows for this dynamic where a plan alone constrains learning.&lt;/p&gt;
&lt;p&gt;Scrum’s Sprint, &lt;a href=&quot;https://cromwellhaus.com/2012/01/time-box-a-holistic-view-on-sprints-and-iterations/&quot;&gt;as I’ve said before&lt;/a&gt;, provides a balance between space for creative problem solving and focused decision making.  The outcome of a sprint allows us to reevaluate our understanding of the problem space and whether we are taking the product and organization in the appropriate direction.  Here we see how we can utilize the Scrum framework to embody the &lt;a href=&quot;http://agilemanifesto.org/&quot;&gt;Agile value&lt;/a&gt; of &lt;em&gt;Responding to change over following a plan.&lt;/em&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Passive Aggressive Commit Messages</title>
    <link href="https://cromwellhaus.com/2012/08/passive-aggressive-commit-messages/"/>
    <updated>2012-09-27T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2012/08/passive-aggressive-commit-messages/</id>
    <content type="html">&lt;p&gt;If anyone tries to tell you Twitter is a waste of time, they have the wrong circle of followers.  Today I posted &lt;a href=&quot;https://gist.github.com/3426969&quot;&gt;this gist&lt;/a&gt; somewhat facetiously asking if the following was an acceptable commit message.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Refactoring done earlier didn’t execute acceptance tests. This makes me wonder why we even have acceptance tests. The acceptance tests (and the bug they surfaced) are fixed. Ugh. Professionalism people. Please.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://cromwellhaus.com/wp-content/uploads/2012/08/image.png&quot;&gt;&lt;img src=&quot;http://cromwellhaus.com/wp-content/uploads/2012/08/image_thumb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; /&gt;&lt;/a&gt;I say &lt;em&gt;somewhat facetiously&lt;/em&gt;, because I actually copied it out of my almost submitted commit command. I was really close to sending it and that would have probably been the end of it.  It’s unlikely anyone would have noticed it, especially the person I was directing this passive aggressive comment towards.&lt;/p&gt;
&lt;h6&gt;Follow My Own Advice&lt;/h6&gt;
&lt;p&gt;I’ve blogged recently about recognizing signals (&lt;a href=&quot;https://cromwellhaus.com/2012/07/failing-builds-arent-your-problem/&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://cromwellhaus.com/2012/08/crickets-messages-are-only-useful-if-received/&quot;&gt;here&lt;/a&gt;).  Obviously, I’m not following my own advice.  I need to go and find out why this person doesn’t care about the acceptance tests and either convince them they are important or find a better way.&lt;/p&gt;
&lt;h6&gt;&lt;/h6&gt;
&lt;h6&gt;Uncomfortable Part&lt;/h6&gt;
&lt;p&gt;Rather than be passive aggressive in silence, I need to have the discussion.  It’s not going to be comfortable, but I have something we can both agree on: we both want this to be successful.  If we can keep the conversation focused on the success of this project, we can find an understanding.  If I use the same tone in our conversation that I’m using in this commit message, well, it’s not going to go well.&lt;/p&gt;
&lt;p&gt;Fortunately, I wear big boy pants (when I go to the office) and I’m willing to get over a little uneasiness for the sake of my creation.  Do it a few times and it gets much easier.&lt;/p&gt;
&lt;h6&gt;Simple Solution&lt;/h6&gt;
&lt;p&gt;It turns out this was able to exist in our codebase for a few days, because we aren’t running our acceptance tests as part of the build. I plan to remedy that tomorrow.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Scrum Fundamentals Recording Available</title>
    <link href="https://cromwellhaus.com/2012/09/scrum-fundamentals-recording-available/"/>
    <updated>2012-09-27T00:00:00Z</updated>
    <id>https://cromwellhaus.com/2012/09/scrum-fundamentals-recording-available/</id>
    <content type="html">&lt;p&gt;Leading up to an open enrollment &lt;a href=&quot;http://courses.scrum.org/classes/show/804&quot;&gt;Professional Scrum Foundations&lt;/a&gt; on October 10th, I gave a 1 hour lunch webinar on the fundamentals of Agile and &lt;a href=&quot;http://scrum.org/&quot;&gt;Scrum&lt;/a&gt;.  I’ve just &lt;a href=&quot;http://www.youtube.com/watch?v=icudcQN79lg&amp;amp;feature=youtu.be&quot;&gt;published this out on Youtube&lt;/a&gt; for anyone to watch.  Let me know what you think.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There is a lot of misinformation out there that comes with a strong movement like Agile. It’s been coopted by some, but the vast majority see these opportunities as a way to make sure the 8 hours they spend away from their families is &lt;a href=&quot;https://cromwellhaus.com/2011/12/full-speed-ahead/&quot;&gt;spent wisely&lt;/a&gt;. &lt;a href=&quot;https://twitter.com/cromwellryan/status/217687590692864000&quot;&gt;That’s where I fit in.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With that in mind, I believe very much that Scrum, like many things, can be used for both good and bad.  When used well, it provides a safe zone for sustainable, creative teamwork.  When used poorly, it sucks as bad if not worse than waterfall/ad-hoc.&lt;/p&gt;
&lt;p&gt;I don’t teach Scrum such that teams go back and simply use it to manage work.  Many don’t get beyond that, but in my courses, webinars, and conversations we talk about the human factors, theory, and sustainable practices that make Scrum work.  This is the legacy I want Deming, Scrum, Agility, and others to be remembered by.  Not &lt;a href=&quot;http://jimhighsmith.com/2011/11/02/velocity-is-killing-agility/&quot;&gt;velocity&lt;/a&gt; and &lt;a href=&quot;http://www.scrum.org/About/All-Articles/articleType/ArticleView/articleId/95/Commitment-vs-Forecast-A-subtle-but-important-change-to-Scrum&quot;&gt;commitment&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
</feed>
