Unable to attach ebs block in aws

I am getting argument error while attaching the ebs volume with instance bootstrapped for the first time with chef provisioning aws for the below snippet of code.

machine ‘Sample’ do
add_machine_options :ssh_username => ‘ec2-user’,
:bootstrap_options => {
:instance_type => ‘t2.micro’,
:image_id => “ami-2051294a”,
:associate_public_ip_address => true,
block_device_mapping: [{
device_name: ‘/dev/sdb’,
ebs: {
volume_size: 6, # 1 GB
delete_on_termination: true
}
}]
}
end

ArgumentError: unexpected value at params[:block_device_mapping]

I have probably 2 suggestions.

Solution to Problem

machine "ebstest" do
  chef_config "chef_server_url \"http://some-chef-server\""
  run_list ["role[some_role]"]
  chef_environment "mycloudenv"
    machine_options(
      lazy do
        {
          bootstrap_options: {
            subnet_id: "whatever"
            security_group_ids: ["group1", "group2"],
            key_name: "mykeyname",
            instance_type: "t2.micro",
            associate_public_ip_address: true,
            image_id: "ami-XXXXXXXX",
            block_device_mappings: [
              {
                device_name: "/dev/xvdf",
                ebs: {
                  volume_size: 15,
                  delete_on_termination: true,
                  volume_type: "gp2", # accepts standard, io1, gp2
                },
              },
            ],
        },
          convergence_options: {
            prerelease: "false",
            chef_client_timeout: 120*60, # Default: 2 hours
            ssl_verify_mode: :verify_none
      },
          ssh_username: "centos",
          aws_tags: {:tagitwith => "sometag" }
     }
    end # end of lazy
  ) # end of machine options for this instance
end

My solution on handling this in a more graceful way - and honestly faster/more reliable

Instead of trying to attach and do everything in one go… I’ll suggest approaching things in 3 phases…

:setup phase - build your machines/infrastructure (no actual converges) but you can register with chef servers… setup all the infrastructure etc… take advantage of machine_batch for lots more speed… just remember to machine_batch action :setup… you can also do loops and so on to create various boxes in this stage (in parallel)

machine_batch do
  action :setup
    machine "machine1" do
      ...
    end
end

intermediate stage. Do things like create and attach EBS volumes … attach machines you built to load balancers…

so here we can build an ebs volume and attach it to our previously created machine that just did :setup

aws_ebs_volume 'my-ebs-volume1' do  
  machine 'ebstest'  
  size 15  
  volume_type 'gp2'  
  device '/dev/xvdf'  
end

you can also do other things in this stage too like create ELBs… or anything really

Converge your nodes to apply software/automagic stuff etc… remember its ruby so you can do loops and other things etc to make your recipe more dynamic

machine_batch do
  action :converge_only
    machine "ebstest" do
    end
    machine "otherboxes" do
    end
end

I HIGHLY prefer the 2nd method… as its less clunky! and less prone to failure… just remember you have to clean up the volumes yourself if you’re doing tests (as in some kind of destroy recipe that enumerates all your resources)

Hope this helps!