はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。
今回は、Laravelアプリケーションの画像保存先をS3に設定しましたので、備忘録としてまとめておきたいと思います。
間違いなどがございましたら、ご指摘のほどよろしくお願い致します。
S3とは
Amazon S3は、拡張可能性やデータ可用性を提供するオブジェクトストレージサービスであり、様々なユースケースをサポートしつつコスト効率を高め、セキュリティを強化してくれます。
Amazon Simple Storage Service (Amazon S3) は、業界をリードするスケーラビリティ、データ可用性、セキュリティ、およびパフォーマンスを提供するオブジェクトストレージサービスです。あらゆる規模や業種のお客様が、データレイク、クラウドネイティブアプリケーション、モバイルアプリケーションなど、事実上あらゆるユースケースで、あらゆる量のデータを保存、保護することができます。
引用:
Amazon S3
詳細はリンク先をご確認下さい。
・S3を利用する理由
アプレケーション上の画像(静的コンテンツ)の保存場所を、WebサーバーではなくS3にすることで下記のようなメリットが得られます。
・webサーバーのストレージに影響を与えなくて済む。
・HTMLへのアクセスと画像へのアクセスを分けることができ、結果的に負荷を分散することができる。
-> もし、webサーバー上に画像が保存されていると、画像へのアクセスの際にwebサーバーにアクセスする必要があり、webサーバーの負荷が増えます。
・画像の保存場所をS3に分離することで、webサーバーの台数を簡単に増設することができる。
-> webサーバー上に画像が保存されていると、webサーバーを増設する際に、画像を同期する必要が出てきます。
・CloudFrontを使用すると、画像配信を高速化できる。
・S3の基礎概念
バケット
: オブジェクトの保存場所であり、バケット名はグローバルでユニークな必要があります。
オブジェクト
: データ本体のことを指し、S3に格納されるファイルでURLが付与されています。(バケット内でのオブジェクト数は無制限)
キー
: オブジェクトの格納URLパスのことを指します。
S3環境の作成手順
今回は、Laravelアプリケーションで画像保存を行う際のデータ保存先をS3にします。
・1.S3のバケットを作成する
・一般的な設定
バケット名
: グローバルで一意な名前を付ける必要があります。
AWSリージョン
: 対象となるアプリケーションのEC2インスタンスと同じリージョンを選択します。
既存のパケットから設定をコピー
: オリジナルの設定を行う場合は選択する必要はありません。
・オブジェクト所有者
他の AWS アカウントからこのバケットに書き込まれたオブジェクトの所有権と、アクセスコントロールリスト (ACL) の使用を管理します。
オブジェクトの所有権は、オブジェクトへのアクセスを指定できるユーザーを決定します。
他のAWSアカウントからのアクセスを許可する際は、ACLを有効化してください。
・バケットのブロックパブリックアクセス設定
この設定では、バケットとオブジェクトに対する外部からのアクセスを禁止するための設定を行います。
今回は、インターネットに配信する画像を保存するため、設定はオフにしています。(ユースケースに合わせて設定を行って下さい)
・その他の設定
バケットのバージョニング
:
バージョニングとは、同じバケット内でオブジェクトの複数のバリアントを保持する手段のことです。要するに、同じファイル名を保存する際は各ファイルに一意なバージョンIDを付けて保存してくれます。
S3のバージョニング機能を使用すると、バケットに保存されたすべてのオブジェクトのバージョンを、保存、取得、復元することができます。
バージョニングは、バケットレベルで有効化および停止します。
バージョニング状態は、バケット内の一部ではなくすべてのオブジェクトに適用されるので、バージョニングを有効にした際は、全ての新しいオブジェクトがバージョニングされ一意のバージョンIDが割り当てられます。
※1度バケットのバージョニングを有効にすると、バージョニング無効の状態に戻すことはできません。
デフォルトの暗号化
:
S3バケットでデフォルトの暗号化を有効にすることで、新しいオブジェクトがバケットに保存される際に暗号化されるようにできます。
詳細は、リンク先をご確認下さい。
オブジェクトロック
オブジェクトロックにより、オブジェクトが削除または上書きされることを、一定期間または無期限に防止できます。
詳細は、リンク先をご確認下さい。
・2.S3を操作する権限を持つIAMユーザーを作成する
・ユーザーを追加
ユーザー名
: グローバルで一意なユーザー名を入力して下さい。
AWS アクセスの種類を選択
: 今回は、LaravelからS3にアクセスするのでプログラムによるアクセスを選択しています。
・アクセス許可の設定
S3で検索して、適切なアクセス権限を選択して下さい。
・設定の確認
各設定に間違いがないか確認後、ユーザーの作成を選択して下さい。
今回は、タグに関して触れていないので、必要な際は各自タグの設定も行って下さい。
・ユーザーの詳細を確認後、.csvファイルをダウンロードする
ユーザーの作成に成功すると、下のような画面が表示されます。
.csvファイルは重要なので、ダウンロードして認証情報を保管して下さい。
・コンソールへの管理アクセスを許可する
デフォルトでは、ユーザーはコンソールへの管理アクセスを許可されていません。
従って、ユーザー詳細画面の認証情報でコンソールのパスワードを有効化する必要があります。
コンソールのパスワードのリンク(管理)を選択すると下のような画面が表示されるので、コンソールへのアクセスを有効化し、自動生成のパスワードを設定して下さい。
適用後、作成されたパスワードを確認できるので、確認して下さい。
.csvファイルは重要なので、ダウンロードして認証情報を保管して下さい。
・3.バケットポリシーの編集
今回の記事で作成したバケットのポリシーを編集します。
・S3用ユーザーのARNとS3バケットのARNをコピーする:
まず初めに、S3用ユーザーのARNをコピーしていつでも使用できるように保管して下さい。
次に、先ほど作成したS3バケットを選択して、プロパティ欄からバケットのARNをコピーして保管して下さい。
・バケットポリシーを編集する
アクセス許可タグを選択後、バケットポリシーの編集ボタンをクリックしてポリシージェネレーターを開きます。
下のようなポリシージェネレーター画面でバケットポリシーに関する必要事項を入力してバケットポリシーを編集します。
Select Type of Policy
: S3 Bucket Policyを選択します。
Effect
: Allowを選択します。
Principal
: S3用のIAMユーザーのARNを入力します。
AWS Service
: Amazon S3が選ばれていることを確認して下さい。
Actions
: All Actions('*') を選択します。
Amazon Resource Name(ARN)
: コピーしたバケットのARNを入力します。
必要事項を入力後、Add Statement
をクリックすることで下記のように追加され、Generate Policy
をクリックすることで自動的にJSONで記述されたアクセスポイントポリシーを生成してくれます。
JSONで記述されたアクセスポイントポリシーをコピーした後に、アクセス許可画面に戻りバケットポリシーの編集画面を開き、デフォルトのバケットポリシーを削除して、先ほど自動生成したアクセスポイントポリシーで上書き保存して下さい。
以上で、バケットポリシーの設定は完了です。
~バケットポリシーの補足~
・Version:
"Version":"2012-10-17"
は、ポリシー言語の現行バージョンであり、常にVersionを2012-10-17に設定する必要があります。
このようにしない場合、このバージョンで導入されたポリシー変数などの機能は使用できません。
・Statement:
Statement要素は、ポリシーの主要要素であり必須です。
Statement要素には、単一のステートメントまたは個々または複数のステートメントの配列を含めることができます。
個々のステートメントブロックは中括弧{ }
で囲み、複数のステートメントの場合は角括弧[ ]
で囲み配列にする必要があります。
・Sid:
Sid (ステートメント ID) は、ポリシードキュメントに与える任意の識別子です。
Sid値は、ステートメント配列内の各ステートメントに割り当てることができます。
・Resource :
バケット、オブジェクト、アクセスポイント、ジョブは、アクセスを許可または拒否できる Amazon S3 のリソースです。ポリシーでは、Amazon リソースネーム (ARN) を使用して、リソースを識別します。
詳細は、リンク先をご確認ください。
・Action :
Amazon S3 では、各リソースに対して一連のオペレーションがサポートされています。許可(または拒否)するリソースのオペレーションは、アクションキーワードを使用して識別します。
・Effect:
Effect要素は必須であり、ステートメントの結果を許可または明示的な拒否のどちらにするかを指定します。
Effectの有効値は、Allow
とDeny
です。
※デフォルト設定では、リソースへのアクセスは拒否されます。
・Principal:
ステートメントのアクションやリソースへのアクセスを許可するアカウントまたはユーザーを指定します。
指定する際は、ユーザーのARNを利用します。
AWS S3へ画像をアップロードする設定(Laravel)
・1.Laravel側でleague/flysystem-aws-s3-v3のインストールを行う
LaravelでAWS S3
を操作する際は、thephpleague/flysystem-aws-s3-v3ライブラリを利用します。
今回使用するLaravelのバージョンは6.xなので、下記のリンク先でバージョン指定等がないか確認して下さい。
ちなみに、Laravel6.xではAmazon S3: league/flysystem-aws-s3-v3 ~1.0
といったようにバージョン指定されています。
[実行ユーザー名@ip- 特定のディレクトリ ]$ composer require league/flysystem-aws-s3-v3:^1.0
・2./config/filesystems.php
を編集する
/config/filesystems.phpを下記のように編集してください。
'default' => env('FILESYSTEM_DRIVER', 'local'),
// 追記
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
// 略
'disks' => [
'local' => [
// 略
],
'public' => [
// 略
],
// 以下を追記
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
],
・3.環境変数の設定
.envファイルを下記のように編集してください。
AWS_ACCESS_KEY_ID='AWSで作成したS3用ユーザーのAccess key ID'
AWS_SECRET_ACCESS_KEY='AWSで作成したS3用ユーザーのSecret access key'
AWS_DEFAULT_REGION=ap-northeast-1(東京リージョンの場合)
AWS_BUCKET='作成したバケット名'
・4.アップロードするメソッドの編集
該当するControllerのメソッドで、下記のように編集してください。
use Illuminate\Support\Facades\Storage;
を利用して、画像のアップロードやフルパスの取得を行います。
public function()
{
// バケットの`example`フォルダへアップロードする
$path = Storage::disk('s3')->putFile('example', $image, 'public');
// アップロードした画像のフルパスを取得
$user->image = Storage::disk('s3')->url($path);
}
以上で画像のアップロードが可能となります。
AWS S3で保存している画像を表示する設定(Laravel)
下記のように記述することで、AWS S3で保存している画像を表示できます。
# 略
<!-- 画像を表示 -->
<img src="{{ $user->image }}">
以上で、LaravelアプリケーションでS3に画像を保存、そして表示できるようになります。
参考文献
Amazon S3
S3 バケットでのバージョニングの使用
Amazon S3 バケット向けのサーバー側のデフォルトの暗号化動作の設定
S3 オブジェクトロックの使用
Amazon S3 コンソールを使用したバケットポリシーの追加
Laravel6.x ファイルストレージ
Amazon S3 のポリシーとアクセス許可
IAM JSON ポリシー要素のリファレンス
Amazon S3 バケットのアクセス許可