<?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: Ben Curtis</title>
    <description>The latest articles on DEV Community by Ben Curtis (@stympy).</description>
    <link>https://dev.to/stympy</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%2F202112%2F2ece86c0-0eb9-4d79-9dad-9668ac146d9e.jpg</url>
      <title>DEV Community: Ben Curtis</title>
      <link>https://dev.to/stympy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stympy"/>
    <language>en</language>
    <item>
      <title>Bootstrap a consul cluster in AWS</title>
      <dc:creator>Ben Curtis</dc:creator>
      <pubDate>Mon, 01 Nov 2021 17:39:28 +0000</pubDate>
      <link>https://dev.to/stympy/bootstrap-a-consul-cluster-in-aws-3gk8</link>
      <guid>https://dev.to/stympy/bootstrap-a-consul-cluster-in-aws-3gk8</guid>
      <description>&lt;p&gt;I recently needed to stand up a test consul cluster, and I thought it might be useful to share my notes. Here's what you can do to quickly get a consul cluster going...&lt;/p&gt;

&lt;p&gt;First, create an IAM role named &lt;code&gt;consul&lt;/code&gt; and attach the AmazonEC2ReadOnlyAccess policy to the role.&lt;/p&gt;

&lt;p&gt;Next, boot three Ubuntu instances, assigning the just-created role to them as the IAM role, and the following user data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install consul

echo "datacenter = \"$(ec2metadata --public-hostname | cut -d. -f2)\"" &amp;gt;&amp;gt; /etc/consul.d/consul.hcl 
echo 'server = true' &amp;gt;&amp;gt; /etc/consul.d/consul.hcl
echo 'bootstrap_expect = 3' &amp;gt;&amp;gt; /etc/consul.d/consul.hcl
echo 'retry_join = ["provider=aws tag_key=Role tag_value=consul"]' &amp;gt;&amp;gt; /etc/consul.d/consul.hcl

systemctl start consul
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the latest consul on each of the instances, configure consul to operate in server mode, and bootstrap the cluster.&lt;/p&gt;

&lt;p&gt;You also want to add the &lt;code&gt;Role&lt;/code&gt; tag with the value of &lt;code&gt;consul&lt;/code&gt; to the instances. This is how the instances will find each other to form a cluster.&lt;/p&gt;

&lt;p&gt;After you boot the instances, edit the security group to allow inbound traffic from the security group (so the instances can connect to each other).&lt;/p&gt;

&lt;p&gt;Once those steps are done, you can confirm the cluster is working by connecting to any of the instances and running &lt;code&gt;consul members&lt;/code&gt;. You should see the three instances listed as servers.&lt;/p&gt;

&lt;p&gt;Now you can use your consul cluster by pointing consul clients at the private IP of any of the instances.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>consul</category>
    </item>
    <item>
      <title>Simple (and naïve) way to mark private URLs as invalid</title>
      <dc:creator>Ben Curtis</dc:creator>
      <pubDate>Sat, 16 May 2020 18:19:38 +0000</pubDate>
      <link>https://dev.to/stympy/simple-and-naive-way-to-mark-private-urls-as-invalid-ki7</link>
      <guid>https://dev.to/stympy/simple-and-naive-way-to-mark-private-urls-as-invalid-ki7</guid>
      <description>&lt;p&gt;I'm working on a new side project, and I needed some code to check that a user-supplied URL won't be accepted if it's a known private address... here's a &lt;a href="https://gist.github.com/stympy/f831f3ad68db28ec60efc9737e09050a"&gt;gist&lt;/a&gt; with some quick code I wrote.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>Managing PostgreSQL partitioned tables with Ruby</title>
      <dc:creator>Ben Curtis</dc:creator>
      <pubDate>Thu, 31 Oct 2019 00:09:31 +0000</pubDate>
      <link>https://dev.to/honeybadger/managing-postgresql-partitioned-tables-with-ruby-1ao7</link>
      <guid>https://dev.to/honeybadger/managing-postgresql-partitioned-tables-with-ruby-1ao7</guid>
      <description>&lt;p&gt;Introducing the &lt;a href="https://github.com/honeybadger-io/pg_partition_manager"&gt;pg_partition_manager gem&lt;/a&gt;: It helps you easily maintain PostgreSQL partitioned tables that need to be created and dropped over time as you add and expire time-based data in your application.&lt;/p&gt;

