How OpsWorks mount EBS Volume automatically

  1. Add an Additional EBS Volumes with OpsWorks Layer's configuration.
$ aws opsworks --region us-west-2 describe-layers --stack-id 433a1bd3-699d-4306-9533-b44530293ab5 --query 'Layers[*].VolumeConfigurations'


[
    [
        {
            "MountPoint": "/mnt/workspace",
            "NumberOfDisks": 1,
            "Size": 10,
            "VolumeType": "gp2",
            "Encrypted": false
        }
    ]
]
  1. Add SSH key with Stack configuration. So, we can access the instance via SSH.
  2. Access to the OpsWorks instance. I can view the EBS is mounted on /mnt/workspace.
$ mount | grep "workspace"
/dev/xvdi on /mnt/workspace type xfs (rw,relatime,attr2,inode64,noquota)
  1. The ephemeral device ephemeral0 is mounted on /media/ephemeral0 by cloud-init.
$ tail -n 5 /etc/cloud/cloud.cfg

mounts:
 - [ ephemeral0, /media/ephemeral0 ]
 - [ swap, none, swap, sw, "0", "0" ]
# vim:syntax=yaml
  1. EBS volumes will be set up the current configuration in /var/lib/aws/opsworks/chef/xxxxxxxxx.json. After that, the default OpsWork recipes aws_opsworks_ebshelp us to mount the volume to the configured mount points.
$ cat /var/lib/aws/opsworks/chef/2022-01-06-10-35-28-01.json
...
      "volumes": [
        {
          "name": "Created for nodejs-server2",
          "mount_point": "/mnt/workspace",
          "device": "/dev/sdi",
          "volume_id": "vol-032b79ca4f686b2ee"
        }
      ]
    },
$ cat /var/lib/aws/opsworks/chef/2022-01-06-10-33-35-01.log
...
[2022-01-06T10:33:51+00:00] INFO: Processing ruby_block[delete_lines_from_fstab] action run (aws_opsworks_ebs::default line 1)
[2022-01-06T10:33:51+00:00] INFO: ruby_block[delete_lines_from_fstab] called
[2022-01-06T10:33:51+00:00] INFO: Processing yum_package[xfsprogs] action install (aws_opsworks_ebs::default line 9)
[2022-01-06T10:33:51+00:00] INFO: Processing ruby_block[add xfs to list of known filesystems] action run (aws_opsworks_ebs::default line 16)
[2022-01-06T10:33:51+00:00] INFO: ruby_block[add xfs to list of known filesystems] called
[2022-01-06T10:33:51+00:00] INFO: Processing apt_repository[add_required_repository_for_nvme-cli_for_ubuntu-14.04] action add (aws_opsworks_ebs::default line 23)
[2022-01-06T10:33:51+00:00] INFO: Processing yum_package[nvme-cli] action install (aws_opsworks_ebs::default line 28)
[2022-01-06T10:33:51+00:00] INFO: Processing ebs_volume[vol-032b79ca4f686b2ee] action mount (aws_opsworks_ebs::default line 44)
[2022-01-06T10:33:51+00:00] INFO: Processing execute[mkfs /dev/xvdi] action run (/var/lib/aws/opsworks/cache.internal/cookbooks/aws_opsworks_ebs/resources/ebs_volume.rb line 15)
[2022-01-06T10:33:52+00:00] INFO: execute[mkfs /dev/xvdi] ran successfully
[2022-01-06T10:33:52+00:00] INFO: Processing directory[/mnt/workspace] action create (/var/lib/aws/opsworks/cache.internal/cookbooks/aws_opsworks_ebs/resources/ebs_volume.rb line 29)
[2022-01-06T10:33:52+00:00] INFO: directory[/mnt/workspace] created directory /mnt/workspace
[2022-01-06T10:33:52+00:00] INFO: directory[/mnt/workspace] mode changed to 755
[2022-01-06T10:33:52+00:00] INFO: Processing ruby_block[delete existing fstab entries for this mount point and device] action run (/var/lib/aws/opsworks/cache.internal/cookbooks/aws_opsworks_ebs/resources/ebs_volume.rb line 35)
[2022-01-06T10:33:52+00:00] INFO: ruby_block[delete existing fstab entries for this mount point and device] called
[2022-01-06T10:33:52+00:00] INFO: Processing mount[/mnt/workspace] action mount (/var/lib/aws/opsworks/cache.internal/cookbooks/aws_opsworks_ebs/resources/ebs_volume.rb line 44)
[2022-01-06T10:33:52+00:00] INFO: mount[/mnt/workspace] mounted
[2022-01-06T10:33:52+00:00] INFO: Processing mount[/mnt/workspace] action enable (/var/lib/aws/opsworks/cache.internal/cookbooks/aws_opsworks_ebs/resources/ebs_volume.rb line 44)
[2022-01-06T10:33:52+00:00] INFO: mount[/mnt/workspace] enabled
...

The following is default aws_opsworks_ebs recipe.

$ cat /opt/aws/opsworks/current/cookbooks/aws_opsworks_ebs/recipes/default.rb
ruby_block "delete_lines_from_fstab" do
  block do
    file = Chef::Util::FileEdit.new("/etc/fstab")
    file.search_file_delete_line("/dev/nvme")
    file.write_file
  end
end

package "xfsprogs" do
  # RedHat 6 does not provide xfsprogs
  not_if { rhel6? }
  retries 2
end

# add xfs to list of known filesystems
ruby_block "add xfs to list of known filesystems" do
  block do
    Filesystems.add_xfs_to_known_filesystems
  end
  only_if { ::File.exist?("/etc/filesystems") && node["aws_opsworks_agent"]["resources"]["volumes"].size > 0 }
end

apt_repository 'add_required_repository_for_nvme-cli_for_ubuntu-14.04' do
  only_if { EbsVolumeHelpers.nvme_based? && !EbsVolumeHelpers.has_ebs_tooling? && platform?("ubuntu") && node[:platform_version] == "14.04" && node["aws_opsworks_agent"]["resources"]["volumes"].size > 0 }
  uri 'ppa:sbates'
end

package "nvme-cli" do
  only_if { EbsVolumeHelpers.nvme_based? && !EbsVolumeHelpers.has_ebs_tooling? && !rhel6? && node["aws_opsworks_agent"]["resources"]["volumes"].size > 0 }
  retries 2
end

node["aws_opsworks_agent"]["resources"]["volumes"].each do |volume|
  if rhel6?
    log "skipping volume #{volume["device"]} - no EBS volume support for Red Hat Enterprise Linux 6"
    next
  end

  if volume["mount_point"].nil? || volume["mount_point"].empty?
    log "skip mounting volume #{volume["device"]} (#{volume["volume_id"]}) because no mount_point specified"
    next
  end

  ebs_volume volume["volume_id"] do
    mount_point volume["mount_point"]
    volume_id volume["volume_id"]
    device volume["device"]
    fstype volume["fstype"] || "xfs"
  end
end

References

  1. Editing an OpsWorks Layer's Configuration - EBS Volumes - https://docs.aws.amazon.com/opsworks/latest/userguide/workinglayers-basics-edit.html#workinglayers-basics-edit-ebs