Code Monkey home page Code Monkey logo

chef-provisioning-aws's Introduction

Chef Provisioning was officially end-of-life on August 31, 2019 and is no longer included with Chef DK. The Chef Provisioning source code and drivers have been moved into the chef-boneyard organization. If you are a current user of Chef Provisioning, please contact your Chef Customer Success Manager or Account Representative to review your options.

Chef Provisioning AWS

Build StatusGem Version

This README is a work in progress. Feel free to open PRs expanding it!

Prerequisites

Credentials

There are 3 ways you can provide your AWS Credentials. We will look for credentials in the order from below and use the first one found. This precedence order is taken from http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration:

  1. Through the environment variables ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"] and optionally ENV["AWS_SESSION_TOKEN"]
  2. The shared credentials ini file. The default location is ~/.aws/credentials but you can overwrite this by specifying ENV["AWS_CONFIG_FILE"]. You can specify multiple profiles in this file and select one with the ENV["AWS_DEFAULT_PROFILE"] environment variable or via the driver url. For example, a driver url of aws:staging:us-east-1 would use the profile staging. If you do not specify a profile then the default one is used. Read this for more information about profiles.
  3. From an instance profile when running on EC2. This accesses the local metadata service to discover the local instance's IAM instance profile.

Configurable Options

aws_retry_limit

When using machine_batch with a large number of machines it is possible to overwhelm the AWS SDK until it starts returning AWS::EC2::Errors::RequestLimitExceeded. You can configure the AWS SDK to retry these errors automatically by specifying

chef_provisioning({:aws_retry_limit => 10})

in your client.rb for the provisioning workstation. The default :aws_retry_limit is 5.

image_max_wait_time and machine_max_wait_time

By default, the time we will wait for a machine to become ready or for the transport to become ready is 120 seconds (each). For a machine_image we wait 300 seconds for the AMI to be created. These timeouts can be configured with

chef_provisioning({:image_max_wait_time => 600, :machine_max_wait_time => 240})

in your client.rb for the provisioning workstation.

Resources

TODO: List out weird/unique things about resources here. We don't need to document every resource because users can look at the resource model.

aws_key_pair

You can specify an existing key pair to upload by specifying the following:

aws_key_pair 'my-aws-key' do
  private_key_path "~boiardi/.ssh/my-aws-key.pem"
  public_key_path "~boiardi/.ssh/my-aws-key.pub"
  allow_overwrite false # Set to true if you want to regenerate this each chef run
end

aws_launch_configuration

In the AWS SDK V1, you must specify key_pair instead of key_name when specifying the key name to use for machines in the auto scaling group. This is fixed in V2 and uses key_name like machines do.

aws_launch_configuration 'example-windows-launch-configuration' do
  image 'example-windows-image'
  instance_type 't2.medium'
  options security_groups: 'example-windows-sg',
    key_pair: 'my-key-name',
    ebs_optimized: false,
    detailed_instance_monitoring: false,
    iam_instance_profile: 'example-windows-role',
    user_data: <<-EOF
<powershell>
# custom powershell code goes here, executed at instance creation time
</powershell>
  EOF
end

aws_vpc

If you specify internet_gateway true the VPC will create and manage its own internet gateway. Specifying internet_gateway false will delete that managed internet gateway.

Specifying main_routes without main_route_table will update the 'default' route table that is created when AWS creates the VPC.

Specifying main_route_table without specifying main_routes will update the main route association to point to the provided route table.

If you specify both main_routes and main_route_table we will update the main_route_table to have the specified main_routes. IE, running

aws_route_table 'ref-main-route-table' do
  vpc 'ref-vpc'
  routes '0.0.0.0/0' => :internet_gateway
end

aws_vpc 'ref-vpc' do
  main_route_table 'ref-main-route-table'
  main_routes '0.0.0.0/1' => :internet_gateway
end

aws_vpc 'ref-vpc' do
  main_routes '0.0.0.0/2' => :internet_gateway
end

will cause resource flapping. The ref-main-route-table resource will set the routes to /0 and then the vpc will set the routes to /1. Then because ref-main-route-table is set to the main route for ref-vpc the third resource will set the routes to /2.

The takeaway from this is that you should either specify main_routes on your VPC and only manage the routes through that, OR only specify main_route_table and manage the routes through the aws_route_table resource.

Purging

If you specify action :purge on the VPC it will attempt to delete ALL resources contained in this VPC before deleting the actual VPC.

A potential danger of this is that it does not delete the data bag entries for tracked AWS objects. If you :purge a VPC and it has aws_route_table[ref-route] in it, the data bag entry for ref-route is not automatically destroyed. Purge is most useful for testing to ensure no objects are left that AWS can charge for.

Machine Options

You can pass machine options that will be used by machine, machine_batch and machine_image to configure the machine.

These options are an extension of the base options. Please see that for a list of the machine_options shared between drivers.

The full syntax available in the bootstrap_options hash is the hash expected by the AWS create_instances method. The options seen below in the example are the default options.

with_machine_options({
  # See https://github.com/chef/chef-provisioning#machine-options for options shared between drivers
  bootstrap_options: {
    # http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Resource.html#create_instances-instance_method
    # lists the available options.  The below options are the default
    image_id: "ami-5915e11d", # default for us-west-1
    instance_type: "t2.micro",
    key_name: "chef_default", # If not specified, this will be used and generated
    key_path: "~/.chef/keys/chef_default", # only necessary if storing keys some other location
    user_data: "...", # Only defaulted on Windows instances to start winrm
  },
  use_private_ip_for_ssh: false, # DEPRECATED, use `transport_address_location`
  transport_address_location: :public_ip, # `:public_ip` (default), `:private_ip` or `:dns`.  Defines how SSH or WinRM should find an address to communicate with the instance.
  is_windows: true, # false by default
  winrm_username: "Administrator",
  winrm_password: "password", # Override if you have specified your own password and are not fetching the password from AWS
})

This options hash can be supplied to either with_machine_options at the recipe level or directly into the machine_options attribute.

Load Balancer Options

You can configure the ELB options by setting with_load_balancer_options or specifying them on each load_balancer resource.

machine 'test1'
m2 = machine 'test2'
load_balancer "my_elb" do
  machines ['test1', m2]
  load_balancer_options({
    subnets: subnets,
    security_groups: [load_balancer_sg],
    listeners: [
      {
          instance_port: 8080,
          protocol: 'HTTP',
          instance_protocol: 'HTTP',
          port: 80
      },
      {
          instance_port: 8080,
          protocol: 'HTTPS',
          instance_protocol: 'HTTP',
          port: 443,
          ssl_certificate_id: "arn:aws:iam::360965486607:server-certificate/cloudfront/foreflight-2015-07-09"
      }
    ],
    health_check: {
      healthy_threshold: 2,
      unhealthy_threshold: 4,
      interval: 12,
      timeout: 5,
      target: 'HTTPS:443/_status'
    }
  })

The available parameters for load_balancer_options can be viewed in the aws docs.

If you wish to enable sticky sessions, pass a sticky_sessions key to the load_balancer_options and specify a cookie name and the ports that should be sticky. In the above example, it would look like this:

