Cloud Storage のチュートリアル

このシンプルなチュートリアルでは、Cloud Storage イベントに応答するために Cloud Storage トリガーを用いてバックグラウンド Cloud Function で書き込み、デプロイ、トリガーを行う方法について説明します。

Cloud Storage 自体を使用したコードサンプルについては、Google Cloud のサンプル ブラウザをご覧ください。

目標

料金

このチュートリアルでは、以下を含む Cloud Platform の有料コンポーネントを使用します。

  • Google Cloud Functions
  • Google Cloud Storage

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

新しい Cloud Platform ユーザーは無料トライアルをご利用いただけます。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    [プロジェクトの選択] ページに移動

  3. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. Cloud Functions, Cloud Build, and Cloud Storage API を有効にします。

    API を有効にする

  5. Cloud SDK をインストールして初期化します。
  6. Cloud SDK がすでにインストールされている場合は、次のコマンドを実行して更新します。

    gcloud components update
  7. 開発環境を準備します。

アプリケーションの準備

  1. Cloud Storage バケットを作成しテストファイルをアップロードします。ここで、YOUR_TRIGGER_BUCKET_NAME はグローバルに固有のバケット名となります。

    gsutil mb gs://YOUR_TRIGGER_BUCKET_NAME
    
  2. ローカルマシンにサンプルアプリのリポジトリのクローンを作成します。

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    または、zip 形式のサンプルをダウンロードし、ファイルを抽出してもかまいません。

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    または、zip 形式のサンプルをダウンロードし、ファイルを抽出してもかまいません。

    Go

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git

    または、zip 形式のサンプルをダウンロードし、ファイルを抽出してもかまいません。

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

    または、zip 形式のサンプルをダウンロードし、ファイルを抽出してもかまいません。

    C#

    git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git

    または、zip 形式のサンプルをダウンロードし、ファイルを抽出してもかまいません。

    Ruby

    git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples.git

    または、zip 形式のサンプルをダウンロードし、ファイルを抽出してもかまいません。

  3. Cloud Functions のサンプルコードが含まれているディレクトリに移動します。

    Node.js

    cd nodejs-docs-samples/functions/helloworld/

    Python

    cd python-docs-samples/functions/helloworld/

    Go

    cd golang-samples/functions/helloworld/

    Java

    cd java-docs-samples/functions/helloworld/hello-gcs/

    C#

    cd dotnet-docs-samples/functions/helloworld/HelloGcs/

    Ruby

    cd ruby-docs-samples/functions/helloworld/storage/

関数のデプロイとトリガー

現在、Cloud Storage の関数は Cloud Storage からの Pub/Sub 通知に基づいており、以下に挙げる類似のイベントタイプに対応しています。

以降のセクションでは、上記の各イベントタイプについて、関数をデプロイしてトリガーする方法を説明します。

オブジェクトのファイナライズ

オブジェクト ファイナライズ イベントは、Cloud Storage オブジェクトの「書き込み」が正常にファイナライズされた時点でトリガーされます。つまり、新しいオブジェクトの作成または既存のオブジェクトの上書きによって、このイベントがトリガーされます。このトリガーにより、アーカイブとメタデータの更新オペレーションは無視されます。

オブジェクトのファイナライズ: 関数のデプロイ

Cloud Storage イベントを処理するサンプル関数を見てみましょう。

Node.js

/**
 * Generic background Cloud Function to be triggered by Cloud Storage.
 *
 * @param {object} file The Cloud Storage file metadata.
 * @param {object} context The event metadata.
 */
exports.helloGCS = (file, context) => {
  console.log(`  Event: ${context.eventId}`);
  console.log(`  Event Type: ${context.eventType}`);
  console.log(`  Bucket: ${file.bucket}`);
  console.log(`  File: ${file.name}`);
  console.log(`  Metageneration: ${file.metageneration}`);
  console.log(`  Created: ${file.timeCreated}`);
  console.log(`  Updated: ${file.updated}`);
};

