<?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>Forem: Michael Fecher</title>
    <description>The latest articles on Forem by Michael Fecher (@michaelfecher).</description>
    <link>https://forem.com/michaelfecher</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%2F312677%2F9179ef87-7fff-4a9a-9bec-1007235c8e73.jpg</url>
      <title>Forem: Michael Fecher</title>
      <link>https://forem.com/michaelfecher</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/michaelfecher"/>
    <language>en</language>
    <item>
      <title>I tell you a secret: Provide Database credentials to an ECS Fargate task in AWS CDK</title>
      <dc:creator>Michael Fecher</dc:creator>
      <pubDate>Fri, 24 Jul 2020 21:28:55 +0000</pubDate>
      <link>https://forem.com/michaelfecher/i-tell-you-a-secret-provide-database-credentials-to-an-ecs-fargate-task-in-aws-cdk-5f4</link>
      <guid>https://forem.com/michaelfecher/i-tell-you-a-secret-provide-database-credentials-to-an-ecs-fargate-task-in-aws-cdk-5f4</guid>
      <description>&lt;p&gt;This is my first post after thinking too much about what to write for a decade or so. ;)&lt;br&gt;
So let's overcome this blockade by talking about this delicate topic.&lt;/p&gt;
&lt;h1&gt;
  
  
  Motivation: Credentials aren't safe in environment variables
&lt;/h1&gt;

&lt;p&gt;Devs without a clue would come up with environment variables to store and pass those credentials.&lt;br&gt;
The nature of environment variables is, that they mostly are used to store readable text in them and make them accessible easily.&lt;br&gt;
Let's imagine you would pass your production credentials to your database around in clear-text.&lt;br&gt;
If an attacker gains access to the instance itself or your container orchestrator, you are screwed up.&lt;br&gt;
In a nutshell: Don't do it.&lt;/p&gt;

&lt;p&gt;Consequently, we need to have an encrypted mechanism to store and to hand-over these credentials to our Fargate tasks as well as to our AWS persistence layer.&lt;/p&gt;
&lt;h1&gt;
  
  
  Prerequisites: AWS Services for storing secret information
&lt;/h1&gt;

&lt;p&gt;AWS itself offers already two products to take care of the management of sensitive data (called secrets):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/secrets-manager"&gt;Secret-Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html"&gt;Systems Manager Parameter Store&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't want to dive deeper into a comparison of both.&lt;br&gt;
I'd like to give the &lt;strong&gt;Secret-Manager&lt;/strong&gt; a shot in this article, but you can exchange it without much hassle.&lt;br&gt;
The Secret Manager offers a key-rotation mechanism, which automatically can change the key after a certain period.&lt;/p&gt;

&lt;p&gt;Both enable us to only retrieve and decrypt the secret information by eligible IAM roles.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create two secrets in the AWS Secret Manager
&lt;/h2&gt;

&lt;p&gt;To create a secret (key/value pair) for your specific database access, you could do it via the AWS Console or by the AWS CLI.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Important&lt;/em&gt;: Don't create a JSON value for the secret key. &lt;br&gt;
The retrieval of it &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data-secrets.html"&gt;isn't working out with Fargate&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Due to the special case related to Fargate, we need to create two secrets. One is for the username and the other for the password itself.&lt;br&gt;
Go ahead and create those:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws secretsmanager create-secret \
--name prod/service/db/user \
--secret-string yourAwesomeUser
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws secretsmanager create-secret \
--name prod/service/db/password \
--secret-string yourAwesomePassword
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You'll get an ARN back per secret.&lt;br&gt;
Remember both ARNs.&lt;br&gt;
Otherwise, if you forget about it, you can look them up later again.&lt;/p&gt;
&lt;h1&gt;
  
  
  Wire the secrets in our Infrastructure as Code / AWS CDK
&lt;/h1&gt;

&lt;p&gt;We successfully created both secrets in the Secret Manager.&lt;/p&gt;

