すべてのプロダクト
Search
ドキュメントセンター

Elastic Container Instance:API オペレーションの呼び出しによるインスタンス RAM ロールの使用

最終更新日:Dec 28, 2024

エラスティックコンテナインスタンスにインスタンス RAM ロールを割り当てることができます。その後、エラスティックコンテナインスタンスにデプロイされたアプリケーションから、Security Token Service (STS) クレデンシャルに基づいて他の Alibaba Cloud サービスの API にアクセスできます。このトピックでは、API オペレーションを呼び出してインスタンス RAM ロールを作成し、RAM ロールに権限ポリシーをアタッチし、エラスティックコンテナインスタンスに RAM ロールを割り当てる方法について説明します。

シナリオ

エラスティックコンテナインスタンスにデプロイされたアプリケーションは、Alibaba Cloud アカウントまたは RAM ユーザーの AccessKey ペアを使用して、オブジェクトストレージサービス (OSS)、仮想プライベートクラウド (VPC)、ApsaraDB RDS などの他の Alibaba Cloud サービスの API にアクセスできます。API オペレーションを簡単に呼び出すために、一部のユーザーは AccessKey ペアをインスタンスに書き込みます (例: AccessKey ペアを構成ファイルに書き込む)。この方法では、情報漏洩や複雑なメンテナンスなどの問題が発生する可能性があります。また、この方法では、必要以上の権限が付与される可能性があります。インスタンス RAM ロールは、このような問題を防ぐことができます。

RAM ロールは、特定の権限を持ち、エラスティックコンテナインスタンスがアサインできる仮想ユーザーです。これにより、インスタンスは対応する権限を取得できます。RAM ロールを使用すると、エラスティックコンテナインスタンスに AccessKey ペアを保存する必要がなくなります。インスタンスの権限を変更する場合、インスタンスがアサインされている RAM ロールの権限のみを変更する必要があります。これにより、AccessKey ペアの漏洩のリスクが軽減されます。RAM ロールの詳細については、「RAM ロールの概要」を参照してください。

手順

API オペレーションを呼び出してインスタンス RAM ロールを使用するには、次の操作を実行します。

  1. インスタンス RAM ロールの作成

    CreateRole オペレーションを呼び出して、インスタンス RAM ロールを作成できます。リクエストでは、RAM ロールをアサインする信頼できるエンティティを Elastic Container Instance に、信頼できるサービスを Elastic Compute Service (ECS) に設定する必要があります。

  2. インスタンス RAM ロールへの権限ポリシーのアタッチ

    CreatePolicy オペレーションを呼び出してポリシーを作成し、AttachPolicyToRole オペレーションを呼び出してポリシーをインスタンス RAM ロールにアタッチできます。

  3. (オプション) RAM ユーザーにインスタンス RAM ロールの使用を許可する

    RAM ユーザーを使用してエラスティックコンテナインスタンスを作成し、インスタンスにインスタンス RAM ロールを割り当てる前に、RAM ユーザーにインスタンス RAM ロールの使用を許可する必要があります。

  4. エラスティックコンテナインスタンスへのインスタンス RAM ロールの割り当て

    CreateContainerGroup オペレーションを呼び出してエラスティックコンテナインスタンスを作成するときに、RamRoleName パラメーターを使用して、インスタンス RAM ロールをエラスティックコンテナインスタンスに割り当てることができます。これにより、インスタンスは RAM ロールの権限を取得します。1 つのエラスティックコンテナインスタンスに割り当てることができるインスタンス RAM ロールは 1 つだけです。

  5. STS トークンの取得

    エラスティックコンテナインスタンスにインスタンス RAM ロールを割り当てた後、エラスティックコンテナインスタンス上のアプリケーションから他の Alibaba Cloud サービスの API にアクセスするには、インスタンスメタデータを使用して STS トークンを取得する必要があります。

インスタンス RAM ロールの作成

CreateRole オペレーションを呼び出して、インスタンス RAM ロールを作成します。パラメーターの詳細については、「CreateRole」を参照してください。

RoleName パラメーターを使用してロール名を指定できます。この例では、ECIRamRoleTest ロール名が使用されています。次に、次のコードに基づいて AssumeRolePolicyDocument を構成します。