Python

def hello_gcs(event, context):
    """Background Cloud Function to be triggered by Cloud Storage.
       This generic function logs relevant data when a file is changed.

    Args:
        event (dict):  The dictionary with data specific to this type of event.
                       The `data` field contains a description of the event in
                       the Cloud Storage `object` format described here:
                       https://cloud.google.com/storage/docs/json_api/v1/objects#resource
        context (google.cloud.functions.Context): Metadata of triggering event.
    Returns:
        None; the output is written to Stackdriver Logging
    """

    print('Event ID: {}'.format(context.event_id))
    print('Event type: {}'.format(context.event_type))
    print('Bucket: {}'.format(event['bucket']))
    print('File: {}'.format(event['name']))
    print('Metageneration: {}'.format(event['metageneration']))
    print('Created: {}'.format(event['timeCreated']))
    print('Updated: {}'.format(event['updated']))

Go


// Package helloworld provides a set of Cloud Functions samples.
package helloworld

import (
	"context"
	"fmt"
	"log"
	"time"

	"cloud.google.com/go/functions/metadata"
)

// GCSEvent is the payload of a GCS event.
type GCSEvent struct {
	Kind                    string                 `json:"kind"`
	ID                      string                 `json:"id"`
	SelfLink                string                 `json:"selfLink"`
	Name                    string                 `json:"name"`
	Bucket                  string                 `json:"bucket"`
	Generation              string                 `json:"generation"`
	Metageneration          string                 `json:"metageneration"`
	ContentType             string                 `json:"contentType"`
	TimeCreated             time.Time              `json:"timeCreated"`
	Updated                 time.Time              `json:"updated"`
	TemporaryHold           bool                   `json:"temporaryHold"`
	EventBasedHold          bool                   `json:"eventBasedHold"`
	RetentionExpirationTime time.Time              `json:"retentionExpirationTime"`
	StorageClass            string                 `json:"storageClass"`
	TimeStorageClassUpdated time.Time              `json:"timeStorageClassUpdated"`
	Size                    string                 `json:"size"`
	MD5Hash                 string                 `json:"md5Hash"`
	MediaLink               string                 `json:"mediaLink"`
	ContentEncoding         string                 `json:"contentEncoding"`
	ContentDisposition      string                 `json:"contentDisposition"`
	CacheControl            string                 `json:"cacheControl"`
	Metadata                map[string]interface{} `json:"metadata"`
	CRC32C                  string                 `json:"crc32c"`
	ComponentCount          int                    `json:"componentCount"`
	Etag                    string                 `json:"etag"`
	CustomerEncryption      struct {
		EncryptionAlgorithm string `json:"encryptionAlgorithm"`
		KeySha256           string `json:"keySha256"`
	}
	KMSKeyName    string `json:"kmsKeyName"`
	ResourceState string `json:"resourceState"`
}

// HelloGCS consumes a GCS event.
func HelloGCS(ctx context.Context, e GCSEvent) error {
	meta, err := metadata.FromContext(ctx)
	if err != nil {
		return fmt.Errorf("metadata.FromContext: %v", err)
	}
	log.Printf("Event ID: %v\n", meta.EventID)
	log.Printf("Event type: %v\n", meta.EventType)
	log.Printf("Bucket: %v\n", e.Bucket)
	log.Printf("File: %v\n", e.Name)
	log.Printf("Metageneration: %v\n", e.Metageneration)
	log.Printf("Created: %v\n", e.TimeCreated)
	log.Printf("Updated: %v\n", e.Updated)
	return nil
}

Java

import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import functions.eventpojos.GcsEvent;
import java.util.logging.Logger;

public class HelloGcs implements BackgroundFunction<GcsEvent> {
  private static final Logger logger = Logger.getLogger(HelloGcs.class.getName());

