質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.81%

S3に本番環境で画像をアップロードしたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 293

kei_0715

score 10

前提・実現したいこと

laravelで構築したサイトを本番環境で運用しています。
その中でS3を使って画像をアップロードしたいです。

発生している問題・エラーメッセージ

ローカル環境では問題なく画像をアップロードできているのですが、
本番環境(ec2)を使用した際にエラーが発生していまいます。

下記がエラーメッセージになります。

GuzzleHttp\Exception\ClientException
Client error: `GET http://169.254.169.254/latest/meta-data/iam/security-credentials/` resulted in a `404 Not Found` response: <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. (truncated...)
        return new $className($message, $request, $response, $previous, $ctx);

    }



    /**

     * Get a short summary of the response

     *

     * Will return `null` if the response is not printable.

     *

     * @param ResponseInterface $response

     *

     * @return string|null

Controllerの内容

use Storage;
--略
public function create(Request $request)
    {
        $this->validate($request, News::$rules);
        $news = new News;
        $form = $request->all();   
        if (isset($form['image'])) {
            $path = Storage::disk('s3')->putFile('/',$form['image'],'public');
            $news->image_path = Storage::disk('s3')->url($path);            
        } else {
            $news->image_path = null;
        }
        unset($form['_token']);        
        unset($form['image']);        
        $news->fill($form);        
        $news->save();        
        return redirect('news/create');


viewの内容

@extends('layouts.news')

@section('title','新規ニュースの作成')

@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-8 mx-auto">
                <h2>新規ニュースの作成</h2>
                <form action="{{ action('NewsController@create') }}" method="post" enctype="multipart/form-data">

                    @if (count($errors) > 0)
                        <ul>
                            @foreach($errors->all() as $e)
                                <li>{{ $e }}</li>
                            @endforeach
                        </ul>
                    @endif
                    <div class="form-group row">
                        <label class="col-md-2" for="title">タイトル</label>
                        <div class="col-md-10">
                            <input type="text" class="form-control" name="title" value="{{ old('title') }}">
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-md-2" for="body">本文</label>
                        <div class="col-md-10">
                            <textarea class="form-control" name="body" rows="20">{{ old('body') }}</textarea>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-md-2" for="title">画像</label>
                        <div class="col-md-10">
                            <input type="file" class="form-control-file" name="image">
                        </div>
                    </div>
                    {{ csrf_field() }}
                    <input type="submit" class="btn btn-primary" value="更新">
                    <a href="{{ action('HomeController@browse') }}" role="button" class="btn btn-primary">TOPへ戻る</a>
                </form>
            </div>
        </div>
    </div>
@endsection


filesystems.php

's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
        ],


.env

AWS_ACCESS_KEY_ID=******************
AWS_SECRET_ACCESS_KEY=***************
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET=portfolio-salon

試したこと

S3バケットのアクセス許可(アカウント、バケット)をオフ。

考えたこと

エラーが404だったので記述ミスも考えたのですが、ローカルで通っていたので本番用の設定に
何かミスがあるのではないかと考えています。

すみません、どなたかアドバイスあればお願いします。

補足情報(FW/ツールのバージョンなど)

Laravel 6.2.0
PHP 7.2.19
cloud 9(ローカル環境)
ec2(本番環境)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

IAM 管理画面で、IAMロールを作成してください。
タイプ:EC2
パーミッション:S3バケットへのアクセス許可を設定するかテンプレートから「Amazon S3 Full Access」を選ぶ
次にEC2管理画面で インスタンスを作成するときに 先程作成した IAMロールを選択します。
詳しくは次のナレッジの関連情報のリンクを読んでみてみてください。
IAM ロールを作成しましたが、これを EC2 インスタンスに割り当てたいと思います。

IAMロールを作成すると curl http://169.254.169.254/latest/meta-data/iam/security-credentials/role_name で認証情報が返されるので アクセスできるようになると思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/19 12:56 編集

    設定をしたところアクセスはできた様です!
    ただ、次のエラーがでました。
    Aws\S3\Exception\S3Exception
    Error executing "PutObject" on "https://kvpeoug8ohhtgob70vhbscz42wwgczzezdxzq47t.jpeg"; AWS HTTP error: cURL error 6: Could not resolve host: kvpeoug8ohhtgob70vhbscz42wwgczzezdxzq47t.jpeg (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
    .envは見直しました。。。
    ローカルではphp artisan cache:clearでは変化が無く、
    php artisan config:clearをして、記述ミスを直したところ解決しました。

    すみません、本番環境でphp artisan config:clearを実行したら画面が真っ白になり対策中です。

    キャンセル

  • 2019/11/19 21:47 編集

    エラーのURLに S3 バケットの名前が入ってない(kv~.jpeg はファイル名ですよね?)のですが、バケットの設定は正しいですか? filesystems.php と .env ファイルの内容を、質問に追記できますか?(センシティブな内容は適当にマスクして貰えればと思います)

    キャンセル

  • 2019/11/21 08:55 編集

    解決しました!S3の設定自体は間違っていなかったようです。
    php artisan config:clearでキャッシュクリアしたら通りました。
    今回.envに誤った記述をしてしまっていて、キャッシュクリア後に画面が真っ白になっていましたが、
    そちらを解消したところ、無事画像の方も反映出来る様になっていました!
    IAMのロールに関して知識が足りず、本当に助かりました。
    ありがとうございました!

    ベストアンサーですが、お二人の方に回答して頂いて非常に甲乙付け難いのですが。。。
    IAMロールの作成に関して詳細を記述して頂いたtake88さんにさせて頂きました。

    キャンセル

  • 2019/11/21 08:59

    よかったですね。解決したならご自身で回答を書いて、解決済みにしてもらえますか。あとから見た人が解決済みだと分かるので ソッチのほうが親切だと思います。よろしくおねがいします。

    キャンセル

+1

GET http://169.254.169.254/latest/meta-data/iam/security-credentials

ということなので、EC2インスタンスのクレデンシャル情報を取得しようとして見つからない、という挙動をしている用に見えます。
Cloud9の環境ではどのようにS3にアクセスする権限を与えていましたか?
また本番環境のインスタンスに何らかの形で必要な権限を与えていますか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/20 17:50

    この設定はしていませんでした。
    ローカルで動作確認がとれた場合でも、本番ではその様な設定をしなければいけないのでしょうか?
    ちなみにconfig:clear後の画面が、いまだ表示できていません・・・。

    キャンセル

  • 2019/11/20 18:04

    ローカルからは一応実行できたんですね…。バケット作成時はデフォルトではパブリックに公開できないような設定になっているので、バッティングする可能性があるかもしれないです。

    画面が表示できていない理由についてはログを見てみないと何とも言えませんが、何か新しい情報は出ていないですか?

    キャンセル

  • 2019/11/21 08:55

    解決しました!S3の設定自体は間違っていなかったようです。
    php artisan config:clearでキャッシュクリアしたら通りました。
    今回.envに誤った記述をしてしまっていて、キャッシュクリア後に画面が真っ白になっていましたが、
    そちらを解消したところ、無事画像の方も反映出来る様になっていました!
    IAMのロールに関して知識が足りず、本当に助かりました。
    ありがとうございました!

    キャンセル

+1

IAMロールの作成

タイプ:EC2
パーミッション:Amazon S3 Full Access
以上の内容で作成すると下記画像の様になる。
イメージ説明

作成したロールをインスタンスに割り当て

参考にした動画

AWS側の設定後、
php artisan cache:clear
php artisan config:clear、で解決しました!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る