

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Vagrant 인스턴스에서 SDK for Ruby 사용
<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 Support 팀에 문의하세요.

이 주제에서는 Vagrant 인스턴스에서 실행되는 레시피가 어떻게 [AWS SDK for Ruby](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/)를 사용하여 Amazon S3에서 파일을 다운로드할 수 있는지에 대해 설명합니다. 시작하기 전에 먼저 레시피가 Amazon S3에 액세스할 수 있도록 허용하는 액세스 키와 보안 액세스 키라는 AWS 자격 증명 세트가 있어야 합니다.

**중요**  
이 목적으로 루트 계정 자격 증명은 사용하지 않는 것이 좋습니다. 그 대신, 적절한 정책으로 사용자를 생성하고 레시피에 해당 자격 증명을 제공합니다.  
자격 증명을 포함한 파일을 공개 GitHub 또는 Bitbucket 저장소에 업로드하는 등 공개적으로 액세스할 수 있는 위치에 자격 증명(IAM 사용자 자격 증명 포함)을 보관하지 않도록 주의하세요. 그러면 자격 증명이 노출되고 계정의 보안이 훼손될 수 있습니다.  
 EC2Amazon EC2 인스턴스에서 실행되는 레시피는 더욱 뛰어난 방식인 IAM 역할을 사용할 수 있습니다([OpsWorks Stacks Linux 인스턴스에서 SDK for Ruby 사용](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 Management Console 하고 [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 사용 설명서](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)의 *IAM 사용자를 위한 액세스 키 관리*를 참조하세요.

다음에는 다운로드할 파일을 제공해야 합니다. 이 예제에서는 새로 생성된 `myfile.txt`이라는 S3 버킷에 `cookbook_bucket`라는 파일을 저장하는 것으로 가정합니다.

**다운로드할 파일을 제공하려면**

1. 다음 텍스트가 포함된 `myfile.txt` 파일을 만든 다음 워크스테이션의 원하는 위치에 저장합니다.

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

1. [Amazon S3 `cookbook_bucket` 콘솔](https://console.aws.amazon.com/s3/)에서 **표준** 리전에 라는 이름의 버킷을 생성하고 `myfile.txt`를 버킷에 업로드합니다.

다음과 같이 쿡북을 설정합니다.

**쿡북을 설정하려면**

1. `opsworks_cookbooks` 안에 `s3bucket` 하위 디렉터리를 만들고 그 디렉터리로 이동합니다.

1. [예제 1: 패키지 설치](cookbooks-101-basics-packages.md) 단원에서 설명하는 대로 Test Kitchen을 초기화 및 구성합니다.

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. 다음 `default_attributes` 섹션을 사용하여 환경 파일 `test.json`을 만들고 사용자에 해당하는 키로 `access_key` 및 `secret_key` 값을 바꿉니다. 쿡북의 `environments` 폴더에 파일을 저장합니다.

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

다양한 방법으로 인스턴스에서 실행되는 레시피에 자격 증명을 제공할 수 있습니다. 중요한 고려 사항은 잘못하여 키가 노출되어 계정 보안이 훼손될 가능성을 제한하는 것입니다. 이를 위해 코드에 명시적 키 값을 사용하는 것은 권장하지 않습니다. 예제에서는 키 값을 노드 객체에 저장합니다. 그러면 레시피가 리터럴 값을 노출하는 대신 노드 구문을 사용하여 참조할 수 있습니다. 노드 객체에 액세스하려면 루트 권한이 있어야 합니다. 이는 키가 노출될 가능성을 제한합니다. 자세한 내용은 [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
```

레시피의 첫 번째 부분은 젬 패키지인 SDK for Ruby를 설치합니다. [gem\$1package](https://docs.chef.io/chef/resources.html#gem-package) 리소스는 레시피 또는 다른 애플리케이션에서 사용될 젬을 설치합니다.

**참고**  
사용자의 인스턴스에는 일반적으로 두 개의 Ruby 인스턴스가 있으며, 이 두 개의 인스턴스는 일반적으로 버전이 다릅니다. 하나는 Chef 클라이언트가 사용하는 전용 인스턴스입니다. 다른 하나는 인스턴스에서 실행되는 애플리케이션 및 레시피가 사용합니다. 젬 설치를 위한 리소스는 [gem\$1package](https://docs.chef.io/chef/resources.html#gem-package) 및 [chef\$1gem](https://docs.chef.io/chef/resources.html#chef-gem) 두 개가 있으므로 젬 패키지를 설치할 때 이 구분을 이해하는 것이 중요합니다. 애플리케이션 또는 레시피가 젬 패키지를 사용하는 경우 `gem_package`를 사용하여 젬 패키지를 설치합니다. `chef_gem`은 Chef 클라이언트가 사용하는 젬 패키지에만 사용합니다.

레시피의 나머지 부분은 [ruby\$1block](https://docs.chef.io/chef/resources.html#ruby-block) 리소스입니다. 여기에 파일을 다운로드하는 Ruby 코드가 포함됩니다. 레시피가 Ruby 애플리케이션이기 때문에 코드를 레시피에 직접 배치할 수 있다고 생각할 수 있습니다. 하지만 Chef 실행은 리소스를 실행하기 전에 모든 코드를 컴파일합니다. 예제 코드를 레시피에 직접 배치할 경우, Ruby는 `gem_package` 리소스를 실행하기 전에 `require 'aws-sdk'` 문을 해결하려고 시도합니다. SDK for Ruby가 아직 설치되지 않았으므로 컴파일이 실패합니다.

`ruby_block` 리소스 내 코드는 해당 리소스가 실행될 때까지는 컴파일되지 않습니다. 이 예제에서 `gem_package` 리소스가 SDK for Ruby 설치를 마친 후에 `ruby_block` 리소스가 실행됩니다. 그러므로 코드가 성공적으로 실행될 것입니다.

`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` 연결을 호출하여 이를 `myfile.txt`을 나타내는 `myfile` 이름의 [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) 객체를 반환합니다.

1. `Dir.chdir`을 사용하여 작업 디렉터리를 `/tmp`로 설정합니다.

1. `myfile.txt` 파일을 열고, 파일에 `myfile`을 기록하고, 파일을 닫습니다.

**레시피를 실행하려면**

1. 예제 레시피가 포함된 `default.rb` 파일을 만들어 `recipes` 디렉터리에 저장합니다.

1. `kitchen converge`를 실행합니다.

1. `kitchen login`을 실행하여 인스턴스에 로그인한 다음, `ls /tmp`를 실행합니다. 여러 Test Kitchen 파일 및 디렉터리와 함께 `myfile.txt`가 있어야 합니다.

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

   또한 `cat /tmp/myfile.txt`를 실행하여 파일의 내용이 올바른지 확인할 수 있습니다.

다 마치면 `kitchen destroy`를 실행해 인스턴스를 종료하세요.