title: How To Use Cloud Init To mount an unformatted EBS volume
body: <h1>Context</h1>
  
  <p>I am using the <a href="https://wiki.jenkins.io/display/JENKINS/Amazon+EC2+Plugin" rel="nofollow noreferrer">https://wiki.jenkins.io/display/JENKINS/Amazon+EC2+Plugin</a> for jenkins which allows me to dynamically provision new cloud instances as build slaves in AWS EC2.</p>
  
  <p>I am launching <code>ami-d834aba1</code> (Amazon Linux 2017.09.1).</p>
  
  <p>The plugin supports providing user-data and block device mapping too, currently I provide config like this after reading <a href="https://cloudinit.readthedocs.io/en/latest/" rel="nofollow noreferrer">https://cloudinit.readthedocs.io/en/latest/</a></p>
  
  <h2>User Data</h2>
  
  <pre><code>#cloud-config
  repo_update: true
  repo_upgrade: all
  package_upgrade: true
  
  bootcmd:
   - [ cloud-init-per, once, mkfs, -t, ext4, /dev/nvme1n1 ]
  
  fs_setup:
   - cmd: mkfs -t %(filesystem)s -L %(label)s %(device)s
     label: jenkins
     filesystem: 'ext4'
     overwrite: false
     device: '/dev/nvme1n1'
  
  mounts:
   - [ /dev/nvme1n1, /jenkins, "ext4", "defaults,nofail", "0", "2" ]
  
  users:
   - default
   - name: jenkins
     homedir: /jenkins
     lock_passwd: true
     ssh_authorized_keys:
       - a-key
  </code></pre>
  
  <h2>Block Device Mapping</h2>
  
  <pre><code>/dev/sdd=:100:true:gp2::encrypted
  </code></pre>
  
  <h1>Desired Behaviour</h1>
  
  <p>The instance would launch and would attach a new 100GB encrypted EBS volume which would be formatted as <code>ext4</code> and mounted at <code>/jenkins</code> as the home directory of the jenkins user.</p>
  
  <h1>Observed Behaviour</h1>
  
  <p>The instance launches, the 100GB encrypted EBS volume is created and attached to the EC2 instance (shows as in use and attached in AWS console). However,</p>
  
  <p>1) <code>df -h</code> doesn't show the filesystem.</p>
  
  <p>2)
      <code>cat /etc/fstab
      /dev/nvme1n1    /jenkins    ext4    defaults,nofail,comment=cloudconfig 0   2</code> does show it</p>
  
  <p>3) <code>sudo file -s /dev/nvme1n1
  /dev/nvme1n1: data</code> shows the volume as <code>data</code> formatted rather than <code>ext4</code></p>
  
  <p>4) sudo mount-a fails due to the filesystem not being ext4.</p>
  
  <h1>Manual Hack</h1>
  
  <p>If i manually SSH to the machine after boot and run:</p>
  
  <pre><code>sudo mkfs -t ext4 /dev/nvme1n1
  mke2fs 1.42.12 (29-Aug-2014)
  Creating filesystem with 26214400 4k blocks and 6553600 inodes
  Filesystem UUID: 7a434f7a-c048-4c3d-8098-b810e2ff8f84
  Superblock backups stored on blocks: 
      32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
      4096000, 7962624, 11239424, 20480000, 23887872
  
  Allocating group tables: done                            
  Writing inode tables: done                            
  Creating journal (32768 blocks): done
  Writing superblocks and filesystem accounting information: done   
  </code></pre>
  
  <p>Then  <code>sudo mount -a</code> it seems to mount the volume.</p>
  
  <h1>Questions</h1>
  
  <p>Is there any way to have the device formatted and mounted automatically? I tried with and without the </p>
  
  <p><code>bootcmd:
       - [ cloud-init-per, once, mkfs, -t, ext4, /dev/nvme1n1 ]</code></p>
  
  <p>Ideally it'd happen all before the user gets created since the home directory of the new user is going to be on this new mount.</p>
  
  <p>If the instance is stopped and started/restarted I'd not want to ideally lose all data by the reformatting happening again on boot.</p>