{
"Statement": [
{
  "Action": "sts:AssumeRole",
  "Effect": "Allow",
  "Principal": {
    "Service": [
      "ecs.aliyuncs.com"
    ]
  }
}
],
"Version": "1"
}

インスタンス RAM ロールへのポリシーのアタッチ

  1. CreatePolicy オペレーションを呼び出して、カスタムポリシーを作成します。

    リクエストで次のパラメーターを構成します。

    • PolicyName: ポリシーの名前。この例では、ECIRamRoleTestPolicy 名が使用されています。

    • PolicyDocument: ポリシーの詳細。

      {
           "Statement": [
               {
               "Action": [
                   "oss:Get*",
                   "oss:List*"
               ],
               "Effect": "Allow",
               "Resource": "*"
               }
           ],
           "Version": "1"
       }

    詳細については、「CreatePolicy」を参照してください。

  2. AttachPolicyToRole オペレーションを呼び出して、ポリシーを RAM ロールにアタッチします。

    リクエストで次のパラメーターを構成します。

    • PolicyName: ポリシーの名前。この例では、ECIRamRoleTestPolicy 名が使用されています。

    • PolicyType: ポリシーのタイプ。このパラメーターを Custom に設定します。

    • RoleName: RAM ロールの名前。この例では、ECIRamRoleTest 名が使用されています。

    詳細については、「AttachPolicyToRole」を参照してください。

RAM ユーザーにインスタンス RAM ロールの使用を許可する

RAM ユーザーにインスタンス RAM ロールを使用させる場合は、インスタンス RAM ロールの ram:PassRole 権限を RAM ユーザーに付与する必要があります。RAM ユーザーに ram:PassRole 権限がない場合、RAM ユーザーはロールポリシーで指定された権限を行使できません。

  1. 管理権限を持つ RAM ユーザーまたは Alibaba Cloud アカウントを使用して、RAM コンソール にログオンします。

  2. RAM ユーザーにインスタンス RAM ロールの使用を許可します。

    RAM ユーザーにインスタンス RAM ロールの使用を許可するには、次のカスタムポリシーを作成し、RAM ユーザーにアタッチします。ECIRamRoleTest はインスタンス RAM ロールの名前です。RAM ロールの ram:PassRole 権限は、RAM ユーザーに付与されます。詳細については、「RAM ユーザーへの権限の付与」を参照してください。

    {
       "Statement": [
        {
          "Effect": "Allow",
          "Action": "ram:PassRole",
          "Resource": "acs:ram:*:*:role/ECIRamRoleTest" 
        }
      ],
      "Version": "1"
    }                

エラスティックコンテナインスタンスへのインスタンス RAM ロールの割り当て

CreateContainerGroup オペレーションを呼び出してエラスティックコンテナインスタンスを作成するときに、RamRoleName パラメーターを使用して RAM ロールを指定できます。詳細については、「CreateContainerGroup」を参照してください。

説明

1 つのエラスティックコンテナインスタンスに割り当てることができるインスタンス RAM ロールは 1 つだけです。インスタンス RAM ロールがエラスティックコンテナインスタンスに割り当てられている場合、インスタンスに別のインスタンス RAM ロールを割り当てようとすると、エラーメッセージが表示されます。

STS トークンの取得

ポッドのメタデータ URL にアクセスして、RAM ロールの STS トークンを取得できます。STS トークンを使用して、RAM ロールの権限を実行し、リソースを使用できます。STS トークンは自動的かつ定期的に更新されます。

curl http://100.100.100.200/latest/meta-data/ram/security-credentials/${your_ram_role_name}

${your_ram_role_name} を実際の RAM ロールの名前に置き換えます。この例では、ECIRamRoleTest が RAM ロールの名前として使用されています。サンプルコマンド:

curl http://100.100.100.200/latest/meta-data/ram/security-credentials/ECIRamRoleTest

コマンド出力で STS トークンを取得できます。例:

{
  "AccessKeyId" : "STS.******",
  "AccessKeySecret" : "******",
  "Expiration" : "2023-06-22T19:13:58Z",
  "SecurityToken" : "******",
  "LastUpdated" : "2023-06-22T13:13:58Z",
  "Code" : "Success"
}

STS トークンに基づいて Alibaba Cloud サービスにアクセスする

