ローカルフォルダ内のファイルをAmazon S3にアップロードする

2021-12-28

AWS SDK for .NETを使い、Visual Studio コンソールアプリ(C#)でAmazon S3にファイルを保存

はじめに

AWSのAmazon S3バケットには、AWSマネジメントコンソール画面からファイルを保存(アップロード)できます。

しかし、マネジメントコンソールにアクセスさせたくないユーザーにも、S3バケットにファイル保存してほしい場合はどうしたらいいのでしょうか。

今回は、「AWS SDK for .NET」を使うことで、ローカルにあるファイルを一気にS3にアップロードできる方法が分かったので、その方法を共有します。

Amazon S3

Amazon S3のバケットをファイルの保存先としています。

Amazon S3 とは

AWSのAmazon S3ページの説明によると

Amazon Simple Storage Service (Amazon S3) は、業界をリードするスケーラビリティ、データ可用性、セキュリティ、およびパフォーマンスを提供するオブジェクトストレージサービスです。これはつまり、企業の規模にかかわらず、あらゆる業界のお客様が、データレイク、ウェブサイト、モバイルアプリケーション、バックアップおよび復元、アーカイブ、エンタープライズアプリケーション、IoT デバイスやビッグデータ分析などのさまざまなユースケースのデータを保存して保護することができるということです。Amazon S3 はデータを整理しアクセス制御を細かく調整するために使いやすい機能を提供しており、ビジネスや組織における規則やコンプライアンスの要件を満たしやすく設計されています。Amazon S3 は 99.999999999% (9 x 11) の耐久性を実現するように設計されており、世界中の企業のために、何百万ものアプリケーションのデータを保存しています。

https://aws.amazon.com/jp/s3/

個人的には以下の理由でS3を使っています。

  • ストレージの料金が「最初の 50 TB/月 :0.025USD/GB」であり、非常に安い
  • AWS Lambda 等、AWSの他サービスとの連携が容易である

特にAWSを使ったシステムを構築する場合には、ファイル置き場としてS3は安価であり使いやすいと思います。

以下Amazon S3の設定について記載しています。

S3バケットの作成

まず、ファイルをアップロードする先のS3バケットを作成します。

AWSマネジメントコンソールにログインし、Amazon S3の画面を開きます。
『バケットを作成』をクリック。

『バケットを作成』画面では任意のバケット名を入力し、他はデフォルト設定のままで大丈夫です。

S3アクセス権限ユーザー作成

次に、S3へのアクセス権限を持つユーザーを作成します。

AWSマネジメントコンソールにログインし、Identity and Access Management(IAM)の画面を開きます。
左メニューから『ユーザー』を選択し、『ユーザーを追加』します。

『ユーザーを追加』画面で、ユーザー名を記入します。
AWSアクセスの種類を選択で『プログラムによるアクセス』にチェックを入れます。
次のステップへ。

アクセス許可の設定で『既存のポリシーを直接アタッチ』を選択します。
ポリシーのフィルタで『s3』と入力するとS3関連のポリシーが出てきます。
この中の『AmazonS3FullAccess』を選択し、次のステップへ。

タグの追加画面では、何も設定せず次へ。

そうすると、以下の『ユーザーを追加』画面になります。

この画面は認証情報をダウンロードできる最後の機会とのことなので、csvダウンロードしておきます。
認証情報(アクセスキーIDとシークレットアクセスキー)は後程使います。

ここまででAmazon S3側の設定は終了です。

Visual Studio

ファイルをAmazon S3にアップロードするためのツールとして、Visual Studio 2019を使いました。

以下Visual Studio側の設定方法について記載しています。

Visual Studio プロジェクト作成

まずVisual Studioのプロジェクトを作成します。

Visual Studioを開き、『新しいプロジェクトの作成』からC#の『コンソールアプリ(.NET Core)』を選択し、次へ。

プロジェクト名には、任意のプロジェクト名を記載します。
今回は プロジェクト名:image2aws にしました。

『作成』を押し、しばらくするとプロジェクトが立ち上がります。

パッケージのインストール

次にAmazon S3と連携するためのパッケージをインストールします。

ソリューションエクスプローラ内のプロジェクト名を右クリックすると、上のメニューが出てきます。
この中の『NuGet パッケージ管理』を選択します。

参照から『aws』で検索するとAWS関連のいろんなパッケージが出てきます。
この中の『AWSSDK.S3』をインストールします。

上画面が出てきて、『AWSSDK.Core』と『AWSSDK.S3』両方がインストールされました。

プログラムの作成

パッケージをインストールした後は、プログラムを作成します。

Program.cs は以下のプログラムとしました。
本プログラムはローカルにあるフォルダー内のファイルを全てS3バケットの同名称フォルダ内にアップロードするプログラムとなってます。

using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.IO;

namespace image2aws
{
    class Program
    {
        static IAmazonS3 client;
        static string bucketName = "バケット名 を入力";
        static string profileName = "default";
        static string accessKey = "accessKey を入力";
        static string secretKey = "secretKey を入力";

        [Obsolete]
        static void Main(string[] args)
        {
            Amazon.Util.ProfileManager.RegisterProfile(profileName, accessKey, secretKey);

            using (client = new AmazonS3Client(RegionEndpoint.APNortheast1))
            {
                Console.WriteLine("Uploading an object");
                string[] files = Directory.GetFiles("folder", "*", SearchOption.AllDirectories);

                foreach (string str in files)
                {
                    string str2 = str.Replace("\\", "/");
                    WritingAnObject(str, str2);
                }
            }

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
        static async void WritingAnObject(string filename, string filename2)
        {
            try
            {
                PutObjectRequest putRequest = new PutObjectRequest
                {
                    BucketName = bucketName,
                    Key = filename2,
                    FilePath = filename
                };

                PutObjectResponse response = await client.PutObjectAsync(putRequest);
                Console.WriteLine("Status Code: " + response.HttpStatusCode);
            }
            catch (AmazonS3Exception amazonS3Exception)
            {
                if (amazonS3Exception.ErrorCode != null &&
                    (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId")
                    ||
                    amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
                {
                    Console.WriteLine("Invalid AccessKey");
                }
                else
                {
                    Console.WriteLine(
                        "Error occurred. Message:'{0}' when writing an object"
                        , amazonS3Exception.Message);
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(
                       "Generic Error occurred. Message:'{0}' when writing an object"
                       , exception.Message);
            }
        }
    }
}

デバック時の使い方

実際に試験する場合は、フォルダ名やS3バケット名が異なるはずなので、デバックしながら調整していきます。

本プロジェクトがあるディレクトリの中の、「\bin\Debug\netcoreapp3.1」に「folder」というフォルダを設置します。
このフォルダ「folder」が中にあるファイルごと全てS3の「folder」にアップロードされる仕組みになってます。

デフォルト設定では以下のフォルダがそのままS3バケットにアップロードされます。
C:\Users\ユーザー名\source\repos\image2aws\image2aws\bin\Debug\netcoreapp3.1\folder

フォルダー名:「folder」がないとエラーになります。

ではデバックボタンでデバック実行します。

以下のコンソール画面が出てきて、folder内のファイルアップロードが完了します。

S3にファイルがアップロードされてるかをAWSマネジメントコンソールで確認します。

Amazon s3バケットのfolder内に、ローカルにあったフォルダが無事アップロードされていました。

正式版の使い方

デバックでいろいろ調整した後、正式版としてユーザーに頒布する方法です。

ソリューションエクスプローラのプロジェクト名を右クリックし、『発行』をクリックします。

フォルダーに発行します。次へ。

更に次へ。

そのままで『完了』をクリックします。

『発行』をクリックします。

この↓ディレクトリにPublishというフォルダができます。
C:\Users\ユーザー名\source\repos\image2aws\image2aws\bin\Release\netcoreapp3.1

Publishフォルダごと移動して使えますので、ユーザーに利用してもらう場合はこのフォルダを渡します。

このフォルダ内に フォルダ名:floder を設置し、image2aws.exeを実行すると、デバック時の挙動と同様、folderが全てS3バケットにアップロードされます。

おわりに

visual studioでコンソールアプリを作成することで、AWSマネジメントコンソールを使わずに、ファイルをAmazon S3のバケットにアップロードする方法をまとめました。

参考