title: Is it secure to store EC2 User-Data shell scripts in a private S3 bucket?
body: <p>I have an EC2 ASG on AWS and I'm interested in storing the shell script that's used to instantiate any given instance in an S3 bucket and have it downloaded and run upon instantiation, but it all feels a little rickety even though I'm using an <code>IAM Instance Role</code>, transferring via HTTPS, and encrypting the script itself while at rest in the S3 bucket <strike>using <code>KMS</code></strike> using <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html" rel="noreferrer"><code>S3 Server Side Encryption</code></a> (<a href="https://stackoverflow.com/questions/30009184/ec2-instance-role-gets-unknown-error-when-attempting-aws-s3-cp-kms-encrypted-f">because the <code>KMS</code> method was throwing an 'Unknown' error</a>).
  <br><br></p>
  
  <p><strong>The Setup</strong></p>
  
  <ul>
  <li>Created an <code>IAM Instance Role</code> that gets assigned to any instance in my ASG upon instantiation, resulting in my AWS creds being baked into the instance as <code>ENV</code> vars</li>
  <li>Uploaded and encrypted my <code>Instance-Init.sh</code> script to S3 resulting in a private endpoint like so : <a href="https://s3.amazonaws.com/super-secret-bucket/Instance-Init.sh" rel="noreferrer">https://s3.amazonaws.com/super-secret-bucket/Instance-Init.sh</a>
  <br><br></li>
  </ul>
  
  <p><strong>In The <code>User-Data</code> Field</strong></p>
  
  <p>I input the following into the <code>User Data</code> field when creating the <code>Launch Configuration</code> I want my ASG to use:</p>
  
  <pre><code>#!/bin/bash
  
  apt-get update
  apt-get -y install python-pip
  apt-get -y install awscli
  cd /home/ubuntu
  aws s3 cp s3://super-secret-bucket/Instance-Init.sh . --region us-east-1
  chmod +x Instance-Init.sh
  . Instance-Init.sh
  shred -u -z -n 27 Instance-Init.sh
  </code></pre>
  
  <p>The above does the following:</p>
  
  <ul>
  <li>Updates package lists</li>
  <li>Installs Python (required to run <code>aws-cli</code>)</li>
  <li>Installs <code>aws-cli</code></li>
  <li>Changes to the <code>/home/ubuntu</code> user directory</li>
  <li>Uses the <code>aws-cli</code> to download the <code>Instance-Init.sh</code> file from <code>S3</code>. Due to the <code>IAM Role</code> assigned to my instance, my AWS creds are automagically discovered by <code>aws-cli</code>. The <code>IAM Role</code> also grants my instance the permissions necessary to decrypt the file.</li>
  <li>Makes it executable</li>
  <li>Runs the script</li>
  <li>Deletes the script after it's completed.
  <br><br></li>
  </ul>
  
  <p><strong>The <code>Instance-Init.sh</code> Script</strong></p>
  
  <p>The script itself will do stuff like setting <code>env</code> vars and <code>docker run</code> the containers that I need deployed on my instance. Kinda like so:</p>
  
  <pre><code>#!/bin/bash
  
  export MONGO_USER='MyMongoUserName'
  export MONGO_PASS='Top-Secret-Dont-Tell-Anyone'
  
  docker login -u &lt;username&gt; -p &lt;password&gt; -e &lt;email&gt;
  docker run - e MONGO_USER=${MONGO_USER} -e MONGO_PASS=${MONGO_PASS} --name MyContainerName quay.io/myQuayNameSpace/MyAppName:latest
  </code></pre>
  
  <p><br></p>
  
  <p><strong>Very Handy</strong></p>
  
  <p>This creates a very handy way to update <code>User-Data</code> scripts without the need to create a new <code>Launch Config</code> every time you need to make a minor change. And it does a great job of getting <code>env</code> vars out of your codebase and into a narrow, controllable space (the <code>Instance-Init.sh</code> script itself).</p>
  
  <p>But it all feels a little insecure. The idea of putting my master DB creds into a file on S3 is unsettling to say the least.
  <br><br></p>
  
  <p><strong>The Questions</strong> </p>
  
  <ol>
  <li>Is this a common practice or am I dreaming up a bad idea here?</li>
  <li>Does the fact that the file is downloaded and stored (albeit briefly) on the fresh instance constitute a vulnerability at all?</li>
  <li>Is there a better method for deleting the file in a more secure way?</li>
  <li>Does it even matter whether the file is deleted after it's run? Considering the secrets are being transferred to <code>env</code> vars it almost seems redundant to delete the <code>Instance-Init.sh</code> file.</li>
  <li>Is there something that I'm missing in my nascent days of ops?
  <br><br></li>
  </ol>
  
  <p>Thanks for any help in advance.</p>