次の例は、SDK for Go を使用して、STS トークンを使用して Alibaba Cloud サービスにアクセスする方法を示しています。この例では、取得した STS トークンを使用して OSS バケットにアクセスし、バケット内のすべてのリストされたオブジェクトを表示できます。

説明

次のサンプルコードは、STS トークンを使用して Alibaba Cloud サービスにアクセスする方法を示すためにのみ使用されます。実際のシナリオでは、ビジネス要件に基づいてコードを記述してください。詳細については、使用するクラウドサービスの SDK を参照してください。

package main

import (
	"encoding/json"
	"flag"
	"log"
	"os/exec"
	"github.com/aliyun/aliyun-oss-go-sdk/oss" // OSS Go SDK をインポートします
)

const (
	securityCredUrl = "http://100.100.100.200/latest/meta-data/ram/security-credentials/"
)

var (
	ossEndpoint   string
	ossBucketName string
)

func init() {
	flag.StringVar(&ossEndpoint, "endpoint", "oss-cn-hangzhou-internal.aliyuncs.com", "OSS エンドポイントを入力してください。内部エンドポイントを推奨します。例: oss-cn-hangzhou-internal.aliyuncs.com")
	flag.StringVar(&ossBucketName, "bucket", "", "OSS バケット名を入力してください")
}

type AssumedRoleUserCredentialsWithServiceIdentity struct {
	AccessKeyId     string `json:"AccessKeyId" xml:"AccessKeyId"`
	AccessKeySecret string `json:"AccessKeySecret" xml:"AccessKeySecret"`
	Expiration      string `json:"Expiration" xml:"Expiration"`
	SecurityToken   string `json:"SecurityToken" xml:"SecurityToken"`
	LastUpdated     string `json:"LastUpdated" xml:"LastUpdated"`
	Code            string `json:"Code" xml:"Code"`
}

func main() {
	flag.Parse()

	if ossEndpoint == "" {
		log.Fatal("OSS エンドポイントを入力してください。例: oss-cn-hangzhou-internal.aliyuncs.com")
	}
	if ossBucketName == "" {
		log.Fatal("OSS バケット名を入力してください")
	}

	output, err := exec.Command("curl", securityCredUrl).Output()
	if err != nil {
		log.Fatalf("メタサーバーから RAM ロールの名前を取得できませんでした: %s", err)
	}

	output, err = exec.Command("curl", securityCredUrl+string(output)).Output()
	if err != nil {
		log.Fatalf("メタサーバーからセキュリティクレデンシャルを取得できませんでした: %s", err)
	}

	authServiceIdentity := new(AssumedRoleUserCredentialsWithServiceIdentity)
	if err := json.Unmarshal(output, authServiceIdentity); err != nil {
		log.Fatalf("AssumedRoleUserCredentialsWithServiceIdentity に Unmarshal できませんでした: %s", err)
	}

	// OSS クライアントインスタンスを作成します。本番環境で OSS クライアントを使用する場合は、STS トークンの有効期限が切れ、Alibaba Cloud サービスへのアクセスに失敗しないように、OSS クライアントを定期的に更新する必要があります。
	ossClient, err := oss.New(ossEndpoint, authServiceIdentity.AccessKeyId,
		authServiceIdentity.AccessKeySecret, oss.SecurityToken(authServiceIdentity.SecurityToken))
	if err != nil {
		log.Fatalf("新しい OSS クライアントを作成できませんでした: %s", err)
	}

	// バケットを取得します。
	bucket, err := ossClient.Bucket(ossBucketName)
	if err != nil {
		log.Fatalf("バケット %q を取得できませんでした: %s", ossBucketName, err)
	}

	// バケット内のオブジェクトを一覧表示します。
	marker := ""
	for {
		lsRes, err := bucket.ListObjects(oss.Marker(marker))
		if err != nil {
			log.Fatalf("バケット %q からオブジェクトを一覧表示できませんでした: %s", ossBucketName, err)
		}
		// リストされたオブジェクトを表示します。デフォルトでは、一度に最大 100 個のオブジェクトが返されます。
		for _, object := range lsRes.Objects {
			log.Println("Bucket: ", object.Key)
		}
		if lsRes.IsTruncated {
			marker = lsRes.NextMarker
		} else {
			break
		}
	}
}