AWS OpsWorks
User Guide (API Version 2013-02-18)

Using the SDK for Ruby on an AWS OpsWorks Stacks Windows Instance


This example assumes that you have already done the Running a Recipe on a Windows Instance example. If not, you should do that example first. In particular, it describes how to enable RDP access to your instances.

This topic describes how to use the AWS SDK for Ruby on an AWS OpsWorks Stacks Windows instance to download a file from an S3 bucket.

If a Ruby application needs to access an AWS resource, you must provide it with a set of AWS credentials with the appropriate permissions. For recipes, your best option for providing AWS credentials is to use an AWS Identity and Access Management (IAM) role. An IAM role works much like an IAM user; it has an attached policy that grants permissions to use the various AWS services. However, you assign a role to an Amazon Elastic Compute Cloud (Amazon EC2) instance instead of to an individual. Applications running on that instance can then acquire the permissions granted by the attached policy. With a role, credentials never appear in your code, even indirectly.

The first step is to set up the IAM role. This example takes the simplest approach, which is to use the Amazon EC2 role that AWS OpsWorks Stacks creates when you create your first stack. It is named aws-opsworks-ec2-role. However, AWS OpsWorks Stacks does not attach a policy to that role, so by default it grants no permissions. You must attach a policy that grants appropriate permissions to the role, in this case, read-only permissions for Amazon S3.

To attach a policy to a role

  1. Open the IAM console and choose Roles in the navigation pane.

  2. Choose aws-opsworks-ec2-role and, under Permissions, choose Attach Policy.

  3. Type S3 in the Policy Type search box to display the Amazon S3 policies. Choose AmazonS3ReadOnlyAccess and choose Attach Policy.

You specify the role when you create or update a stack. Set up a stack with a custom layer, as described in Running a Recipe on a Windows Instance, with one addition. On the Add Stack page, confirm that Default IAM instance profile is set to aws-opsworks-ec2-role. AWS OpsWorks Stacks will then assign that role to all of the stack's instances.

The procedure for setting up the cookbook is similar to the one used by Running a Recipe on a Linux Instance. The following is a brief summary; refer to that example for details.

To set up the cookbook

  1. Create a directory named s3bucket_ops and navigate to it.

  2. Create a metadata.rb file with the following content and save it to s3bucket_ops.

    name "s3download" version "0.1.0"
  3. Create a recipes directory within s3download.

  4. Create a default.rb file with the following recipe, and save it to the recipes directory. Replace windows-cookbooks with the name of the S3 bucket that you will use to store the file to be downloaded.

    Copy"******Downloading an object from S3******") chef_gem "aws-sdk" do compile_time false action :install end ruby_block "download-object" do block do require 'aws-sdk' Aws.config[:ssl_ca_bundle] = 'C:\ProgramData\Git\bin\curl-ca-bundle.crt' s3_client ='us-west-2') s3_client.get_object(bucket: 'windows-cookbooks', key: 'myfile.txt', response_target: '/chef/myfile.txt') end action :run end
  5. Create a .zip archive of s3download and upload the file to an S3 bucket. Make the file public and record the URL for later use. It should look something like For more information, see Cookbook Repositories.

  6. Create a text file named myfile.txt and upload it to an S3 bucket. This is the file that your recipe will download, so you can use any convenient bucket.

The recipe performs the following tasks.

1: Install the SDK for Ruby v2.

The example uses the SDK for Ruby to download the object. However, AWS OpsWorks Stacks does not install this SDK on Windows instances, so the first part of the recipe uses a chef_gem resource to handle that task. You use this resource to install gems for use by Chef, which includes recipes.

2: Specify a Certificate Bundle.

Amazon S3 uses SSL, so you need an appropriate certificate to download objects from an S3 bucket. The SDK for Ruby v2 does not include a certificate bundle, so you must provide one and configure the SDK for Ruby to use it. AWS OpsWorks Stacks does not install a certificate bundle directly, but it does install Git, which includes a certificate bundle (curl-ca-bundle.crt). For simplicity, this example configures the SDK for Ruby to use the Git certificate bundle, but you can also install your own and configure the SDK accordingly.

3: Download the file.

The third part of the recipe uses a ruby_block resource to run SDK for Ruby v2 code to download myfile.txt from an S3 bucket named windows-cookbooks to the instance's /chef directory. Change windows-cookbooks to the name of the bucket that contains myfile.txt.


A recipe is a Ruby application, so you can put Ruby code in the body of the recipe; it doesn't have to be in a ruby_block resource. However, Chef executes the Ruby code in the recipe's body first, followed by each resource, in order. For this example, if you put the download code in the recipe's body, it will fail because it depends on the SDK for Ruby, and the chef_gem resource that installs the SDK hasn't yet executed. The code in the ruby_block resource executes when the resource executes, and that happens after the chef_gem resource has installed the SDK for Ruby.

Create a stack for this example as follows. You can also use an existing Windows stack. Just update the cookbooks, as described later.

Create a stack

  1. Open the AWS OpsWorks Stacks console and choose Add Stack. Specify the following settings, accept the defaults for the other settings, and choose Add Stack.

    • Name – S3Download

    • Region – US West (Oregon)

      This example will work in any region, but we recommend using US West (Oregon) for tutorials.

    • Default operating system – Microsoft Windows Server 2012 R2

  2. Choose Add a layer and add a custom layer to the stack with the following settings.

    • Name – S3Download

    • Short name – s3download

  3. Add a 24/7 instance with default settings to the S3Download layer and start it.

You can now install and run the recipe

To run the recipe

  1. Edit the stack to enable custom cookbooks, and specify the following settings.

    • Repository typeS3 Archive.

    • Repository URL – The cookbook's archive URL that you recorded earlier.

    Accept the default values for the other settings and choose Save to update the stack configuration.

  2. Run the Update Custom Cookbooks stack command, which installs the latest version of your custom cookbook on the stack's online instances. If an earlier version of your cookbooks is present, this command overwrites it.

  3. Execute the recipe by running the Execute Recipes stack command with Recipes to execute set to s3download::default. This command initiates a Chef run, with a run list that consists of s3download::default.


    You typically have AWS OpsWorks Stacks run your recipes automatically by assigning them to the appropriate lifecycle event. You also can run such recipes by manually triggering the event. You can use a stack command to trigger Setup and Configure events, and a deploy command to trigger Deploy and Undeploy events.

After the recipe runs successfully, you can verify it.

To verify s3download

  1. The first step is to examine the Chef log. Your stack should have one instance named s3download1. On the Instances page, choose show in the instance's Log column to display the Chef log. Scroll down to find your log message near the bottom.

    ... [2015-05-01T21:11:04+00:00] INFO: Loading cookbooks [s3download@0.0.0] [2015-05-01T21:11:04+00:00] INFO: Storing updated cookbooks/s3download/recipes/default.rb in the cache. [2015-05-01T21:11:04+00:00] INFO: ******Downloading an object from S3****** [2015-05-01T21:11:04+00:00] INFO: Processing chef_gem[aws-sdk] action install (s3download::default line 3) [2015-05-01T21:11:05+00:00] INFO: Processing ruby_block[download-object] action run (s3download::default line 8) ...
  2. Use RDP to log in to the instance and examine the contents of c:\chef.