

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 Vagrant 執行個體上使用適用於 Ruby 的 SDK
<a name="cookbooks-101-opsworks-s3-vagrant"></a>

**重要**  
 AWS OpsWorks Stacks 此服務已於 2024 年 5 月 26 日終止，並已針對新客戶和現有客戶停用。我們強烈建議客戶盡快將其工作負載遷移至其他解決方案。如果您對遷移有任何疑問，請透過 [AWS re：Post](https://repost.aws/) 或透過 [AWS Premium Support](https://aws.amazon.com/support) 聯絡 AWS 支援 團隊。

本主題說明在 Vagrant 執行個體上執行的配方如何使用 從 Amazon S3 [適用於 Ruby 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/)下載檔案。開始之前，您必須先擁有一組 AWS 登入資料：存取金鑰和私密存取金鑰，以允許配方存取 Amazon S3。

**重要**  
強烈建議您不要基於此目的使用 root 帳戶登入資料。反之，請使用適當的政策建立使用者，並將這些登入資料提供給配方。  
請注意不要將登入資料—甚至是 IAM 使用者登入資料—放在可公開存取的位置，例如將包含登入資料的檔案上傳至公有 GitHub 或 Bitbucket 儲存庫。這麼做會公開您的登入資料，而且可能會危害您帳戶的安全性。  
 在 EC2Amazon EC2 執行個體上執行的配方可以使用更好的方法，即 IAM 角色，如中所述[在 Stacks Linux 執行個體上使用適用於 Ruby OpsWorks 的 SDK](cookbooks-101-opsworks-s3-opsworks.md)。  
傳遞至 Amazon S3 儲存貯體的內容可能包含客戶內容。如需移除敏感資料的詳細資訊，請參閱[如何清空 S3 儲存貯體？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/empty-bucket.html)或[如何刪除 S3 儲存貯體？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html)。

如果您還沒有適當的 使用者，則可以建立一位使用者，如下所示。如需詳細資訊，請參閱[什麼是 IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/Introduction.html)。

**警告**  
IAM 使用者具有長期憑證，這會造成安全風險。為了協助降低此風險，建議您只為這些使用者提供執行任務所需的許可，並在不再需要這些使用者時將其移除。

**建立 IAM 使用者**

1. 登入 AWS 管理主控台 並開啟位於 https：//[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 的 IAM 主控台。

1. 在導覽窗格中，選擇**使用者**，並視需要選擇**新增使用者**以建立新的管理使用者。

1. 在**設定許可**頁面上，選擇**直接連接政策**。

1. **S3** 在**許可政策**搜尋方塊中輸入 以顯示 Amazon S3 政策。

   選擇 **AmazonS3ReadOnlyAccess**。如果您想要，則可以指定政策來授予更廣泛的許可 (例如 **AmazonS3FullAccess**)，但標準實務是僅授予這些所需的許可。在此情況下，配方僅會下載檔案，因此唯讀存取就已足夠。

1. 選擇**下一步**。

1. 選擇**建立使用者**

1. 接著為您的使用者建立存取金鑰。如需建立存取金鑰的詳細資訊，請參閱*IAM 使用者指南*中的[管理 IAM 使用者的存取金鑰](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)。

您必須接著提供要下載的檔案。此範例假設您將名為 `myfile.txt` 的檔案放入名為 `cookbook_bucket` 的新建立 S3 儲存貯體中。

**提供要下載的檔案**

1. 建立名為 `myfile.txt` 且具有下列文字的檔案，並將它儲存至工作站上的方便位置。

   ```
   This is the file that you just downloaded from Amazon S3.
   ```

1. 在 [Amazon S3 主控台](https://console.aws.amazon.com/s3/)`cookbook_bucket`上，在**標準**區域中建立名為 的儲存貯體，並上傳至`myfile.txt`儲存貯體。

設定技術指南，如下所示。

**設定技術指南**

1. 在 `opsworks_cookbooks` 內建立並導覽至名為 `s3bucket` 的目錄。

1. 初始化並設定 Test Kitchen，如[範例 1：安裝套件](cookbooks-101-basics-packages.md)中所述。

1. 將 `.kitchen.yml` 中的文字取代為下列內容。

   ```
   ---
   driver:
     name: vagrant
   
   provisioner:
     name: chef_solo
     environments_path: ./environments
   
   platforms:
     - name: ubuntu-14.04
   
   suites:
     - name: s3bucket
       provisioner:
         solo_rb:
           environment: test
       run_list:
         - recipe[s3bucket::default]
       attributes:
   ```

1. 將兩個目錄新增至 `s3bucket`：`recipes` 和 `environments`。

1. `test.json` 使用下列`default_attributes`區段建立名為 的環境檔案，將 `access_key`和 `secret_key`值取代為您的使用者對應的金鑰。將檔案儲存至技術指南的 `environments` 資料夾。

   ```
   {
     "default_attributes" : {
       "cookbooks_101" : {
         "access_key": "AKIAIOSFODNN7EXAMPLE",
         "secret_key" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
       }
     },
     "chef_type" : "environment",
     "json_class" : "Chef::Environment"
   }
   ```

您有各種方法可以將登入資料提供給執行個體上所執行的配方。主要考量是限制意外公開金鑰以及危害您帳戶安全性的機會。因此，不建議在您的程式碼中使用明確金鑰值。此範例改為將金鑰值放入節點物件中，以使用節點語法而非公開常值來允許配方參考它們。您必須擁有 root 權限才能存取節點物件，這會限制可能公開金鑰的可能性。如需詳細資訊，請參閱[管理 AWS 存取金鑰的最佳實務](https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html)。

**注意**  
請注意，此範例使用巢狀屬性，而且 `cookbooks_101` 為第一個元素。如果節點物件中有其他 `access_key` 或 `secret_key` 屬性，則本實務可限制名稱衝突的機會。

下列配方會從 `myfile.text` 儲存貯體下載 `cookbook_bucket`。

```
gem_package "aws-sdk ~> 3" do
  action :install
end

ruby_block "download-object" do
  block do
    require 'aws-sdk'

    s3 = Aws::S3::Client.new(
          :access_key_id => "#{node['cookbooks_101']['access_key']}",
          :secret_access_key => "#{node['cookbooks_101']['secret_key']}")

    myfile = s3.bucket['cookbook_bucket'].objects['myfile.txt']
    Dir.chdir("/tmp")
    File.open("myfile.txt", "w") do |f|
      f.write(myfile.read)
      f.close
    end
  end
  action :run
end
```

配方的第一部分會安裝適用於 Ruby 的 SDK，這是 Gem 套件。[gem\$1package](https://docs.chef.io/chef/resources.html#gem-package) 資源會安裝配方或其他應用程式所使用的 Gem。

**注意**  
您的執行個體通常會有兩個 Ruby 執行個體，這一般是不同的版本。其中一個是 Chef 用戶端所使用的專用執行個體。另一個是供執行個體上所執行的應用程式和配方使用。安裝 Gem 套件時，請務必了解這項差異，因為有兩個適用於安裝 Gem ([gem\$1package](https://docs.chef.io/chef/resources.html#gem-package) 和 [chef\$1gem](https://docs.chef.io/chef/resources.html#chef-gem)) 的資源。如果應用程式或配方使用 Gem 套件，則請使用 `gem_package` 安裝它。`chef_gem` 僅適用於 Chef 用戶端所使用的 Gem 套件。

配方的其餘部分是 [ruby\$1block](https://docs.chef.io/chef/resources.html#ruby-block) 資源，而此資源包含可下載檔案的 Ruby 程式碼。您可能認為配方是 Ruby 應用程式，因此可以直接將程式碼放入配方中。不過，Chef 執行會先編譯整個程式碼，再執行任何資源。如果您將範例程式碼直接放在配方中，則 Ruby 會嘗試先解決 `require 'aws-sdk'` 陳述式，再執行 `gem_package` 資源。由於尚未安裝適用於 Ruby 的 SDK，編譯將會失敗。

除非執行 `ruby_block` 資源，否則不會編譯該資源中的程式碼。在此範例中，`ruby_block`資源會在`gem_package`資源完成安裝適用於 Ruby 的 SDK 後執行，因此程式碼將成功執行。

`ruby_block` 中的程式碼會運作，如下所示。

1. 建立新的 [https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3.html](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3.html) 物件，以提供服務界面。

   存取金鑰和秘密金鑰的指定方式是參考節點物件中所存放的值。

1. 呼叫`S3`物件的`bucket.objects`關聯，傳回名為 的[https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html)物件`myfile`，代表 `myfile.txt`。

1. 使用 `Dir.chdir` 將工作目錄設定為 `/tmp`。

1. 開啟名為 `myfile.txt` 的檔案，並將 `myfile` 的內容寫入該檔案，然後關閉該檔案。

**執行配方**

1. 使用範例配方建立名為 `default.rb` 的檔案，並將它儲存至 `recipes` 目錄。

1. 執行 `kitchen converge`。

1. 執行 `kitchen login` 登入執行個體，然後執行 `ls /tmp`。您應該會看到 `myfile.txt`，以及數種 Test Kitchen 檔案和目錄。

   ```
   vagrant@s3bucket-ubuntu-1204:~$ ls /tmp
   install.sh  kitchen  myfile.txt  stderr
   ```

   您也可以執行 `cat /tmp/myfile.txt`，確認檔案的內容正確。

完成後，請執行 `kitchen destroy` 終止執行個體。