  @Override
  public void accept(GcsEvent event, Context context) {
    logger.info("Event: " + context.eventId());
    logger.info("Event Type: " + context.eventType());
    logger.info("Bucket: " + event.getBucket());
    logger.info("File: " + event.getName());
    logger.info("Metageneration: " + event.getMetageneration());
    logger.info("Created: " + event.getTimeCreated());
    logger.info("Updated: " + event.getUpdated());
  }
}

C#

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Cloud.Storage.V1;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;

namespace HelloGcs
{
    public class Function : ICloudEventFunction<StorageObjectData>
    {
        private readonly ILogger _logger;

        public Function(ILogger<Function> logger) =>
            _logger = logger;

        public Task HandleAsync(CloudEvent cloudEvent, StorageObjectData data, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Event: {event}", cloudEvent.Id);
            _logger.LogInformation("Event Type: {type}", cloudEvent.Type);
            _logger.LogInformation("Bucket: {bucket}", data.Bucket);
            _logger.LogInformation("File: {file}", data.Name);
            _logger.LogInformation("Metageneration: {metageneration}", data.Metageneration);
            _logger.LogInformation("Created: {created:s}", data.TimeCreated?.ToDateTimeOffset());
            _logger.LogInformation("Updated: {updated:s}", data.Updated?.ToDateTimeOffset());
            return Task.CompletedTask;
        }
    }
}

Ruby

require "functions_framework"

FunctionsFramework.cloud_event "hello_gcs" do |event|
  # The event parameter is a CloudEvents::Event::V1 object.
  # See https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1.html
  payload = event.data

  logger.info "Event: #{event.id}"
  logger.info "Event Type: #{event.type}"
  logger.info "Bucket: #{payload['bucket']}"
  logger.info "File: #{payload['name']}"
  logger.info "Metageneration: #{payload['metageneration']}"
  logger.info "Created: #{payload['timeCreated']}"
  logger.info "Updated: #{payload['updated']}"
end

関数をデプロイするには、サンプルコードがあるディレクトリで次のコマンドを実行します。

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs10 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize
優先する Node.js のバージョンを指定するには、--runtime フラグに次の値を使用します。
  • nodejs10
  • nodejs12
  • nodejs14(公開プレビュー)

Python

gcloud functions deploy hello_gcs \
--runtime python38 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize
優先する Python バージョンを指定するには、--runtime フラグに次の値を使用します。
  • python37
  • python38
  • python39(公開プレビュー)

Go

gcloud functions deploy HelloGCS \
--runtime go113 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize
優先する Go バージョンを指定するには、--runtime フラグに次の値を使用します。
  • go111(サポート終了)
  • go113

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java11 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

C#

gcloud functions deploy csharp-gcs-function \
--entry-point HelloGcs.Function \
--runtime dotnet3 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

Ruby

gcloud functions deploy hello_gcs --runtime ruby26 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize
優先する Ruby バージョンを指定するには、--runtime フラグに次の値を使用します。
  • ruby26
  • ruby27

YOUR_TRIGGER_BUCKET_NAME は、関数をトリガーする Cloud Storage バケットの名前です。

オブジェクトのファイナライズ: 関数のトリガー

関数をトリガーするには、以下の手順に従います。

  1. サンプルコードがあるディレクトリに空の gcf-test.txt ファイルを作成します。

  2. 関数をトリガーするために、Cloud Storage にファイルをアップロードします。

    gsutil cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME
    

    YOUR_TRIGGER_BUCKET_NAME は、テストファイルをアップロードする Cloud Storage バケットの名前です。

  3. 実行が完了したことをログで確認します。

    gcloud functions logs read --limit 50
    

オブジェクトの削除

オブジェクト削除イベントは、バージョニング非対応バケットには特に便利です。このイベントがトリガーされるのは、オブジェクトの古いバージョンが削除された時点です。さらに、オブジェクトが上書きされた場合にもトリガーされます。また、オブジェクト削除トリガーをバージョニング対応バケットで使用することもできます。この場合、オブジェクトのバージョンが完全に削除された時点でトリガーされます。

