LoginSignup
0
0

More than 3 years have passed since last update.

AWS スイッチ先(他アカウント)のサービスを制御

Last updated at Posted at 2020-03-31

目的

  • ソースにアクセスキーを書かない
  • ローカルにセキュリティキーをそのまま置かない <- 開発環境
  • スイッチ先のRDSに接続したい、S3のデータを取りたい ...

プロフィール準備

ローカルまたは運用サーバにAWS1のUSERのプロフィールを作成
(ECSのようなサーバレスは環境変数にSSMを利用)

STS(Security Token Service)を使用してスイッチ先のクレデンシャル取得

クレデンシャル取得フロー

AWS1(IAM USER) -> スイッチ先:AWS{2-N}(IAM ROLE)

IAM

AWS1 IAM USER

arn:aws:iam::012345678:user/aspnet
ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

スイッチ先 IAM Role

arn:aws:iam::123456789:role/aspnet
信頼関係

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::012345678:user/aspnet",
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

例).NET Application

プロファイル追加

Set-AWSCredentials -AccessKey XXXXX -SecretKey XXXXX -StoreAs aspnet -ProfileLocation C:\workspace\ps1\credentials

app.config

<appSettings>
  <add key="AwsRoleArnBaseProfile" value="aspnet"/> ← IAM USER
  <add key="AwsRoleArnAws1" value="arn:aws:iam::123456789:role/aspnet"/> ← スイッチ先Role
  <add key="AwsRoleArnAws2" value="arn:aws:iam::234567891:role/aspnet"/>
  ...
  <!-- サーバ側はユーザプロファイルではないフォルダを指定 -->
  <add key="AWSProfilesLocation" value="C:\workspace\ps1\credentials" />
  ...

</appSettings>

AmazonConfig.cs

using Amazon;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;

//スイッチ先
public enum AccountNo
{
    AWS1 = 1,
    AWS2 = 2,
    ...
}

function ... (AccountNo accountNo){
    var roleArn = $"AwsRoleArnAws{(byte)accountNo}";    //accountNo: 1~N
    var chain = new CredentialProfileStoreChain();
    AWSCredentials awsCredentials;
    var profile =  System.Configuration.ConfigurationManager.AppSettings["AwsRoleArnBaseProfile"];
    if (chain.TryGetAWSCredentials(profile, out awsCredentials))    
    {
        var sts = new  AmazonSecurityTokenServiceClient(awsCredentials);
        var arn =  System.Configuration.ConfigurationManager.AppSettings[roleArn];
        var stsreq = new AssumeRoleRequest
        {
            RoleArn = arn,
            RoleSessionName =  $"{(byte)accountNo}_{region.SystemName}_{DateTime.Now.ToString("yyyyMMddHHmmsssss")}",
            DurationSeconds = 900
        };
        var stsres = sts.AssumeRole(stsreq);
        StsCredentials = stsres.Credentials;    
    }
}

Ec2Service.cs

using Amazon;
using Amazon.EC2;
using Amazon.EC2.Model;

...
aconf = new AmazonConfig(accountNo);
IAmazonEC2 client = new AmazonEC2Client(aconf.StsCredentials,  RegionEndpoint.APNortheast1);
...

参考

バグ対応

リリースすると本番環境のみ、下記のエラーが、

アセンブリ 'AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604' から型 'Amazon.Runtime.SharedInterfaces.ICoreAmazonSTS_WebIdentity' を読み込めませんでした。
説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。

例外の詳細: System.TypeLoadException: アセンブリ 'AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604' から型 'Amazon.Runtime.SharedInterfaces.ICoreAmazonSTS_WebIdentity' を読み込めませんでした。

STSを実装したアセンブリを参照するプロジェクトに古いAWSSDK.SecurityTokenが残っていた。削除で解決。半日飛んだー
https://hydracards.hydratecinc.com/cards/card-839

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0