# Chef-provisioning and multiple regions

**URL:** <https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036>\
**Category:** Chef Infra (archive)\
**Created:** [March 22, 2016, 3:07am UTC](https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036 "2016-03-22T03:07:56Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![fletchowns](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/fletchowns/32/53_2.png) [@fletchowns](https://discourse.chef.io/u/fletchowns)\
**Post date:** [March 22, 2016, 3:07am UTC](https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036/1 "2016-03-22T03:07:57Z")

</div>

I’m just getting started with chef-provisioning-aws and wasn’t sure how to handle the following:

1. Allocate an elastic IP in eu-central-1
2. Append that IP to a security group in us-west-1
3. Spin up a machine in eu-central-1 with that elastic IP associated to it

I think part of what I’m getting hung up on is how to share the value of that elastic IP between the two pieces of code that need it. Do I need to stick the IP address in a data bag and then reference that data bag?

The other part is how to associate the IP to the machine during initial provisioning, it seems like [the example](https://github.com/chef/chef-provisioning-aws/blob/master/docs/examples/eip.rb) associates the elastic IP _after_ initial provisioning. But in order for initial provisioning to succeed, I need it to already be added to the security group.

Something like:

```ruby
with_driver "aws::eu-central-1" do
    some_ip = aws_eip_address "some-machine-ip"
end

with_driver "aws::us-west-1" do
    aws_security_group "some-group" do
    vpc "some-vpc"
    inbound_rules ({
        "how should I reference some_ip.aws_object.public_ip here?" => [443]
    })
end

with_driver "aws::eu-central-1" do
    machine "some-machine" do
        role "my_role"
        chef_environment "prod"
        # how do i specify the elastic IP to use here?
    end
end

```

---

<div class="post-metadata">

**Author:** ![Christine\_Draper](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/christine_draper/32/68_2.png) [@Christine\_Draper](https://discourse.chef.io/u/Christine_Draper)\
**Post date:** [March 22, 2016, 3:49pm UTC](https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036/2 "2016-03-22T15:49:30Z")

</div>

For your second question, one approach would be to bring the machine up but not converge it (either :ready or :setup actions), associate the elastic IP address, then converge it.

For the first question, perhaps something like this (not tested):  
aws\_security\_group “some-group” do  
vpc "some-vpc"  
inbound\_rules lazy { “#{some\_ip.aws\_object.public\_ip}/32” =\> [443] }  
end

If you need to pass information between recipes, then you might need to use [run\_state](https://docs.chef.io/recipes.html#node-run-state) or [look up the resource as needed from the resource collection](https://docs.chef.io/dsl_recipe.html#resources).

---

<div class="post-metadata">

**Author:** ![Eulipion](https://avatars.discourse-cdn.com/v4/letter/e/7c8e57/32.png) [@Eulipion](https://discourse.chef.io/u/Eulipion)\
**Post date:** [March 22, 2016, 5:04pm UTC](https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036/3 "2016-03-22T17:04:27Z")

</div>

1. Allocate an elastic IP in eu-central-1  
You really want to have a VPC with a private and public subnet. set everything in that public subnet to get an EIP automatically.  
`public_subnet = aws_subnet "eu-west-1-public" do vpc 'vpc-eu-west' cidr_block "10.0.0.0/23" availability_zone "eu-west-1a" map_public_ip_on_launch true end`
2. Append that IP to a security group in us-west-1  
You can just search for it like a normal chef node  
`webserver = search(:node, "name:eu-west-1d-webserver101").first webserver_ipaddress = webserver['ec2']['public_ipv4']`
3. Spin up a machine in eu-central-1 with that elastic IP associated to it  
repeat step 1

---

<div class="post-metadata">

**Author:** ![fletchowns](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/fletchowns/32/53_2.png) [@fletchowns](https://discourse.chef.io/u/fletchowns)\
**Post date:** [March 22, 2016, 11:12pm UTC](https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036/4 "2016-03-22T23:12:32Z")

</div>

Thanks for the feedback! After trying a bunch of different options and bugging some helpful folks on gitter, here’s what I ended up with:

```auto
# keep track of eips for later
eip_by_machine = {}
with_driver "aws::eu-central-1" do
    # get machine in ready state, don't converge yet though
    machine "some-machine" do
        action :setup
    end

    eip_by_machine["some-machine"] = aws_eip_address "some-machine" do
        machine "some-machine"
    end
end

with_driver "aws::us-west-1" do
    # now add the eips to the security group
    rules = {}
    eip_by_machine.each do |machine_name, eip|
        rules["#{eip.aws_object.public_ip}/32"] = [443]
    end
    aws_security_group "my_sg" do
        vpc "my_vpc"
        inbound_rules(lazy { rules })
    end
end

# now we can proceed with converge
with_driver "aws::eu-central-1" do
    machine "some-machine" do
        action :converge_only
    end
end

```

---

<div class="post-metadata">

**Author:** ![fletchowns](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/fletchowns/32/53_2.png) [@fletchowns](https://discourse.chef.io/u/fletchowns)\
**Post date:** [March 23, 2016, 1:07am UTC](https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036/5 "2016-03-23T01:07:13Z")

</div>

Maybe I spoke too soon. After adding “some-other-machine” to this provisioning script, it’s bailing out during compile phase with:

```auto
INFO: HTTP Request Returned 404 Object Not Found: Cannot load data bag item some-other-machine for data bag aws_eip_address
...
ERROR: undefined method `public_ip' for nil:NilClass

```

Stack trace indicates it’s originating from the `rules["#{eip.aws_object.public_ip}/32"] = [443]` line.

---

<div class="post-metadata">

**Author:** ![dreamnite](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/dreamnite/32/1320_2.png) [@dreamnite](https://discourse.chef.io/u/dreamnite)\
**Post date:** [March 23, 2016, 3:56am UTC](https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036/6 "2016-03-23T03:56:07Z")

</div>

Could you provide a full example of how you added the second machine?

–Jp Robinson

---

<div class="post-metadata">

**Author:** ![fletchowns](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/fletchowns/32/53_2.png) [@fletchowns](https://discourse.chef.io/u/fletchowns)\
**Post date:** [March 23, 2016, 7:05am UTC](https://discourse.chef.io/t/chef-provisioning-and-multiple-regions/8036/7 "2016-03-23T07:05:53Z")

</div>

I think I’ve got it working now. Had to stick the eip\_by\_machine loop in a ruby block:

```ruby
with_driver "aws::us-west-1" do
    # now add the eips to the security group
    rules = {}
    ruby_block do
        block do
            eip_by_machine.each do |machine_name, eip|
                rules["#{eip.aws_object.public_ip}/32"] = [443]
            end
        end
    end
    aws_security_group "my_sg" do
        vpc "my_vpc"
        inbound_rules(lazy { rules })
    end
end

```