オブジェクトの削除: 関数のデプロイ

ファイナライズの例と同じサンプルコードを使用して、トリガー イベントとしてオブジェクトの削除を行う関数をデプロイします。サンプルコードがあるディレクトリで次のコマンドを実行します。

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs10 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete
優先する Node.js のバージョンを指定するには、--runtime フラグに次の値を使用します。
  • nodejs10
  • nodejs12
  • nodejs14(公開プレビュー)

Python

gcloud functions deploy hello_gcs \
--runtime python38 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete
優先する Python バージョンを指定するには、--runtime フラグに次の値を使用します。
  • python37
  • python38
  • python39(公開プレビュー)

Go

gcloud functions deploy HelloGCS \
--runtime go113 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete
優先する Go バージョンを指定するには、--runtime フラグに次の値を使用します。
  • go111(サポート終了)
  • go113

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java11 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

C#

gcloud functions deploy csharp-gcs-function \
--entry-point HelloGcs.Function \
--runtime dotnet3 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

Ruby

gcloud functions deploy hello_gcs --runtime ruby26 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete
優先する Ruby バージョンを指定するには、--runtime フラグに次の値を使用します。
  • ruby26
  • ruby27

YOUR_TRIGGER_BUCKET_NAME は、関数をトリガーする Cloud Storage バケットの名前です。

オブジェクトの削除: 関数のトリガー

関数をトリガーするには、以下の手順に従います。

  1. サンプルコードがあるディレクトリに空の gcf-test.txt ファイルを作成します。

  2. バケットがバージョニング対応でないことを確認します。

    gsutil versioning set off gs://YOUR_TRIGGER_BUCKET_NAME
    
  3. Cloud Storage にファイルをアップロードします。

    gsutil cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME
    

    YOUR_TRIGGER_BUCKET_NAME は、テストファイルをアップロードする Cloud Storage バケットの名前です。この時点ではまだ関数は実行されません。

  4. ファイルを削除して関数をトリガーします。

    gsutil rm gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt
    
  5. 実行が完了したことをログで確認します。

    gcloud functions logs read --limit 50
    

関数の実行が完了するまでに時間がかかる場合があることに注意してください。

オブジェクトのアーカイブ

オブジェクト アーカイブ イベントは、バージョニング対応バケットでのみ使用できます。このイベントがトリガーされるのは、オブジェクトの古いバージョンがアーカイブされた時点です。つまり、オブジェクトが上書きまたは削除されると、アーカイブ イベントがトリガーされます。

オブジェクトのアーカイブ: 関数のデプロイ

ファイナライズの例と同じサンプルコードを使用して、トリガー イベントとしてオブジェクトのアーカイブを行う関数をデプロイします。サンプルコードがあるディレクトリで次のコマンドを実行します。

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs10 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive
優先する Node.js のバージョンを指定するには、--runtime フラグに次の値を使用します。
  • nodejs10
  • nodejs12
  • nodejs14(公開プレビュー)

Python

gcloud functions deploy hello_gcs \
--runtime python38 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive
優先する Python バージョンを指定するには、--runtime フラグに次の値を使用します。
  • python37
  • python38
  • python39(公開プレビュー)

Go

gcloud functions deploy HelloGCS \
--runtime go113 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive
優先する Go バージョンを指定するには、--runtime フラグに次の値を使用します。
  • go111(サポート終了)
  • go113

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java11 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

C#

gcloud functions deploy csharp-gcs-function \
--entry-point HelloGcs.Function \
--runtime dotnet3 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

Ruby

gcloud functions deploy hello_gcs --runtime ruby26 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive
優先する Ruby バージョンを指定するには、--runtime フラグに次の値を使用します。
  • ruby26
  • ruby27