&lt;p&gt;As introduced in the header, we now want to integrate both secrets in the AWS CDK code in order to ship them to our ECS Fargate task.&lt;/p&gt;

&lt;p&gt;A few words on &lt;a href="https://aws.amazon.com/cdk/"&gt;AWS CDK&lt;/a&gt;:&lt;br&gt;
AWS CDK enables you to write your AWS infrastructure in your favorite programming language. No YAML/JSON headaches, but instead testable, clean, and reusable code.&lt;br&gt;
Yes, I was also impressed when I first used it in 2018 for PoCs after it was in the developer preview.&lt;br&gt;
Its popularity and feature set has grown tremendously over the past two years.&lt;br&gt;
It's even possible since a few days &lt;a href="https://aws.amazon.com/blogs/developer/introducing-the-cloud-development-kit-for-terraform-preview/"&gt;to integrate it with Terraform&lt;/a&gt;.. :O&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites: AWS CDK infrastructure
&lt;/h2&gt;

&lt;p&gt;Alright, I assume that you are kind of familiar with it.&lt;br&gt;
Therefore, I highlight the gist instead.&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;don't cover&lt;/em&gt; the following in AWS CDK:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the ECS cluster. The adaption of the Fargate task itself is important and will be covered in this article!&lt;/li&gt;
&lt;li&gt;the VPC stack.&lt;/li&gt;
&lt;li&gt;the wiring of the stacks in the main application (located in &lt;code&gt;/bin&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The database adaption topic will be provided with an RDS example.&lt;/p&gt;
&lt;h2&gt;
  
  
  Import the secrets
&lt;/h2&gt;

&lt;p&gt;We created both secrets outside of AWS CDK, so we have to import them as resources.&lt;/p&gt;

&lt;p&gt;I highly recommend creating a separate Stack for that, which makes it essential for reusing them not only for the Fargate task but also for the (RDS) database.&lt;/p&gt;

&lt;p&gt;Get both ARNs of the username and password in order to import them properly.&lt;br&gt;
This can be done like that:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;One-third of the work is already done now. Congrats! ;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing the secrets to your AWS database
&lt;/h2&gt;

&lt;p&gt;In the example code, we going to use the RDS Service from AWS.&lt;br&gt;
The good thing about is, that we can use the password secret natively.&lt;br&gt;
The username needs to be converted to a &lt;code&gt;string&lt;/code&gt; before passing it to RDS.&lt;/p&gt;


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


&lt;p&gt;That concludes the setup of the database with our secret credentials.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing the secrets to the ECS Fargate task
&lt;/h2&gt;

&lt;p&gt;Here we go with the most precious piece of this article.&lt;/p&gt;

&lt;p&gt;Basically, we apply the same principle as with the RDS-Stack.&lt;br&gt;
We provide the database credentials as stack-props. Additionally, we add the database connection information to the props, e.g. host, port, etc.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;taskRole&lt;/code&gt; is created to grant access to both secrets and has a default behavior in this example.&lt;br&gt;
Under the hood, the command applies an IAM policy to the role.&lt;br&gt;
The read access is super important. Otherwise, the Fargate task can't read the actual content of both secrets during its runtime.&lt;br&gt;
This role needs to be passed to the ECS task by the argument &lt;code&gt;taskRole&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The important part comes straight after the &lt;code&gt;taskDef&lt;/code&gt; when appending the container.&lt;br&gt;
Spot the &lt;code&gt;secrets&lt;/code&gt; section.&lt;br&gt;
Here they are!&lt;/p&gt;


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


&lt;p&gt;As you can see, the secrets can live beside the regular environment variables.&lt;br&gt;
Feels decent like in a shared flat with beer and good music each evening, but with separated rooms! ;)&lt;/p&gt;

&lt;p&gt;If you made it up here, then big thanks for staying!&lt;br&gt;
Feel free to contact me for further discussions.&lt;br&gt;
Additionally, I like to get feedback on my very first article!&lt;br&gt;
Cheers!&lt;/p&gt;

&lt;p&gt;Michael&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>security</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