machine 'test1'
m2 = machine 'test2'
load_balancer "my_elb" do
  machines ['test1', m2]
  load_balancer_options({
    subnets: subnets,
    security_groups: [load_balancer_sg],
    listeners: [
      {
          instance_port: 8080,
          protocol: 'HTTP',
          instance_protocol: 'HTTP',
          port: 80
      },
      {
          instance_port: 8080,
          protocol: 'HTTPS',
          instance_protocol: 'HTTP',
          port: 443,
          ssl_certificate_id: "arn:aws:iam::360965486607:server-certificate/cloudfront/foreflight-2015-07-09"
      }
    ],
    sticky_sessions: {
      cookie_name: 'my-app-cookie',
      ports: [80, 443]
    }
  })

NOTES:

  1. You can specify either ssl_certificate_id or server_certificate in a listener but the value to both parameters should be the ARN of an existing IAM::ServerCertificate object.

  2. The sticky_sessions option currently only supports Application-Controlled Session Stickiness.

RDS Instance Options

Additional Options

RDS instances have many options. Some of them live as first class attributes. Any valid RDS option that is not a first class attribute can still be set via a hash in additional_options. If you set an attribute and also specify it in additional_options, the resource will chose the attribute and not what is specified in additional_options.

To illustrate, note that the following example defines multi_az as both an attribute and in the additional_options hash:

aws_rds_instance "test-rds-instance2" do
  engine "postgres"
  publicly_accessible false
  db_instance_class "db.t1.micro"
  master_username "thechief"
  master_user_password "securesecure"
  multi_az false
  additional_options(multi_az: true)
end

The above would result in a new aws_rds_instance with multi_az being false.

Additional values for additional_options can view viewed in the aws docs.

Specifying a DB Subnet Group for your RDS Instance

See this example for how to set up a DB Subnet Group and pass it to your RDS Instance.

Specifying a Chef Server

See Pointing Boxes at Chef Servers

Tagging Resources

For Recipe authors

All resources (incuding base resources like machine) that are taggable support an aws_tags attribute which accepts a single layer hash. To set just the key of an AWS tag specify the value as nil. EG, aws_tags {my_tag_key: nil}. Some AWS objects cannot accept nil values and will automatically convert it to an empty string.

Some AWS objects (may EC2) view the Name tag as unique - it shows up in a Name column in the AWS console. By default we specify the Name tag as the resource name. This can be overridden by specifying aws_tags {Name: 'some other name'}.

You can remove all the tags except the Name tag by specifying aws_tags({}).

Tag keys and values can be specified as symbols or strings but will be converted to strings before sending to AWS.

Examples:

aws_ebs_volume 'ref-volume' do
  aws_tags company: 'my_company', 'key_as_string' => :value_as_symbol
end

aws_vpc 'ref-vpc' do
  aws_tags 'Name' => 'custom-vpc-name'
end

For Resource Authors

To enable tagging support you must make specific changes to the Resource and Attribute. For the Resource it needs to include the attribute aws_tags. This should be done by include Chef::Provisioning::AWSDriver::AWSTaggable on the Resource.

The AWSProvider class will automatically try to call converge_tags when running the action_create method. You should instantiate an instance of the AWSTagger and provide it a strategy depending on the client used to perform the tagging. For example, an RDS Provider should define

def aws_tagger
  @aws_tagger ||= begin
    rds_strategy = Chef::Provisioning::AWSDriver::TaggingStrategy::RDS.new(
      new_resource.driver.rds,
      construct_arn(new_resource),
      new_resource.aws_tags
    )
    Chef::Provisioning::AWSDriver::AWSTagger.new(rds_strategy, action_handler)
  end
end
def converge_tags
  aws_tagger.converge_tags
end

The aws_tagger method is used by the tests to assert that the object tags are correct. These methods can be encapsulated in an module for DRY purposes, as the EC2 strategy shows.

Finally, you should add 3 standard tests for taggable objects - 1) Tags can be created on a new object, 2) Tags can be updated on an existing object with tags and 3) Tags can be cleared by setting aws_tags({}). Copy the tests from an existing spec file and modify them to support your resource. TODO make a module that copies these tests for us. Right now it is complicated by the fact that some resources have required attributes that others don't.

Looking up AWS objects

#aws_object

All chef-provisioning-aws resources have a aws_object method that will return the AWS object. The base resources machine, machine_image and load_balancer are monkeypatched to also include the aws_object method and should respond to it like all other resources.

The AWS object won't exist until the resource converges, however. An example of how to do this looks like:

my_vpc = aws_vpc 'my_vpc' do
  cidr_block '10.0.0.0/24'
  main_routes '0.0.0.0/0' => :internet_gateway
  internet_gateway true
end

my_sg = aws_security_group 'my_sg' do
  vpc lazy { my_vpc.aws_object.id }
  inbound_rules '0.0.0.0/0' => [ 22, 80 ]
end

my_subnet = aws_subnet 'my_subnet' do
  vpc lazy { my_vpc.aws_object.id }
  cidr_block '10.0.0.0/24'
  availability_zone 'eu-west-1a'
  map_public_ip_on_launch true
end

machine 'my_machine' do
  machine_options(
    lazy do
      {
        bootstrap_options: {
          subnet_id: my_subnet.aws_object.id,
          security_group_ids: [my_sg.aws_object.id]
        }
      }
    end
  )
end

Note the use of the lazy attribute modifier. This is necessary because when the resources are compiled the aws_objects do not exist yet, so we must wait to reference them until the converge phase.

#lookup_options

You have access to the aws object when necessary, but often it isn't needed. The above example is better written as:

aws_vpc 'my_vpc' do
  cidr_block '10.0.0.0/24'
  main_routes '0.0.0.0/0' => :internet_gateway
  internet_gateway true
end

aws_security_group 'my_sg' do
  vpc 'my_vpc'
  inbound_rules '0.0.0.0/0' => [ 22, 80 ]
end

aws_subnet 'my_subnet' do
  vpc 'my_vpc'
  cidr_block '10.0.0.0/24'
  availability_zone 'eu-west-1a'
  map_public_ip_on_launch true
end

machine 'my_machine' do
  machine_options(
    bootstrap_options: {
      subnet_id: 'my_subnet',
      security_group_ids: ['my_sg']
    }
  )
end

When specifying bootstrap_options and any attributes which reference another aws resource, we perform lookup_options. This tries to turn elements with names like vpc, security_group_ids, machines, launch_configurations, load_balancers, etc. to the correct AWS object.

How to update Security Groups for EC2-VPC instances

The behavior of the machine resource is that once a machine has been allocated, the bootstrap_options can not be modified. This currently reflects AWS's restrictions on EC2-Classic instances, but AWS does allow users to modify the security groups associated with EC2-VPC instances. This is because the security groups for EC2-VPC instances are actually associated with that instance's Network Interface. This means that if you wish to modify the security groups associated with an EC2-VPC instance, you'll want to use the aws_network_interface resource.

The first step is to find the Network Interface ID (eni-XXXXXXX) associated with your machine. You can do this by inspecting the instance details in the AWS Console or by using the AWS CLI. If you want to use the AWS CLI, you can use this command replacing MACHINE_NAME with the name of the machine resource you wish to update.

aws ec2 describe-instances --filter "Name=tag:Name,Values=MACHINE_NAME" | grep NetworkInterfaceId

Once you have the Network Interface ID, in a chef-provisioning recipe you can specify the following resource:

require 'chef/provisioning/aws_driver'
with_driver 'aws' # specify the profile / region as appropriate