&lt;p&gt;We use partitioned tables at &lt;a href="https://www.honeybadger.io/"&gt;Honeybadger&lt;/a&gt; in our primary PostgreSQL database to efficiently expire old data, as deleting a bunch of data from a huge table can cause database performance to suffer. Prior to version 10, PostgreSQL didn't have native support for partitioned tables, so we used the &lt;a href="https://github.com/pgpartman/pg_partman"&gt;pg_partman&lt;/a&gt; extension to implement partitioning. It works by using PostgreSQL's table inheritance to create child tables of the table that is to be partitioned and triggers to insert data into the child tables rather than the parent table. That extension has worked well for us, but it has a downside -- it isn't an option when you are using Amazon RDS, as it isn't supported. Now that that PostgreSQL has support for native partitions, I figured now was the time to see about dropping that extension so we'd have the option of using RDS.&lt;/p&gt;

&lt;p&gt;Our partitioning use-case is fairly simple: we partition tables based on time, creating a new partition for every day, week, or month, depending on how many rows we want to store across all partitions and on how long we want to retain the data. All of our partitioned tables have a &lt;code&gt;created_at&lt;/code&gt; column that will be used to determine which partition stores each row. For example, we might have a table defined like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;project_id&lt;/span&gt; &lt;span class="nb"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="n"&gt;jsonb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;partition&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if we wanted to have weekly partitions, they would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;events_p2019_10_28&lt;/span&gt; &lt;span class="k"&gt;partition&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-10-28'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-11-04'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;events_p2019_11_04&lt;/span&gt; &lt;span class="k"&gt;partition&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-11-04'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-11-11'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a time-based partitioning scheme, deleting old data is as simple as dropping one of the partitions. The regular maintenance we need to do, then, is create new partitions for date ranges as we approach them and delete old partitions containing data we no longer want. To make that maintenance a little easier, I have created the &lt;a href="https://github.com/honeybadger-io/pg_partition_manager"&gt;pg_partition_manager gem&lt;/a&gt;. Naturally, it's inspired by my experience with the pg_partman extension, which has served us so well.&lt;/p&gt;

&lt;p&gt;Let's take a look at how you'd use this gem, given the events table and partitioning scheme described above. You would create a script or rake task that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"pg_partition_manager"&lt;/span&gt;

&lt;span class="no"&gt;PgPartitionManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt;&lt;span class="ss"&gt;parent_table: &lt;/span&gt;&lt;span class="s2"&gt;"public.events"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;period: &lt;/span&gt;&lt;span class="s2"&gt;"week"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;premake: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;retain: &lt;/span&gt;&lt;span class="mi"&gt;3&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;parent_table&lt;/code&gt; is defined as &lt;code&gt;schema.table_name&lt;/code&gt; (&lt;code&gt;public&lt;/code&gt;, the default schema, is often the only one Rails developers end up using). The &lt;code&gt;period&lt;/code&gt; can be day, week, or month. You can choose how many tables you want created in advance (after the current period) with &lt;code&gt;premake&lt;/code&gt;, and how many tables you want to keep (prior to the current period) with &lt;code&gt;retain&lt;/code&gt;. The gem defaults to pre-creating 4 tables if you don't specify &lt;code&gt;premake&lt;/code&gt;, and it defaults to retaining data for 7 days, 4 weeks, and 6 months if you don't specify &lt;code&gt;retain&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Invoke that script/task with a daily cron job, and you're all set -- it will create and drop the tables as needed.&lt;/p&gt;

&lt;p&gt;All ActiveRecord queries act just as they would with a non-partitioned table, so there's nothing you need to change in your code. That is, &lt;code&gt;Event.create&lt;/code&gt;, &lt;code&gt;Event.where&lt;/code&gt;, etc., will work just as they always have, with PostgreSQL putting the data in the right partition for you when you insert it. There is one change you may notice if you have lots of data, though... when you include &lt;code&gt;created_at&lt;/code&gt; in your queries, PostgreSQL won't have to scan all the partitions -- just the ones the cover the range you specify in your where clause.&lt;/p&gt;

