【AWS】AWS SDKを利用したNode.jsサンプル - はまったこと、S3クラスのバケット作成など

#はじめに
AWS公式サイトにAWS SDKを利用したNode.jsサンプルについて「はまった点」、「S3クラスのバケット作成関数」についてまとめました

#AWS公式サンプルプログラム
https://aws.amazon.com/jp/developers/getting-started/nodejs/

#前提
- AWSアカウントを取得済みであること
- IAMユーザーを作成済であること
- Gitがインストール済みであること
- Node.jsがインストール済みであること

#手順
- 公式サイトの手順を補足しながら進めていきます。

1.任意のディレクトリを作成します。
2.サンプルプロジェクトのダウンロード

```console
git clone https://github.com/awslabs/aws-nodejs-sample.git
```

3.npm install

4.アクセスキーの設定 

- credentialsの場所は以下
    - ~/.aws/credentials（Windows ユーザーの場合は、C:\Users\USER_NAME\.aws\credentials） 
    - 以下の様に設定済みなので、省略

```
[pguser1]
aws_access_key_id = (任意のアクセスキー)
aws_secret_access_key = (任意のシークレットアクセスキー)
```

5.サンプルの実行

```console
node sample.js
```

## 結果
- コンソールにはエラーメッセージも何も表示されないので、成功したのかと思いきや、AWSマネジメントコンソールにてS3バケットを確認しましたが、実際にはファイルがアップロードされていませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235774/a483159e-84b9-9da4-aebc-cd4faee9501a.png)

## 原因
- ソースコードを追ったところ、当たり前かもしれませんが、credentialのデフォルトを使用する想定のようです。自分の環境では、defaultを作成していなかった為、どこのユーザーのS3バケットにファイルをアップロードすれば良いかプログラムの方で分からなかった為のようです。

```
aws configure --profile pguser1
```

## 対応策1
- credential でdefaultユーザーが未設定の場合は、サンプルソースの以下個所にコードを追加してください。
- 私の環境だと、ユーザー名は[pguser1]を指定していますが、指定するユーザー名は、皆様の環境に合わせてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235774/e9f14618-0228-737c-e127-326352e8b094.png)

### 結果
```
C:\Dev\AWS\node_sample\aws-nodejs-sample>node sample.js
Successfully uploaded data to node-sdk-sample-1d6a29d7-6378-44c3-9627-4d472e1cb40a/hello_world.txt
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235774/6d0c7fde-d467-7fc8-923b-3ed06400763e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235774/70f0b418-c8b6-a3ee-97b9-3e8d3b38dcbd.png)

# サンプルソースの中身について解説

```js
var AWS = require('aws-sdk');
var uuid = require('node-uuid');

var credentials = new AWS.SharedIniFileCredentials({profile: 'pguser1'});
AWS.config.credentials = credentials;

// Create an S3 client
var s3 = new AWS.S3();

// Create a bucket and upload something into it
var bucketName = 'node-sdk-sample-' + uuid.v4();
var keyName = 'hello_world.txt';

s3.createBucket({Bucket: bucketName}, function() {
  var params = {Bucket: bucketName, Key: keyName, Body: 'Hello World!'};
  s3.putObject(params, function(err, data) {
    if (err)
      console.log(err)
    else
      console.log("Successfully uploaded data to " + bucketName + "/" + keyName);
  });
});

```

## 拡張機能の読込

1.AWS SDKとNodeのUUIDパッケージを読み込んで機能を使用できるようにします。  

```js
var AWS = require('aws-sdk');
var uuid = require('node-uuid');
```

2.認証情報のユーザーを指定します。

```js
var credentials = new AWS.SharedIniFileCredentials({profile: 'pguser1'});
AWS.config.credentials = credentials;

```

3.S3オブジェクトを定義します。

```js
var s3 = new AWS.S3();
```

4.S3バケット、アップロード用ファイルの名前を定義します。

```js
var bucketName = 'node-sdk-sample-' + uuid.v4();
var keyName = 'hello_world.txt';
```

5.S3バケットにファイルをアップロードします。

```js
s3.createBucket({Bucket: bucketName}, function() {
  var params = {Bucket: bucketName, Key: keyName, Body: 'Hello World!'};
  s3.putObject(params, function(err, data) {
    if (err)
      console.log(err)
    else
      console.log("Successfully uploaded data to " + bucketName + "/" + keyName);
  });
});

```
# S3サービスのcreateBucket関数
- 構文 S3.createBucket関数(パラメータ, コールバック引数)
    - パラメータ(参考)　※Bucketは必須ですが、以外は未設定の場合、デフォルトで設定されます。
        - Bucket：作成するバケット名 ※必須
        - ACL：バケットの公開範囲
            - "private"
            - "public-read"
            - "public-read-write"
            - "authenticated-read"
        - CreateBucketConfiguration：バケットの構成情報
            - LocationConstraint：バケットが作成されるリージョンを指定します。リージョンを指定しない場合、バケットは米国東部（バージニア北部）リージョン（us-east-1）に作成されます。
        - GrantFullControl：バケットの読み取り、書き込み、読み取りACP、および書き込みACP権限を被付与者に許可します。
        - GrantRead：被付与者がバケット内のオブジェクトをリストできるようにします。
        - GrantReadACP：被付与者がバケットACLを読み取ることができるようにします。
        - GrantWrite：被付与者がバケット内のオブジェクトを作成、上書き、削除で
        - GrantWriteACP：被付与者は、該当するバケットのACLを作成できます。
        - ObjectLockEnabledForBucket：新しいバケットに対してS3オブジェクトロックを有効にするかどうかを指定します。
    - コールバック引数：JSの機能。割愛します。


# 参考URL
[AWS公式 - Node.js 内の AWS SDK for JavaScript のご利用開始にあたって](https://aws.amazon.com/jp/developers/getting-started/nodejs/)
[AWS公式 - クラス：AWS.S3](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createBucket-property)
[HACKNOTE - aws cliでアカウントを切り替えるし、AWS SDK for JavaScriptでも切り替える](https://hacknote.jp/archives/26571/)