aws_network_interface 'eni-XXXXXXXX' do
  security_groups ['sg-XXXXXXXX', 'sg-YYYYYYYY']
end

This resource can be in the same chef-provisioning recipe as the corresponding machine resource, or it can be in a different one.

Running Integration Tests

To run the integration tests execute bundle exec rspec. If you have not set it up, you should see an error message about a missing environment variable AWS_TEST_DRIVER. You can add this as a normal environment variable or set it for a single run with AWS_TEST_DRIVER=aws::eu-west-1 bundle exec rspec. The format should match what with_driver expects.

You will also need to have configured your ~/.aws/config or environment variables with your AWS credentials.

This creates real objects within AWS. The tests make their best effort to delete these objects after each test finishes but errors can happen which prevent this. Be aware that this may charge you!

If you find the tests leaving behind resources during normal conditions (IE, not when there is an unexpected exception) please file a bug. Most objects can be cleaned up by deleting the test_vpc from within the AWS browser console.

chef-provisioning-aws's People

Contributors

bbbco avatar bookshelfdave avatar btm avatar chef-ci avatar dblessing avatar dheerajd-msys avatar hh avatar jaym avatar jjlimepoint avatar jkeiser avatar joaogbcravo avatar johnewart avatar josb avatar keen99 avatar lynchc avatar mattyait avatar miguelcnf avatar mrtam avatar msonnabaum avatar nashwini avatar piyushawasthi avatar randomcamel avatar raskchanky avatar redterror avatar ryancragun avatar schisamo avatar stevendanna avatar tas50 avatar tyler-ball avatar tylercloke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chef-provisioning-aws's Issues

Remove update_load_balancer?

update_load_balancer looks like a code smell to me: the driver ought to be making those decisions internally (this would also make it easier to clean things up so that things like servers would be added to the LB on create as well as update).

Can't specify ssh_username via machine_options

Because of:

          machine_spec.location = {
              'driver_url' => driver_url,
              'driver_version' => Chef::Provisioning::AWSDriver::VERSION,
              'allocated_at' => Time.now.utc.to_s,
              'host_node' => action_handler.host_node,
              'image_id' => machine_options[:image_id],
              'instance_id' => instance.id
          }

And:

          username = machine_spec.location['ssh_username'] || default_ssh_username

We can't set ssh_username as a machine_option.

Support Spot Instances

SPIKE! It seems like we need a small spike story to go answer all these questions first.

Acceptance Criteria: Users can specify a spot price and number of instances, and chef will store the request information and poll until timeout to wait for the request to be fulfilled. If not fulfilled in time or the price is too low, we error out. If not fulfilled in time, we can run chef again to restart polling and wait for the instances to come up.

  • Do we need to store all the individual instance numbers, or just the request so we can look up the whole batch at once?
  • For number of instances, how will it work out with machine batch? Don't support batch for spot instances?
  • Should this extend the regular machine resource, or be its own standalone resource?
  • I propose we use the AWS SDK V2 because it has built in waiters for this
  • What happens if a spot instance disappears? Can you get outbid on them and then have it taken away?

:destroy does not remove local client and node data

first successful converge (create and destroy)

  * machine[aws-driver] action converge
    - Creating aws-driver with AMI ami-f1ce8bc1 in us-west-2...
    - Created i-196dbb13 in us-west-2...
    - update node aws-driver at http://localhost:8889
    -   update normal.metal.location.allocated_at from "2014-10-29 02:41:20 UTC" to "2014-10-29 14:26:32 UTC"
    -   update normal.metal.location.instance_id from "i-fa8751f0" to "i-196dbb13"
    - Starting aws-driver (i-196dbb13) in us-west-2...
    - waiting for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 0/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 10/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - aws-driver is now ready
    - waiting for aws-driver (i-196dbb13 on aws:aws) to be connectable (transport up and running) ...
    - been waiting 0/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be connectable ...
    - been waiting 10/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be connectable ...
    - been waiting 20/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be connectable ...
    - aws-driver is now connectable[2014-10-29T07:28:03-07:00] ERROR: Unable to download /etc/chef/client.pem to #<StringIO:0x007ff52906bfa0> on [email protected] -- Error: command 'cp /etc/chef/client.pem /tmp/client.pem.2205673337' exited with code 1.

[2014-10-29T07:28:03-07:00] WARN: Unable to clean up /tmp/client.pem.2205673337 on [email protected] -- Error: command 'rm /tmp/client.pem.2205673337' exited with code 1.


    - generate private key (2048 bits)
    - create directory /etc/chef on aws-driver
    - write file /etc/chef/client.pem on aws-driver
    - update client aws-driver at clients
    -   update public_key from "-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----\n"
    - write file /etc/chef/client.rb on aws-driver
    - write file /tmp/chef-install.sh on aws-driver
    - run 'bash -c ' bash /tmp/chef-install.sh'' on aws-driver
    [aws-driver] Starting Chef Client, version 11.16.4
                 resolving cookbooks for run list: []
                 Synchronizing Cookbooks:
                 Compiling Cookbooks...
                 [2014-10-29T14:28:34+00:00] WARN: Node aws-driver has an empty run list.
                 Converging 0 resources

                 Running handlers:
                 Running handlers complete
                 Chef Client finished, 0/0 resources updated in 3.996096093 seconds
    - run 'chef-client -l auto' on aws-driver
  * machine[aws-driver] action destroy (up to date)
[2014-10-29T07:28:35-07:00] WARN: Skipping final node save because override_runlist was given

Running handlers:
Running handlers complete
Chef Client finished, 1/2 resources updated in 127.596084 seconds

failed second attempt

  * machine[aws-driver] action converge
    - Starting aws-driver (i-196dbb13) in us-west-2...
    - waiting for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 0/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 10/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 20/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 30/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 40/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 50/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 60/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 70/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 80/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 90/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 100/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - been waiting 110/120 -- sleeping 10 seconds for aws-driver (i-196dbb13 on aws:aws) to be ready ...
    - aws-driver is now ready[2014-10-29T07:39:48-07:00] WARN: Server aws-driver has no public ip address.  Using private ip ''.  Set driver option 'use_private_ip_for_ssh' => true if this will always be the case ...

    ================================================================================
    Error executing action `converge` on resource 'machine[aws-driver]'
    ================================================================================

    TypeError
    ---------
    no implicit conversion of nil into String

    Resource Declaration:
    ---------------------
    # In /Users/patrickwright/Chef/github/patrick-wright/chef-metal-test-suite/.chef/local-mode-cache/cache/cookbooks/dont-get-cute/recipes/aws.rb

      7: machine machine_name do
      8:   machine_options :bootstrap_options => {
      9:           :key_name => 'metal_default'
     10:     }
     11: end
     12:

    Compiled Resource:
    ------------------
    # Declared in /Users/patrickwright/Chef/github/patrick-wright/chef-metal-test-suite/.chef/local-mode-cache/cache/cookbooks/dont-get-cute/recipes/aws.rb:7:in `from_file'

    machine("aws-driver") do
      action :converge
      retries 0
      retry_delay 2
      guard_interpreter :default
      chef_server {:chef_server_url=>"http://localhost:8889", :options=>{:client_name=>"remwright01", :signing_key_filename=>nil}}
      driver "aws"
      machine_options {:bootstrap_options=>{:key_name=>"metal_default"}}
      cookbook_name "dont-get-cute"
      recipe_name "aws"
    end


