{"id":13618387,"url":"https://github.com/oogali/ebs-automatic-nvme-mapping","last_synced_at":"2025-04-14T10:31:46.170Z","repository":{"id":54573381,"uuid":"118183359","full_name":"oogali/ebs-automatic-nvme-mapping","owner":"oogali","description":"Automatic mapping of EBS volumes via NVMe block devices to standard block device paths","archived":true,"fork":false,"pushed_at":"2021-02-09T22:16:40.000Z","size":23,"stargazers_count":156,"open_issues_count":6,"forks_count":55,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-11-08T03:37:04.607Z","etag":null,"topics":["aws","aws-ec2","ebs-volumes","sysadmin","udev-rules"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oogali.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-19T22:02:41.000Z","updated_at":"2024-06-03T12:26:55.000Z","dependencies_parsed_at":"2022-08-13T20:10:29.512Z","dependency_job_id":null,"html_url":"https://github.com/oogali/ebs-automatic-nvme-mapping","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oogali%2Febs-automatic-nvme-mapping","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oogali%2Febs-automatic-nvme-mapping/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oogali%2Febs-automatic-nvme-mapping/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oogali%2Febs-automatic-nvme-mapping/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oogali","download_url":"https://codeload.github.com/oogali/ebs-automatic-nvme-mapping/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248862688,"owners_count":21173861,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","aws-ec2","ebs-volumes","sysadmin","udev-rules"],"created_at":"2024-08-01T20:02:00.156Z","updated_at":"2025-04-14T10:31:45.859Z","avatar_url":"https://github.com/oogali.png","language":"Shell","funding_links":[],"categories":["HarmonyOS","Shell"],"sub_categories":["Windows Manager"],"readme":"# Automatic Mapping of NVMe-style EBS Volumes to Standard Block Device Paths\n\n1. [Introduction](#introduction)\n2. [The Problem](#the-problem)\n3. [Brainstorming](#brainstorming)\n4. [The Hacky Solution](#the-hacky-solution)\n5. [The Less Hacky Solution](#the-less-hacky-solution)\n6. [A Test Run](#a-test-run)\n\n## Introduction\n\nSo you've decided to use the new `c5.large` or `m5.large` instance type in EC2.\n\nCongratulations! You get more IOPS!\n\n```\n$ aws --profile=personal-aws-testing ec2 --region=us-east-1 \\\n    run-instances \\\n      --count=1 \\\n      --instance-type=m5.large \\\n      --image-id=ami-8d3fd59b \\\n      --key-name=aws-testing \\\n      --subnet-id=subnet-bbbbbbbb \\\n      --security-group-ids=sg-77777777 \\\n      --ebs-optimized \\\n      --instance-initiated-shutdown-behavior=terminate \\\n      --tag-specifications='ResourceType=instance,Tags=[{Key=Name,Value=nvme-mapping-example}]'\n```\nBut wait, when you go to look at mountpoints (and disk space), what is this new `/dev/nvme*` device\nyou see?\n\n```\n[ec2-user@ip-10-81-64-224 ~]$ df -h\nFilesystem      Size  Used Avail Use% Mounted on\n...\n/dev/nvme0n1p1  7.8G  956M  6.8G  13% /\n```\n\nOh, ok. That's a NVMe block device per the AWS documentation[1]. That's cool.\n\n## The Problem\n\nNow, let's create and attach a 10GB EBS volume.\n\n```\n$ aws --profile=personal-aws-testing ec2 --region=us-east-1 \\\n    create-volume \\\n      --availability-zone=us-east-1a \\\n      --size=10 \\\n      --volume-type=gp2 \\\n      --tag-specifications='ResourceType=volume,Tags=[{Key=Name,Value=\"nvme-mapping-example, Example EBS Volume\"}]'\n...\n\n$ aws --profile=personal-aws-testing ec2 --region=us-east-1 \\\n    attach-volume \\\n      --device=/dev/sdf \\\n      --instance-id=i-44444444444444444 \\\n      --volume-id=vol-22222222222222222\n```\n\nRight, now let's verify our volume was attached.\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ dmesg | grep xvdf\n[ec2-user@ip-10-81-66-128 ~]$\n```\n\nUh, there's no mention of our block device (`xvdf`) in the kernel output. What about NVMe devices?\n\n```\n[  504.204889] nvme 0000:00:1f.0: enabling device (0000 -\u003e 0002)\n```\n\nThat's not quite what I'm expecting from the old days.\n\n## Brainstorming\n\nThere's more to this NVMe business. Let's get to it.\n\n### nvme-cli\n\nWe'll start by install the NVMe tools, and requesting a list of all NVMe devices in the system.\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo yum install nvme-cli\n...\nInstalled:\n  nvme-cli.x86_64 0:0.7-1.3.amzn1\n\nComplete!\n\n[ec2-user@ip-10-81-66-128 ~]$ sudo nvme list\nNode             SN                   Model                                    Version  Namespace Usage                      Format           FW Rev\n---------------- -------------------- ---------------------------------------- -------- --------- -------------------------- ---------------- --------\n/dev/nvme0n1     vol11111111111111111 Amazon Elastic Block Store               1.0      1           0.00   B /   8.59  GB    512   B +  0 B   1.0\n/dev/nvme1n1     vol22222222222222222 Amazon Elastic Block Store               1.0      1           0.00   B /  10.74  GB    512   B +  0 B   1.0\n```\n\nThe summary output shows our root EBS device (`/dev/nvme0n1`) and our newly created-and-attached\n device (`/dev/nvme1n1`).\n\n#### Can we get more information about our device? Yes.\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo nvme id-ctrl /dev/nvme1n1\nNVME Identify Controller:\nvid     : 0x1d0f\nssvid   : 0x1d0f\nsn      : vol22222222222222222\nmn      : Amazon Elastic Block Store\nfr      : 1.0\nrab     : 32\nieee    : dc02a0\ncmic    : 0\nmdts    : 6\ncntlid  : 0\nver     : 0\nrtd3r   : 0\nrtd3e   : 0\noaes    : 0\noacs    : 0\nacl     : 4\naerl    : 0\nfrmw    : 0x3\nlpa     : 0\nelpe    : 0\nnpss    : 1\navscc   : 0x1\napsta   : 0\nwctemp  : 0\ncctemp  : 0\nmtfa    : 0\nhmpre   : 0\nhmmin   : 0\ntnvmcap : 0\nunvmcap : 0\nrpmbs   : 0\nsqes    : 0x66\ncqes    : 0x44\nnn      : 1\noncs    : 0\nfuses   : 0\nfna     : 0\nvwc     : 0x1\nawun    : 0\nawupf   : 0\nnvscc   : 0\nacwu    : 0\nsgls    : 0\nps    0 : mp:0.01W operational enlat:1000000 exlat:1000000 rrt:0 rrl:0\n          rwt:0 rwl:0 idle_power:- active_power:-\nps    1 : mp:0.00W operational enlat:0 exlat:0 rrt:0 rrl:0\n          rwt:0 rwl:0 idle_power:- active_power:-\n```\n\n#### How about MORE information? Yes.\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo nvme id-ctrl --vendor-specific /dev/nvme1n1\n...\nvs[]:\n       0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n0000: 2f 64 65 76 2f 78 76 64 66 20 20 20 20 20 20 20 \"/dev/xvdf.......\"\n0010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 \"................\"\n0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n01a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n01b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n01c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n01d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n01e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n01f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n02a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n02b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n02c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n02d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n02f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n0390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n03a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n03b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n03c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n03d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n03e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n03f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \"................\"\n```\n\nWhaddya know? There's our requested block device name, at the beginning of the vendor specific\ninformation.\n\nLet's extract it. How? The `nvme id-ctrl` command takes an option called `--raw-binary`, which dumps\nout the information block inclusive of the vendor-specific data.\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo nvme id-ctrl --raw-binary /dev/nvme1n1 | hexdump -C\n00000000  0f 1d 0f 1d 76 6f 6c 30  32 34 32 39 34 33 34 62  |....vol222222222|\n00000010  38 61 35 35 37 66 66 32  41 6d 61 7a 6f 6e 20 45  |22222222Amazon E|\n00000020  6c 61 73 74 69 63 20 42  6c 6f 63 6b 20 53 74 6f  |lastic Block Sto|\n00000030  72 65 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |re              |\n00000040  31 2e 30 20 20 20 20 20  20 a0 02 dc 00 06 00 00  |1.0      .......|\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\n*\n00000100  00 00 04 00 03 00 00 01  01 00 00 00 00 00 00 00  |................|\n00000110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\n*\n00000200  66 44 00 00 01 00 00 00  00 00 00 00 00 01 00 00  |fD..............|\n00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\n*\n00000800  01 00 00 00 40 42 0f 00  40 42 0f 00 00 00 00 00  |....@B..@B......|\n00000810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\n*\n00000c00  2f 64 65 76 2f 78 76 64  66 20 20 20 20 20 20 20  |/dev/xvdf       |\n00000c10  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |\n00000c20  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\n*\n00001000\n```\n\nThe information within the vendor-specific data we are looking for appears to start at an offset of\n3,072 bytes, is a 32-byte record, and is padded with spaces (`0x20` == 32 dec == `\u003cSPACE\u003e`).\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo nvme id-ctrl --raw-binary /dev/nvme1n1 | cut -c3073-3104\n/dev/xvdf\u003cAND 23 SPACES YOU DO NOT READILY SEE\u003e\n```\n\nIt looks fine... but it has trailing spaces. How to verify that? Count the characters.\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo nvme id-ctrl --raw-binary /dev/nvme1n1 | cut -c3073-3104 | wc -c\n33\n```\n\n(It says 33 characters: 32 characters from our original block, plus one byte for a newline added by\n`cut`)\n\nSo, let's trim the trailing spaces for a viable block device name.\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo nvme id-ctrl --raw-binary /dev/nvme1n1 | cut -c3073-3104 | tr -s ' ' | sed 's/ $//g'\n/dev/xvdf\n```\n\nWe now have our desired block device name.\n\n## The Hacky Solution\n\nWe can create a symbolic link from the origin NVMe device, to the desired block device name.\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo ln -s /dev/nvme1n1 /dev/xvdf\n[ec2-user@ip-10-81-66-128 ~]$\n```\n\nHowever, the original block device can change with each reboot of the EC2 instance, e.g. reboot an\nEC2 instance with two volumes attached, and AWS can attach the two EBS volumes in different order,\nresulting in `nvme1n1` and `nvme2n1` swapping places.\n\nBut it's not limited to reboots. The same behavior can happen whenever an EBS volume is detached or\nattached.\n\n## The Less Hacky Solution\n\nTo make this a bit more resilient to attach-detach events, we want to trigger our shell script upon\neach of those events. This is what udev[2] was made for.\n\n### udev\n\n`udev`, the userspace /dev manager, operates as a daemon, that receives events each time a device is\nattached/detached from the host. It reads each event, compares the attributes of that event to a set\nof rules (located in `/etc/udev/rules.d`), and executes the specified actions of the rule.\n\nWhat are the attributes of our NVMe device that we can match on?\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo udevadm info --query=all --attribute-walk --path=/sys/block/nvme1n1\n\nUdevadm info starts with the device specified by the devpath and then\nwalks up the chain of parent devices. It prints for every device\nfound, all possible attributes in the udev rules key format.\nA rule to match, can be composed by the attributes of the device\nand the attributes from one single parent device.\n\n  looking at device '/devices/pci0000:00/0000:00:1f.0/nvme/nvme1/nvme1n1':\n    KERNEL==\"nvme1n1\"\n    SUBSYSTEM==\"block\"\n    DRIVER==\"\"\n    ATTR{ro}==\"0\"\n    ATTR{size}==\"20971520\"\n    ATTR{stat}==\"      61        0      920      108        0        0        0        0        0      108      108\"\n    ATTR{range}==\"0\"\n    ATTR{discard_alignment}==\"0\"\n    ATTR{ext_range}==\"256\"\n    ATTR{alignment_offset}==\"0\"\n    ATTR{inflight}==\"       0        0\"\n    ATTR{removable}==\"0\"\n    ATTR{capability}==\"50\"\n\n  looking at parent device '/devices/pci0000:00/0000:00:1f.0/nvme/nvme1':\n    KERNELS==\"nvme1\"\n    SUBSYSTEMS==\"nvme\"\n    DRIVERS==\"\"\n    ATTRS{model}==\"Amazon Elastic Block Store              \"\n    ATTRS{serial}==\"vol22222222222222222\"\n    ATTRS{firmware_rev}==\"1.0     \"\n\n  looking at parent device '/devices/pci0000:00/0000:00:1f.0':\n    KERNELS==\"0000:00:1f.0\"\n    SUBSYSTEMS==\"pci\"\n    DRIVERS==\"nvme\"\n    ATTRS{irq}==\"10\"\n    ATTRS{subsystem_vendor}==\"0x1d0f\"\n    ATTRS{broken_parity_status}==\"0\"\n    ATTRS{class}==\"0x010802\"\n    ATTRS{driver_override}==\"(null)\"\n    ATTRS{consistent_dma_mask_bits}==\"64\"\n    ATTRS{dma_mask_bits}==\"64\"\n    ATTRS{local_cpus}==\"3\"\n    ATTRS{device}==\"0x8061\"\n    ATTRS{enable}==\"1\"\n    ATTRS{msi_bus}==\"1\"\n    ATTRS{local_cpulist}==\"0-1\"\n    ATTRS{vendor}==\"0x1d0f\"\n    ATTRS{subsystem_device}==\"0x8061\"\n    ATTRS{numa_node}==\"0\"\n    ATTRS{d3cold_allowed}==\"0\"\n\n  looking at parent device '/devices/pci0000:00':\n    KERNELS==\"pci0000:00\"\n    SUBSYSTEMS==\"\"\n    DRIVERS==\"\"\n```\n\nIn order to identify EBS volumes, we want something that is stable across reboots. But not too\nspecific to this volume, otherwise you're flying in the face of automation and manually hard-coding\nyour configuation.\n\nI've picked `ATTRS{model}`.\n\nLet's combine what we've found into a [shell script](ebs-nvme-mapping.sh), and a [udev rule](999-aws-ebs-nvme.rules)...\n\n...and finally reload the `udev` rules and trigger it...\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo udevadm control --reload-rules \u0026\u0026 udevadm trigger\n```\n\nNow, when we attach and detach EBS volumes, our shell script will run.\n\n## A Test Run\n\n### Dry run\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ sudo udevadm test /sys/block/nvme1n1\n[...]\nReading rules file: /etc/udev/rules.d/999-aws-ebs-nvme.rules\n[...]\nstarting '/usr/local/sbin/ebs-nvme-mapping.sh /dev/nvme1n1'\n[...]\n'/usr/local/sbin/ebs-nvme-mapping.sh /dev/nvme1n1'(out) 'xvdf'\n[...]\ncreating link '/dev/xvdf' to '/dev/nvme1n1'\n[...]\n```\n\n### Live run\n\nWe have no block device (symlink) before...\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ ls -la /dev/xvdf\nls: cannot access /dev/xvdf: No such file or directory\n```\n\nNow let's create and attach a new volume...\n\n```\n$ aws --profile=personal-aws-testing ec2 --region=us-east-1 \\\n    create-volume \\\n      --availability-zone=us-east-1a \\\n      --size=30 \\\n      --volume-type=gp2 \\\n      --tag-specifications='ResourceType=volume,Tags=[{Key=Name,Value=\"nvme-mapping-example, Example EBS Volume #2\"}]'\n...\n\n$ aws --profile=personal-aws-testing ec2 --region=us-east-1 \\\n    attach-volume \\\n      --device=/dev/sdf \\\n      --instance-id=i-44444444444444444 \\\n      --volume-id=vol-22222222222222222\n...\n```\n\nEt voila!\n\n```\n[ec2-user@ip-10-81-66-128 ~]$ ls -la /dev/xvdf\nlrwxrwxrwx 1 root root 12 Jan 19 21:43 /dev/xvdf -\u003e /dev/nvme2n1\n```\n\n1: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html\n\n2: https://en.wikipedia.org/wiki/Udev\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foogali%2Febs-automatic-nvme-mapping","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foogali%2Febs-automatic-nvme-mapping","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foogali%2Febs-automatic-nvme-mapping/lists"}