&lt;p&gt;To recap, if you have a lot of time-based data that you want to delete as it expires, use PostgreSQL partitioned tables and the &lt;a href="https://github.com/honeybadger-io/pg_partition_manager"&gt;pg_partition_manager gem&lt;/a&gt; to make your app happy. :)&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>postgres</category>
      <category>devops</category>
    </item>
    <item>
      <title>Configure Your App with SSM Parameter Store</title>
      <dc:creator>Ben Curtis</dc:creator>
      <pubDate>Wed, 09 Oct 2019 16:13:33 +0000</pubDate>
      <link>https://dev.to/honeybadger/configure-your-app-with-ssm-parameter-store-1hah</link>
      <guid>https://dev.to/honeybadger/configure-your-app-with-ssm-parameter-store-1hah</guid>
      <description>&lt;p&gt;Configuring your Rails app via environment variables works well, but sometimes you want to be able to update your configuration on the fly. Here's a way to update your app's environment using &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html"&gt;SSM Parameter Store&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Why would you want to do this? Well, say you deploy your Rails app to an EC2 instance that's part of an autoscaling group. To get the fastest boot times, you should create a custom AMI with your code already on it (a.k.a. a golden image) that the autoscaling group can use when it's time to boot a new instance. Unfortunately, if you store your configuration on the image (and use something like &lt;a href="https://github.com/bkeepers/dotenv"&gt;dotenv&lt;/a&gt; to load it), you'll need to create a new AMI every time you have a configuration change. You can work around this by using SSM Parameter Store parameters, and let your app fetch its configuration at boot time.&lt;/p&gt;

&lt;p&gt;Putting data into Parameter Store is easy enough -- you can use the CLI or the AWS console to edit the variables. But how do you get the data back out for your app to use? One way to do it is to fetch these parameters into your ENV via an initializer, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Aws&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SSM&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_parameters_by_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s2"&gt;"/honeybadger/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;recursive: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with_decryption: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;split&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="nf"&gt;last&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming you have parameters named like &lt;code&gt;honeybadger/production/MY_API_KEY&lt;/code&gt;, this snippet will result in &lt;code&gt;ENV["MY_API_KEY"]&lt;/code&gt; having whatever value you supplied for that parameter.&lt;/p&gt;

&lt;p&gt;But what if loading the environment variable values in an initializer is too late in the Rails boot up process? What if you need settings like DATABASE_URL to be set in SSM &lt;em&gt;and&lt;/em&gt; you need to use those settings before your app loads? For that, you can save the variables to a &lt;code&gt;.env&lt;/code&gt; file and let dotenv &lt;a href="https://github.com/bkeepers/dotenv#note-on-load-order"&gt;handle that&lt;/a&gt;. But first, let's set up the database and store our DATABASE_URL value.&lt;/p&gt;

&lt;p&gt;Here's a &lt;a href="https://terraform.io"&gt;terraform&lt;/a&gt; snippet that creates an RDS instance and stores the connection in SSM Parameter Store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_db_instance"&lt;/span&gt; &lt;span class="s2"&gt;"db"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;allocated_storage&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
  &lt;span class="nx"&gt;storage_type&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"gp2"&lt;/span&gt;
  &lt;span class="nx"&gt;engine&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"postgres"&lt;/span&gt;
  &lt;span class="nx"&gt;engine_version&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"11.4"&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.database_password}"&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"honeybadger"&lt;/span&gt;
  &lt;span class="nx"&gt;username&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"honeybadger"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_ssm_parameter"&lt;/span&gt; &lt;span class="s2"&gt;"database_url"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/honeybadger/${var.environment}/DATABASE_URL"&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"SecureString"&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"postgres://${aws_db_instance.db.username}:${var.database_password}@${aws_db_instance.db.endpoint}/${aws_db_instance.db.name}"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the following shell command, you can grab all the parameters (just like we did with the Ruby snippet above) and get them ready for use as environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ssm get-parameters-by-path &lt;span class="nt"&gt;--path&lt;/span&gt; /honeybadger/production/ &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--recursive&lt;/span&gt; &lt;span class="nt"&gt;--with-decryption&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Parameters[].[Name,Value]"&lt;/span&gt; |
  &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'s#/honeybadger/production/([^[:space:]]*)[[:space:]]*#export \1=#'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /home/honeybadger/shared/.env.production.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have a &lt;code&gt;.env.production.local&lt;/code&gt; file that dotenv can load -- assuming that it's symlinked into your &lt;code&gt;current&lt;/code&gt; path at deploy time, if you are using capistrano. As a bonus, you can also source that env file to have variables like $DATABASE_URL defined for you in any shell scripts you want to run.&lt;/p&gt;

&lt;p&gt;We put that shell command in our deployment script (which is triggered by our CI/CD pipeline), so any new code that goes to production will pick up any changes to made to our parameters in SSM. Now we get to have our golden image &lt;em&gt;and&lt;/em&gt; we don't have to build a new one for every configuration change. 😎&lt;/p&gt;

</description>
      <category>devops</category>
      <category>rails</category>
      <category>aws</category>
    </item>
  </channel>
</rss>