Running handlers:
[2014-10-29T07:39:48-07:00] ERROR: Running exception handlers
Running handlers complete
[2014-10-29T07:39:48-07:00] ERROR: Exception handlers complete
[2014-10-29T07:39:48-07:00] FATAL: Stacktrace dumped to /Users/patrickwright/Chef/github/patrick-wright/chef-metal-test-suite/.chef/local-mode-cache/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 130.409134 seconds
[2014-10-29T07:39:48-07:00] ERROR: machine[aws-driver] (dont-get-cute::aws line 7) had an error: TypeError: no implicit conversion of nil into String
[2014-10-29T07:39:48-07:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

Fails after :ready timeout. Since the local client and node data exist after the initial destroy the driver seems to think the instance is ready, and times outs and raises a confusing TypeError exception.

When I manually delete the node and client json files and run again all is well.

Delete action for aws_vpc doesnt work

I run this, to create the VPC:

with_data_center 'us-west-2' do
aws_vpc "provisioning-vpc" do
cidr_block "10.0.1.0/24"
end

Followed by a second recipe, to delete it:

aws_vpc "provisioning-vpc" do
action :delete
end

The delete recipe just deletes the data bag, not the VPC.

Creation of aws_security_group fails if run from multiple machines [local mode]

I have some code that looks like this:

require 'chef/provisioning/aws_driver'
with_driver 'aws'

# declare two security groups - one that provides inbound access on port 22 (SSH) and another that provides inbound access on port 80 (HTTP)
aws_security_group 'webserver-ssh' do
  inbound_rules [
    {:ports => 22, :protocol => :tcp, :sources => ['0.0.0.0/0'] }
  ]
end
aws_security_group 'webserver-http' do
  inbound_rules [
    {:ports => 80, :protocol => :tcp, :sources => ['0.0.0.0/0'] }
  ]
end

When I run it, it works as expected. The security groups get made.

But, when I run it from another machine, it fails like this:

Starting Chef Client, version 11.18.0.rc.1
resolving cookbooks for run list: ["web::servers"]
Synchronizing Cookbooks:
  - web
Compiling Cookbooks...
WARN: Unresolved specs during Gem::Specification.reset:
      nokogiri (>= 1.4.0, >= 1.4.4, ~> 1.5)
WARN: Clearing out unresolved specs.
Please report a bug if this causes problems.
Converging 3 resources
Recipe: web::servers
  * aws_security_group[webserver-ssh] action create

    ================================================================================
    Error executing action `create` on resource 'aws_security_group[webserver-ssh]'
    ================================================================================

    AWS::EC2::Errors::InvalidGroup::Duplicate
    -----------------------------------------
    The security group 'webserver-ssh' already exists for VPC 'vpc-3b678f5e'

    Resource Declaration:
    ---------------------
    # In /home/thomaspetchel/.chef/local-mode-cache/cache/cookbooks/web/recipes/servers.rb

      5: aws_security_group 'webserver-ssh' do
      6:   inbound_rules [
      7:     {:ports => 22, :protocol => :tcp, :sources => ['0.0.0.0/0'] }
      8:   ]
      9: end
     10: aws_security_group 'webserver-http' do

    Compiled Resource:
    ------------------
    # Declared in /home/thomaspetchel/.chef/local-mode-cache/cache/cookbooks/web/recipes/servers.rb:5:in `from_file'

    aws_security_group("webserver-ssh") do
      action :create
      retries 0
      retry_delay 2
      guard_interpreter :default
      cookbook_name "web"
      recipe_name "servers"
      inbound_rules [{:ports=>22, :protocol=>:tcp, :sources=>["0.0.0.0/0"]}]
    end


Running handlers:
[2014-12-16T13:12:23-08:00] ERROR: Running exception handlers
Running handlers complete
[2014-12-16T13:12:23-08:00] ERROR: Exception handlers complete
[2014-12-16T13:12:23-08:00] FATAL: Stacktrace dumped to /home/thomaspetchel/.chef/local-mode-cache/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 3.036997802 seconds
[2014-12-16T13:12:23-08:00] ERROR: aws_security_group[webserver-ssh] (web::servers line 5) had an error: AWS::EC2::Errors::InvalidGroup::Duplicate: The security group 'webserver-ssh' already exists for VPC 'vpc-3b678f5e'
[2014-12-16T13:12:23-08:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

(You can also repo this by simply renaming data_bags/aws_security_groups)

This is presumably because the second machine doesn't have the security groups' metadata written as part of the data bag.

I would have expected provisioning to see that the security group already existed on AWS and thus just fill in the local data bags.

I'm working in local mode in my scenario. In a scenario that uses Chef server, the data bag would exist there and therefore be available to multiple clients. So if the fact I'm working in local mode invalidates the scenario, feel free to punt this. Just wanted to highlight the use case.

Security Groups

Can an option be added to remove any entries in the security ingress/egress that are not in the chef run? Meaning if someone were to manually add a rule to security group, it appears the current implementation leaves this rule in place.

bootstrap_options need to be clarified

Following up on #46:

The bootstrap_options for this driver need documenting as that can are quite different to the documentation of the fog::AWS driver, with which they can be easily confused since there is no clear and complete separation between the two (doc named aws.md, and titled AWS provider with no mention of fog).

For instance:

  • the option :flavor_id in fog is called :instance_type here
  • the option :vpc_id does not exist here
  • the option :subnet_id in fog is called :subnet here
  • etc.

Am I wrong in thinking that this driver is being much close to the aws-sdk-v1?

If so can it be assumed that the aws-sdk-v1 documentation on the Class: AWS::EC2::InstanceCollection create method would give a reliable list of the options available?

Namely (copy/paste):

  • :count (Integer) โ€” How many instances to request. By default one instance is requested. You can specify this either as an integer or as a Range, to indicate the minimum and maximum number of instances to run. Note that for a new account you can request at most 20 instances at once.
  • :iam_instance_profile (String) โ€” The name or ARN of an IAM instance profile. This provides credentials to the EC2 instance(s) via the instance metadata service.
  • :block_device_mappings (Array) โ€” Specifies how block devices are exposed to the instance. Each mapping is made up of a virtualName and a deviceName.
    • :virtual_name - (String) Specifies the virtual device name.
    • :device_name - (String) Specifies the device name (e.g., /dev/sdh).
    • :ebs - (Hash) Specifies parameters used to automatically setup Amazon EBS volumes when the instance is launched.
      • :snapshot_id - (String) The ID of the snapshot from which the volume will be created.
      • :volume_size - (Integer) The size of the volume, in gigabytes.
      • :delete_on_termination - (Boolean) Specifies whether the Amazon EBS volume is deleted on instance termination.
      • :volume_type - (String) Valid values include:
        • standard
        • io1
        • gp2
      • :iops - (Integer)
    • :no_device - (String) Specifies the device name to suppress during instance launch.
  • :monitoring_enabled (Boolean) โ€” Setting this to true enables CloudWatch monitoring on the instances once they are started.
  • :availability_zone (String) โ€” Specifies the availability zone where the instance should run. Without this option, EC2 will choose an availability zone for you.
  • :placement_group (String) โ€” Specifies the cluster placement group where the instance should run.
  • :image_id (String) โ€” ID of the AMI you want to launch.
  • :key_name (String) โ€” The name of the key pair to use. Note: Launching public images without a key pair ID will leave them inaccessible.
  • :key_pair (KeyPair) โ€” A KeyPair that should be used when launching an instance.
  • :security_groups (Array) โ€” Security groups are used to determine network access rules for the instances. :security_groups can be a single value or an array of values. Values should be group name strings or SecurityGroup objects.
  • :security_group_ids (Array) โ€” Security groups are used to determine network access rules for the instances. :security_group_ids accepts a single ID or an array of security group IDs.
  • :user_data (String) โ€” Arbitrary user data. You do not need to encode this value.
  • :instance_type (String) โ€” The type of instance to launch, for example "m1.small".
  • :kernel_id (String) โ€” The ID of the kernel with which to launch the instance.
  • :ramdisk_id (String) โ€” The ID of the RAM disk to select. Some kernels require additional drivers at launch. Check the kernel requirements for information on whether you need to specify a RAM disk. To find kernel requirements, refer to the Resource Center and search for the kernel ID.
  • :disable_api_termination (Boolean) โ€” Specifies whether you can terminate the instance using the EC2 API. A value of true means you can't terminate the instance using the API (i.e., the instance is "locked"); a value of false means you can. If you set this to true, and you later want to terminate the instance, you must first enable API termination. For example:
i = ec2.instances.create(:image_id => "ami-8c1fece5",
                         :disable_api_termination => true)
i.api_termination_disabled?        # => true
i.terminate                        # raises an exception
i.api_termination_disabled = false
i.terminate                        # terminates the instance
  • :instance_initiated_shutdown_behavior (String) โ€” Determines whether the instance stops or terminates on instance-initiated shutdown.
  • :subnet (Subnet, String) โ€” default: nil โ€” The VPC Subnet (or subnet id string) to launch the instance in.
  • :private_ip_address (String) โ€” default: nil โ€” If you're using VPC, you can optionally use this option to assign the instance a specific available IP address from the subnet (e.g., '10.0.0.25'). This option is not valid for instances launched outside a VPC (i.e. those launched without the :subnet option).
  • :dedicated_tenancy (Boolean) โ€” default: false โ€” Instances with dedicated tenancy will not share physical hardware with instances outside their VPC. NOTE: Dedicated tenancy incurs an additional service charge. This option is not valid for instances launched outside a VPC (e.g. those launched without the :subnet option).
  • :ebs_optimized (Boolean) โ€” default: false โ€” EBS-Optimized instances enable Amazon EC2 instances to fully utilize the IOPS provisioned on an EBS volume. EBS-optimized instances deliver dedicated throughput between Amazon EC2 and Amazon EBS, with options between 500 Mbps and 1000 Mbps depending on the instance type used. When attached to EBS-Optimized instances, Provisioned IOPS volumes are designed to deliver within 10% of their provisioned performance 99.9% of the time. NOTE: EBS Optimized instances incur an additional service charge. This optional is only valid for certain instance types.
  • :associate_public_ip_address (Boolean) โ€” default: false

Error on destroying a loadbalancer

With 0.2.1, I create a load balancer:

load_balancer "webapp-elb" do
load_balancer_options :availability_zones => ['us-west-1b'],
:listeners => [{
:port => 80,
:protocol => :http,
:instance_port => 80,
:instance_protocol => :http
},
{
:port => 3301,
:protocol => :tcp,
:instance_port => 3301,
:instance_protocol => :tcp
}
]
machines [ 'bowser' ]
end

When I try to destroy it with:

load_balancer "webapp-elb" do
action :destroy
end

It deletes the load balancer but fails with an error message:

Recipe: @recipe_files::/home/christine/test/provision/scripts/elb_destroy.rb
  * load_balancer[webapp-elb] action destroy[2015-02-02T17:51:30-06:00] INFO: Processing load_balancer[webapp-elb] action destroy (@recipe_files::/home/christine/test/provision/scripts/elb_destroy.rb line 5)

    - Deleting EC2 ELB http://localhost:8889/data/loadbalancers/webapp-elb
    ================================================================================
    Error executing action `destroy` on resource 'load_balancer[webapp-elb]'
    ================================================================================

    Chef::Exceptions::ValidationFailed
    ----------------------------------
    Option action must be equal to one of: nothing, create, delete, nothing!  You passed :destroy.

What are the sane defaults for complete and converge in the machine resource?

In my scenario, I need to supply values for complete and converge in my machine resources, like this:

machine webserver_name do
    recipe 'web::apache2'
    complete true
    converge true
    tag 'webserver'
    subscribes :converge, 'load_balancer[webserver-lb]'
  end

My only feedback/question is whether true could be the sane default so I don't have to supply it.

Add security_group_names to bootstrap_options

I want to create a security group and associate it with my machine.

Currently, we only have security_group_ids in bootstrap options. To get the id, you need to read from a data bag. That data bag is created during the execution phase, so you need to evaluate is lazily.

Providing security_group_names in bootstrap options would alleviate the pain.

So instead of this:

require 'chef/provisioning/aws_driver'
with_driver 'aws'

aws_security_group 'webserver-ssh' do
  inbound_rules [
    {:ports => 22, :protocol => :tcp, :sources => ['0.0.0.0/0'] }
  ]
end
aws_security_group 'webserver-http' do
  inbound_rules [
    {:ports => 80, :protocol => :tcp, :sources => ['0.0.0.0/0'] }
  ]
end

machine 'webserver-1' do
  machine_options lazy { ({
    :bootstrap_options => {
      :instance_type => 't1.micro',
      :security_group_ids => [
        data_bag_item('aws_security_groups', 'webserver-ssh')['security_group_id'],
        data_bag_item('aws_security_groups', 'webserver-http')['security_group_id']
      ]
    },
    :ssh_username => 'root',
    :image_id => 'ami-b6bdde86'
  }) }

  recipe 'web'
  tag 'webserver'
  converge true
end

Iโ€™d like to do this:

require 'chef/provisioning/aws_driver'
with_driver 'aws'

aws_security_group 'webserver-ssh' do
  inbound_rules [
    {:ports => 22, :protocol => :tcp, :sources => ['0.0.0.0/0'] }
  ]
end
aws_security_group 'webserver-http' do
  inbound_rules [
    {:ports => 80, :protocol => :tcp, :sources => ['0.0.0.0/0'] }
  ]
end

with_machine_options({
    :bootstrap_options => {
      :instance_type => 't1.micro',
      :security_group_names => ['webserver-ssh','webserver-http']
    },
    :ssh_username => 'root',
    :image_id => 'ami-b6bdde86'
  })

machine 'webserver-1' do
  recipe 'web'
  tag 'webserver'
  converge true
end

Cleaner handling when trying :disassociate action on an already disassociated aws_eip_address

Running a :disassociate action on an already disassociated aws_eip_address brought the following error message:

  * aws_eip_address[esc-xebia-chef-server-ip] action disassociate[2014-12-26T15:00:01+01:00] FATAL: Error Disassociating EIP: expected string value for option association_id


    ================================================================================
    Error executing action `disassociate` on resource 'aws_eip_address[esc-xebia-chef-server-ip]'
    ================================================================================

    SystemExit
    ----------
    exit

    Resource Declaration:
    ---------------------
    # In /Users/emmanuelsciara/Documents/Development/git-repos/chef-cookbooks/xebia-chef-server/.chef/local-mode-cache/cache/cookbooks/xebia-chef-server/recipes/cp-destroy-n-clean-up.rb

     19: aws_eip_address "esc-xebia-chef-server-ip" do
     20:   action :disassociate
     21: end
     22:

    Compiled Resource:
    ------------------
    # Declared in /Users/emmanuelsciara/Documents/Development/git-repos/chef-cookbooks/xebia-chef-server/.chef/local-mode-cache/cache/cookbooks/xebia-chef-server/recipes/cp-destroy-n-clean-up.rb:19:in `from_file'

    aws_eip_address("esc-xebia-chef-server-ip") do
      action [:disassociate]
      retries 0
      retry_delay 2
      default_guard_interpreter :default
      id "esc-xebia-chef-server-ip"
      public_ip "54.77.227.78"
      declared_type :aws_eip_address
      cookbook_name "xebia-chef-server"
      recipe_name "cp-destroy-n-clean-up"
    end


Running handlers:
[2014-12-26T15:00:01+01:00] ERROR: Running exception handlers
Running handlers complete
[2014-12-26T15:00:01+01:00] ERROR: Exception handlers complete
[2014-12-26T15:00:01+01:00] FATAL: Stacktrace dumped to /Users/emmanuelsciara/Documents/Development/git-repos/chef-cookbooks/xebia-chef-server/.chef/local-mode-cache/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 5.205668 seconds
[2014-12-26T15:00:01+01:00] ERROR: aws_eip_address[esc-xebia-chef-server-ip] (xebia-chef-server::cp-destroy-n-clean-up line 19) had an error: SystemExit: exit
[2014-12-26T15:00:01+01:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

What about handling this more gracefully, either by always checking that eip is already dissociated, or by adding an option to raise either only a warning or a plain error when it is?

driver image methods are empty

Just leaving this here for tracking purposes. cc/ @jkeiser

The image methods used by the machine_image resources are implemented but empty:

    # Image methods
    def allocate_image(action_handler, image_spec, image_options, machine_spec)
    end

    def ready_image(action_handler, image_spec, image_options)
    end

    def destroy_image(action_handler, image_spec, image_options)
    end

This causes that a chef-client run using the machine_image resource with the aws driver not to produce the desired results but also not failing.

Multiple listeners defined in `load_balancer`

load_balancer_options :availability_zones => ['us-west-1c'],
                          :subnet => 'subnet-52fb453a',
                          :listeners => [{
                            :port => 80,
                            :protocol => :http,
                            :instance_port => 80,
                            :instance_protocol => :http
                            },
                            {
                            :port => 443,
                            :protocol => :https,
                            :instance_port => 443,
                            :instance_protocol => :https,
                            :instance_certificate => 'EV-Cert-2015'
                            }]

Gives me NameError: undefined local variable or method 'listener' for #<Chef::Provisioning::AWSDriver::Driver:0x007f854e60c888>

CloudFront Distribution Resource

As a Chef user, I would like to create and manage CloudFront distributions with Chef Provisioning. At a minimum, make it so I can create or update the SSL certificate for one (see #52.)

Error when converging cookbooks depending on 'aws' cookbook

Whenever a cookbook using the chef-provisioning-aws driver depends on the 'aws' cookbook, converging fails at cookbooks compilation time with the following error:

[..]
Compiling Cookbooks...

================================================================================
Recipe Compile Error in /path/to/your/cookbook/development/directory/.chef/local-mode-cache/cache/cookbooks/aws-bug-cookbook/recipes/default.rb
================================================================================

TypeError
---------
superclass mismatch for class AwsEbsVolume

Cookbook Trace:
---------------
  /path/to/your/cookbook/development/directory/.chef/local-mode-cache/cache/cookbooks/aws-bug-cookbook/recipes/default.rb:15:in `require'
  /path/to/your/cookbook/development/directory/.chef/local-mode-cache/cache/cookbooks/aws-bug-cookbook/recipes/default.rb:15:in `from_file'

Relevant File Content:
----------------------
/path/to/your/cookbook/development/directory/.chef/local-mode-cache/cache/cookbooks/aws-bug-cookbook/recipes/default.rb:

  8:  #
  9:  # Licensed under the Apache License, Version 2.0 (the "License");
 10:  # you may not use this file except in compliance with the License.
 11:  # You may obtain a copy of the License at
 12:  #
 13:  #     http://www.apache.org/licenses/LICENSE-2.0
 14:  
 15>> require 'chef/provisioning/aws_driver'
 16:  with_driver 'aws'
 17:  
[..]

Full instructions on https://gist.github.com/esciara/d0921bded64568dc6424

This stops me completly from deploying cookbooks such as https://github.com/bflad/chef-confluence .

Provisioning only creates t1.micros

I specified an m3.medium in my config, and chef provisioning reports back that is what it's creating:

    - creating machine backend1.example.local on fog:AWS:410980185594:us-west-2
    -   availability_zone: "us-west-2a"
    -   instance_type: "m3.medium"
    -   subnet_id: "subnet-4d70cd28"
    -   security_group_ids: ["sg-7dabec18", "sg-59b6f13c"]
    -   image_id: "ami-b6bdde86"
    -   private_ip_address: "172.25.10.98"
    -   key_name: "scarolan_chef"

But when I go into the AWS GUI to look at it, I'm stuck with t1.micro every time

machine provisioning doesn't work for windows target

I am quite sure this worked before, but after updating to the latest version, provisioning a windows machine does not use winRM anymore. Here's a sample resource which basically hangs on trying to connect, as it's trying to use SSH instead of winRM:

windows_ami = 'ami-e99c1d9e'
machine "MyMachine" do
    machine_options ({
        :image_id => windows_ami,
        :is_windows => true,
        :bootstrap_options => {
            # some stuff here
        },
    })

    role 'WebServer'
end

I think I've traced it back to this line: https://github.com/chef/chef-provisioning-aws/blob/master/lib/chef/provisioning/aws_driver/driver.rb#L370

This was added quite recently (about a week ago), and if we then jump to line 448 it's quite obvious that winRM is not implemented there ;-) However, the next statement, machine_for, DOES implement winRM as a transport, see line 370.

I can take a stab at fixing it, but do I need to sign a CLA for chef-provisioning for that, just like for the main chef-codebase? If so, I'll need to get that arranged on my side.

-- edit --

On further inspection I have no clue what happened, it's clear that it doesn't work though ;-) Will continue investigating. On second thought, I used the fog:aws one before, so maybe I am confusing things. Either way, the aws_driver.rb file seems to be a bit messy.

Provide sane default load_balancer_options[:listeners]

Currently, I have to do this:

load_balancer 'webserver-lb' do
  load_balancer_options :listeners => [{
      :port => 80,
      :protocol => :http,
      :instance_port => 80,
      :instance_protocol => :http
    }],
  machines webservers
end

It would be great if I could do just this to get some sane defaults (HTTP):

load_balancer 'webserver-lb' do
  machines webservers
end

If I don't provide :listeners I get an error

  * load_balancer[webserver-lb] action create
    - Checking for ELB named webserver-lb...
    ================================================================================
    Error executing action `create` on resource 'load_balancer[webserver-lb]'
    ================================================================================

    AWS::Core::OptionGrammar::FormatError
    -------------------------------------
    expected enumerable value for option listeners

    Resource Declaration:
    ---------------------
    # In /home/thomaspetchel/.chef/local-mode-cache/cache/cookbooks/web/recipes/cluster.rb

Should you get t1.micro instances by default?

By default, a machine resource gives you an Ubuntu ami-f1ce8bc1 m1.small instance. Would it be better to make this a t1.micro, so folks can take advantange of free tier usage?

If the user is using the default, she may likely be just experimenting with gettings things off the ground, and may not benefit from an m1.small, and may not want to spend the extra money on it.

Ugly output message during machine resource convergence

  • It appears that this message is missing a few words (between 'username' and 'and' in "with SSH username and machine_options" and also "Using .")
  • I'm not sure what the actual problem is that this is describing.
  • It would be difficult for most users (IMO) to know what it means to change chef_provisioning.location.ssh_username.
* machine[webserver-1] action converge[2014-12-16T15:57:53-08:00] WARN: Server webserver-1 was 
created with SSH username  and machine_options specifies username root.  Using .  Please edit the 
node and change the chef_provisioning.location.ssh_username attribute if you want to change it.

Load balancer convergence not based on reality

Load balancers are comparing the desired state against the previous desired state (which was stuffed in the data bag). They should compare against reality, by looking at the real load balancer data in the api. And they should not store the desired state in the data bag--it can only confuse people, desired state is ephemeral and no longer valid after the recipe is done.

There is the related issue that when you store the symbol keys in the data bag, they are stored as strings, so when they come back out the comparison is not correct anyway.

instance created when key name is not configured

We need to decide what happens when a key name is not provided.

Currently, the instance will be created, and then the converge will fail due to the key name not being set. This leaves the instance in limbo.

Do we want this to happen?
If yes, we need some way to failing gracefully and informing the user the the instance has been created.
If no, we should abort the instance launch when a key is not set

bootstrap tagging options

this driver needs to the ability to tag ec2 instances. fog adds a few default tags, perhaps we should do that too

Default load_balancer security group not working

When I omit :security_group_id from load_balancer_options, like this:

load_balancer 'webserver-lb' do
  load_balancer_options :availability_zones => ['us-west-2a'],
    :listeners => [{
      :port => 80,
      :protocol => :http,
      :instance_port => 80,
      :instance_protocol => :http
    }],
  machines webservers
end

I get an error:

[2014-11-07T11:45:07-08:00] ERROR: load_balancer[webserver-lb] (web::cluster line 26) had an error: AWS::ELB::Errors::InvalidConfigurationRequest: Security group "sg-423f9027" does not belong to VPC "vpc-3b678f5e"

I needed to create a SG in that VPC and supply it to the recipe to make things work, like this:

load_balancer 'webserver-lb' do
  load_balancer_options :availability_zones => ['us-west-2a'],
    :listeners => [{
      :port => 80,
      :protocol => :http,
      :instance_port => 80,
      :instance_protocol => :http
    }],
    :security_group_id => 'sg-75056b10'
  machines webservers
end

:destroy action on load_balancer is a noop

When I run this recipe:

require 'chef/provisioning'
with_driver 'aws'

load_balancer 'webserver-lb' do
  action :destroy
end

I don't see any change to the LB on EC2. I get this output:

 * load_balancer[webserver-lb] action destroy (up to date)

data_bags/loadbalancers/webserver-lb.json is also left around.

load_balancer doesn't add machines on create

You have to run the recipe multiple times to get the machines added--first time to create the LB, second time to add the machines to it.

  load_balancer "metaldemo-elb" do
    load_balancer_options :availability_zones => ['us-east-1a', 'us-east-1c', 'us-east-1d'],
                          :listeners => [{
                               :port => 80,
                               :protocol => :http,
                               :instance_port => 8080,
                               :instance_protocol => :http,
                           }]
    machines machine_names
  end

aws_security_group doesn't show (up to date) message

Converge an aws_security_group resource multiple times. You'll see something like the following, but not with the "(up to date)" message that's typical of most other resource types.

Recipe: web::servers
  * aws_security_group[webserver-ssh] action create

EC2 node attributes not available through ohai

After spinning up a machine resource on EC2, I'd like to grab its public IP address. When I run this command:

knife node show --local-mode --attribute ec2.public_ipv4 webserver-1

I get the empty string in the response:

WARNING: No knife configuration file found
webserver-1:
  ec2.public_ipv4: 

The same goes when I try to retrieve this attribute through code (e.g. a Chef template.)

implement connect_to_machine

This is preventing some core chef-provisioning resources from functioning (machine_execute for example)

The chef-provisioning-test-suite depends on the core functionality

Can't update a machine's security group after it's created

You specify a machine resources's security group through bootstrap options. For example:

with_machine_options :bootstrap_options => {
    :security_group_ids => ['sg-12345678']
  }

machine 'webserver-1'

That sets the initial SG, but you can't use Chef to reassign the SG later.

One use case is that you would use an initial one to enable the server to set itself up (e.g. download software, etc.) and later switch over to one that is more locked down.

One option might be to enable placement of the security_group_ids field on the machine resource itself, and then inject this value into the bootstrap_options. If you specify it in both places, I'm not sure what the best behavior should be (have machine overwrite, take union, intersection, etc.)

This issue could be generalized to other things that you may want to change later (none come to mind at the moment.)

No resource, method, or local variable named `existing_vpc' when delete security group

When I try to delete a security group:

aws_security_group "provisioning-vpc-security-group" do
action :delete
end

I get:

ERROR: aws_security_group[provisioning-vpc-security-group](@recipe_files::/home/christine/test/provision/network_aws_delete.rb line 10) had an error: NameError: No resource, method, or local variable named existing_vpc' forChef::Provider::AwsSecurityGroup ""'

I think that 'existing_vpc' should be 'existing_sg' here:
https://github.com/chef/chef-provisioning-aws/blob/master/lib/chef/provider/aws_security_group.rb#L35

Route53 RecordSets Resource needed

Provisioning machines and being able to register DNS recordsets for either internal or external Route 53 Hosted Zones is a logical requirement.

I especially need this for internal entries, which is why I'm going to make it a priority.

Thoughts on using aws-sdk-core (Version 2 of the sdk)?

Since you are just starting this project, did you consider using the aws-sdk-core, ie Version 2 of the AWS-SDK? It just had its production release last week (now up to 2.0.1)

It has some nice features. Most importantly a "waiter" mechanism that finally deals with the issue that you need to wait for things a lot of the time (images to be created, instances to come up, policies to be instantiated, etc). Now you can do it without manually polling or sleeps.

Also new (but in pre-release) is a much more ruby way of dealing with resources
http://ruby.awsblog.com/post/Tx1TLKAM6WR3E8H/Version-2-Resource-Interfaces

AWS Profile not honored for aws_vpc (and possibly others)

I created an AWS .credentials file with two profiles, one has authority to create VPCs, one didn't.

I tried various ways to set the profile, including with_driver 'aws:test1' and setting CHEF_DRIVER. In all cases, it ignored the specified profile and used the default one.

The same driver URL worked to set the profile for the machine resource.

When I set a breakpoint in AwsDriver.initialize, it appear not even to be called in the case of aws_vpc, although it is for machine.

I am using chef-provisioning-aws 0.2.1 and chef-provisioning 0.17

machine_file resource not working as the connect_to_machine method is not implemented

When trying the following:

%w{ chef-validator.pem admin.pem}.each do |opscode_file|
  machine_file "/etc/chef-server/#{opscode_file}" do
    local_path "/tmp/#{opscode_file}"
    machine "my-test-machine"
    action :download
  end
end

the following error is thrown:

 * machine_file[/etc/opscode/chef-validator.pem] action download

    ================================================================================
    Error executing action `download` on resource 'machine_file[/etc/opscode/chef-validator.pem]'
    ================================================================================

    RuntimeError
    ------------
    Chef::Provisioning::AWSDriver::Driver does not implement connect_to_machine

    Resource Declaration:
    ---------------------
    # In /Users/emmanuelsciara/Documents/Development/git-repos/chef-cookbooks/xebia-chef-server/.chef/local-mode-cache/cache/cookbooks/xebia-chef-server/recipes/cp-xebia-chef-server.rb

     51:     machine_file "/etc/opscode/#{opscode_file}" do
     52:       local_path "#{opscode_file}"
     53:       machine node['xebia-chef-server']['server']['name']
     54:       action :download
     55:     end
     56:

    Compiled Resource:
    ------------------
    # Declared in /Users/emmanuelsciara/Documents/Development/git-repos/chef-cookbooks/xebia-chef-server/.chef/local-mode-cache/cache/cookbooks/xebia-chef-server/recipes/cp-xebia-chef-server.rb:51:in `block (2 levels) in from_file'

    machine_file("/etc/opscode/chef-validator.pem") do
      action [:download]
      retries 0
      retry_delay 2
      default_guard_interpreter :default
      chef_server {:chef_server_url=>"http://127.0.0.1:8889", :options=>{:client_name=>"Ems-MacBook-Pro.local", :signing_key_filename=>nil}}
      declared_type :machine_file
      cookbook_name "xebia-chef-server"
      recipe_name "cp-xebia-chef-server"
      local_path "chef-validator.pem"
      machine "esc-provisioned-chef-server"
    end


Running handlers:
[2014-12-26T17:39:11+01:00] ERROR: Running exception handlers
Running handlers complete
[2014-12-26T17:39:11+01:00] ERROR: Exception handlers complete
[2014-12-26T17:39:11+01:00] FATAL: Stacktrace dumped to /Users/emmanuelsciara/Documents/Development/git-repos/chef-cookbooks/xebia-chef-server/.chef/local-mode-cache/cache/chef-stacktrace.out
Chef Client failed. 2 resources updated in 22.918384 seconds
[2014-12-26T17:39:11+01:00] ERROR: machine_file[/etc/opscode/chef-validator.pem] (xebia-chef-server::cp-xebia-chef-server line 51) had an error: RuntimeError: Chef::Provisioning::AWSDriver::Driver does not implement connect_to_machine
[2014-12-26T17:39:11+01:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

When looking at today's lib/chef/provisioning/aws_driver/driver.rb file, the connect_to_machine method is indeed not implemented. Looking at the current driver.rb file of the chef-provisioning-fog driver, which is working fine, here is the implementation of the offending method:

    # Connect to machine without acquiring it
    def connect_to_machine(machine_spec, machine_options)
      machine_for(machine_spec, machine_options)
    end

Would do it myself and submit a PR, but I got to dash and I have not setup up a dev env for this yet. Anyone is a taker?

machine resource not idempotent

If you run the recipe a second time without changing it, the machine resource still reconverges and marks the resource as "updated." It should emit no green text, should not converge, and should not mark the resource as "updated."

Default key doesn't work when creating machine resource

Perhaps it's something with my local setup, but when I run this basic recipe (running chef-client in local mode)

require 'chef/provisioning'
with_driver 'aws'
machine 'pikachu'

I get this error:

No key found to connect to pikachu

Full output:

[2014-11-24T11:34:29-08:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 11.16.4
resolving cookbooks for run list: ["web::servers"]
Synchronizing Cookbooks:
  - web
Compiling Cookbooks...
Converging 4 resources
Recipe: web::servers
  * machine[pikachu] action converge
    - Creating pikachu with AMI ami-f1ce8bc1 in us-west-2...
    - Created i-42abb5b6 in us-west-2...
    - create node pikachu at http://localhost:8889
    -   add normal.tags = nil
    -   add normal.chef_provisioning = {"location"=>{"driver_url"=>"aws:aws", "driver_version"=>"0.1.1", "allocated_at"=>"2014-11-24 19:34:31 UTC", "host_node"=>"http://localhost:8889/nodes/", "image_id"=>nil, "instance_id"=>"i-42abb5b6"}}
    - Starting pikachu (i-42abb5b6) in us-west-2...
    - waiting for pikachu (i-42abb5b6 on aws:aws) to be ready ...
    - been waiting 0/120 -- sleeping 10 seconds for pikachu (i-42abb5b6 on aws:aws) to be ready ...
    - been waiting 10/120 -- sleeping 10 seconds for pikachu (i-42abb5b6 on aws:aws) to be ready ...
    - pikachu is now ready
    ================================================================================
    Error executing action `converge` on resource 'machine[pikachu]'
    ================================================================================

    RuntimeError
    ------------
    No key found to connect to pikachu ({"driver_url"=>"aws:aws", "driver_version"=>"0.1.1", "allocated_at"=>"2014-11-24 19:34:31 UTC", "host_node"=>"http://localhost:8889/nodes/", "image_id"=>nil, "instance_id"=>"i-42abb5b6"})!

    Resource Declaration:
    ---------------------
    # In /home/thomaspetchel/.chef/local-mode-cache/cache/cookbooks/web/recipes/servers.rb

      9: machine 'pikachu'
     10: 

    Compiled Resource:
    ------------------
    # Declared in /home/thomaspetchel/.chef/local-mode-cache/cache/cookbooks/web/recipes/servers.rb:9:in `from_file'

    machine("pikachu") do
      action :converge
      retries 0
      retry_delay 2
      guard_interpreter :default
      chef_server {:chef_server_url=>"http://localhost:8889", :options=>{:client_name=>"ubuntu", :signing_key_filename=>nil}}
      driver "aws"
      cookbook_name "web"
      recipe_name "servers"
    end


Running handlers:
[2014-11-24T11:34:54-08:00] ERROR: Running exception handlers
Running handlers complete
[2014-11-24T11:34:54-08:00] ERROR: Exception handlers complete
[2014-11-24T11:34:54-08:00] FATAL: Stacktrace dumped to /home/thomaspetchel/.chef/local-mode-cache/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 24.666186112 seconds
[2014-11-24T11:34:54-08:00] ERROR: machine[pikachu] (web::servers line 9) had an error: RuntimeError: No key found to connect to pikachu ({"driver_url"=>"aws:aws", "driver_version"=>"0.1.1", "allocated_at"=>"2014-11-24 19:34:31 UTC", "host_node"=>"http://localhost:8889/nodes/", "image_id"=>nil, "instance_id"=>"i-42abb5b6"})!
[2014-11-24T11:34:54-08:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

I need to supply my own .pem file in order for things to work:

require 'chef/provisioning'
with_driver 'aws'

with_machine_options :bootstrap_options => {
  :key_name => "tpetchel"
}

machine 'pikachu'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.