YOUR_TRIGGER_BUCKET_NAME は、関数をトリガーする Cloud Storage バケットの名前です。

オブジェクトのアーカイブ: 関数のトリガー

関数をトリガーするには、以下の手順に従います。

  1. サンプルコードがあるディレクトリに空の gcf-test.txt ファイルを作成します。

  2. バケットのバージョニングが有効になっていることを確認します。

    gsutil versioning set on gs://YOUR_TRIGGER_BUCKET_NAME
    
  3. Cloud Storage にファイルをアップロードします。

    gsutil cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME
    

    YOUR_TRIGGER_BUCKET_NAME は、テストファイルをアップロードする Cloud Storage バケットの名前です。この時点ではまだ関数は実行されません。

  4. ファイルをアーカイブして関数をトリガーします。

    gsutil rm gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt
    
  5. 実行が完了したことをログで確認します。

    gcloud functions logs read --limit 50
    

オブジェクト メタデータの更新

メタデータ更新イベントは、既存のオブジェクトのメタデータが更新された時点でトリガーされます。

オブジェクト メタデータの更新: 関数のデプロイ

ファイナライズの例と同じサンプルコードを使用して、トリガー イベントとしてメタデータの更新を行う関数をデプロイします。サンプルコードがあるディレクトリで次のコマンドを実行します。

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs10 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate
優先する Node.js のバージョンを指定するには、--runtime フラグに次の値を使用します。
  • nodejs10
  • nodejs12
  • nodejs14(公開プレビュー)

Python

gcloud functions deploy hello_gcs \
--runtime python38 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate
優先する Python バージョンを指定するには、--runtime フラグに次の値を使用します。
  • python37
  • python38
  • python39(公開プレビュー)

Go

gcloud functions deploy HelloGCS \
--runtime go113 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate
優先する Go バージョンを指定するには、--runtime フラグに次の値を使用します。
  • go111(サポート終了)
  • go113

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java11 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

C#

gcloud functions deploy csharp-gcs-function \
--entry-point HelloGcs.Function \
--runtime dotnet3 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

Ruby

gcloud functions deploy hello_gcs --runtime ruby26 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate
優先する Ruby バージョンを指定するには、--runtime フラグに次の値を使用します。
  • ruby26
  • ruby27

YOUR_TRIGGER_BUCKET_NAME は、関数をトリガーする Cloud Storage バケットの名前です。

オブジェクト メタデータの更新: 関数のトリガー

関数をトリガーするには、以下の手順に従います。

  1. サンプルコードがあるディレクトリに空の gcf-test.txt ファイルを作成します。

  2. バケットがバージョニング対応でないことを確認します。

    gsutil versioning set off gs://YOUR_TRIGGER_BUCKET_NAME
    
  3. Cloud Storage にファイルをアップロードします。

    gsutil cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME
    

    YOUR_TRIGGER_BUCKET_NAME は、テストファイルをアップロードする Cloud Storage バケットの名前です。この時点ではまだ関数は実行されません。

  4. ファイルのメタデータを更新します。

    gsutil -m setmeta -h "Content-Type:text/plain" gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt
    
  5. 実行が完了したことをログで確認します。

    gcloud functions logs read --limit 50
    

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトの削除

課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除するには:

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

Cloud Function の削除

Cloud Functions を削除しても、Cloud Storage に保存されたリソースは削除されません。

このチュートリアルで作成した Cloud Function を削除するには、次のコマンドを実行します。

Node.js

gcloud functions delete helloGCS 

Python

gcloud functions delete hello_gcs 

Go

gcloud functions delete HelloGCS 

Java

gcloud functions delete java-gcs-function 

C#

gcloud functions delete csharp-gcs-function 

Ruby

gcloud functions delete hello_gcs 

Google Cloud Console から Cloud Functions を削除することもできます。

次のステップ