Quantcast
Channel: 技術 –サーバーワークスエンジニアブログ
Viewing all 1210 articles
Browse latest View live

俺的CloudFormation テンプレートの便利な定義 3選

$
0
0

こんにちは、技術4課の多田です。

CloudFormation を最近業務でよく使うのですが、自分が使っていてこの定義は便利だなと思ったものがあります。

今回は、その定義 3つをまとめていきます。

1. Mappings を使ってリソースタグをまとめて設定
2. Metadata を使って入力パラメータを見やすく管理する
3. Condition を使って条件判定する

Mappings を使ってリソースタグをまとめて設定

Mappings を使うと、キーと名前付きの一連の値とが対応づけられます。

Mappings

業務で、大量の AWS リソースに対してタグ付けを行なっているのですが、固定したタグの値が決まっているのであれば、この Mappings を使えば統一的にタグ設定ができます。

例えば、 CloudFormation のコードで以下のように定義します。

下記の定義で、NameタグがEC2_TEST、EnvironmentタグがDEV、SystemIdタグがTESTとタグづけされます。

AWSTemplateFormatVersion: 2010-09-09
Mappings:
  TagsMap:
    EnvName:
      Name: "EC2_TEST"
      Environment: "DEV"
      SystemId: "TEST"
Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: ami-0d7ed3ddb85b521a6
      InstanceType: t3.small
      Tags:
        -
          Key: Name
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Name
        - Key: Environment
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Environment
        - Key: SystemId
          Value: !FindInMap
            - TagsMap
            - EnvName
            - SystemId

Metadata を使って入力パラメータを見やすく管理する

Metadata の AWS::CloudFormation::Interface メタデータキーを使うと、テンプレート内のパラメータの順番を制御することができます。

AWS::CloudFormation::Interface

テンプレート内で多くのパラメータを扱わなければいけない、かつCloudFormation スタックを画面から作成を行うならばこのオプションを使うのがオススメです。

例えば、以下のテンプレートがあったとします。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  InstanceType:
    Type: String
    Description: (Required) Enter InstanceType.
  ImageId:
    Type: "AWS::EC2::Image::Id"
    Description: (Required) Enter AMI ID.
  DiskSize:
      Type: String
      Description:  (Required) Enter Disk Size.
Mappings:
  TagsMap:
    EnvName:
      Name: "EC2_TEST"
      Environment: "DEV"
      SystemId: "TEST"
Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            DeleteOnTermination: true
            VolumeSize: !Ref DiskSize
            VolumeType: gp2
      DisableApiTermination: false
      Tags:
        -
          Key: Name
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Name
        - Key: Environment
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Environment
        - Key: SystemId
          Value: !FindInMap
            - TagsMap
            - EnvName
            - SystemId

上記の場合、スタック作成時に次のようなランダムな羅列になります。 

この例ではパラメーターが少なくていいですが、ランダムに多数のパラメーターが羅列されるより見やすい形に変更した方が利用しやすいです。

この並びを好みの順番にしたい場合は、次のように定義します。

AWSTemplateFormatVersion: 2010-09-09
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: EC2 Configuration
        Parameters:
          - ImageId
          - InstanceType
          - DiskSize
Parameters:
  InstanceType:
    Type: String
    Description: (Required) Enter InstanceType.
  ImageId:
    Type: "AWS::EC2::Image::Id"
    Description: (Required) Enter AMI ID.
  DiskSize:
      Type: String
      Description:  (Required) Enter Disk Size.
Mappings:
  TagsMap:
    EnvName:
      Name: "EC2_TEST"
      Environment: "DEV"
      SystemId: "TEST"
Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            DeleteOnTermination: true
            VolumeSize: !Ref DiskSize
            VolumeType: gp2
      DisableApiTermination: false
      Tags:
        -
          Key: Name
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Name
        - Key: Environment
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Environment
        - Key: SystemId
          Value: !FindInMap
            - TagsMap
            - EnvName
            - SystemId

上記に指定すると、ParameterGroupsParameters で指定した順番に羅列されています。

Condition を使って条件判定する

Condition句を使うと、特定の条件の時に、テンプレート内のパラメータ値を自動で変更可能になります。

Conditions

条件の組み込み関数として、次の定義が可能です。

  • Fn::And : 指定されたすべての条件が true に評価された場合は true を返し、条件のいずれかが false に評価された場合は false を返す
  • Fn::Equals : 2つの値が等しいかどうかを比較し、2つの値が同じ場合は true を返し、同じでない場合は false を返す
  • Fn::If : 指定された条件が true に評価された場合は 1 つの値を返し、指定された条件が false に評価された場合はもう 1 つの値を返す
  • Fn::Not : false と評価された条件に対しては、true を返し、true と評価された条件に対しては、false を返す
  • Fn::Or : 指定された条件のいずれかが true に評価された場合は true を返し、条件のすべてが false に評価された場合は false を返す

具体的に、テンプレートでの定義例を書きます。

下記のように設定することで、Modeパラメーターがprodならば、EBSボリュームはテンプレートが削除されても残りますが、testならば、EBSボリュームは削除されます。 このように使えるので、テンプレート内でのパラメータの使い分けを行う時に便利です。

AWSTemplateFormatVersion: 2010-09-09
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: EC2 Configuration
        Parameters:
          - ImageId
          - InstanceType
          - DiskSize
          - Mode
Parameters:
  InstanceType:
    Type: String
    Description: (Required) Enter InstanceType.
  ImageId:
    Type: "AWS::EC2::Image::Id"
    Description: (Required) Enter AMI ID.
  DiskSize:
      Type: String
      Description:  (Required) Enter Disk Size.
  Mode:
    Default: prod
    AllowedValues:
      - prod
      - test
    Type: String
    Description: (Required) Select mode.
Conditions:
  EC2RunningMode: !Equals [ !Ref Mode, prod]

Mappings:
  TagsMap:
    EnvName:
      Name: "EC2_TEST"
      Environment: "DEV"
      SystemId: "TEST"
Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            DeleteOnTermination: !If [EC2RunningMode, false, true]
            VolumeSize: !Ref DiskSize
            VolumeType: gp2
      DisableApiTermination: false
      Tags:
        -
          Key: Name
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Name
        - Key: Environment
          Value: !FindInMap
            - TagsMap
            - EnvName
            - Environment
        - Key: SystemId
          Value: !FindInMap
            - TagsMap
            - EnvName
            - SystemId

まとめ

私が業務で扱った CloudFormation テンプレート内の定義で便利だと思ったものを紹介しました。

CloudFormation は自動化していくにあたって欠かせないサービスになるので、活用していきまた別の Tips があったらブログで紹介します。


CloudFormation で AWS Marketplace の AMIを利用する方法

$
0
0

技術4課の多田です。こんにちは。

小ネタですが、 CloudFormation で AWS Marketplace の AMI を指定する機会があったので、やり方をまとめていきます。

AWS Marketplace での AMI 利用方法

ドキュメントに AWS Marketplace での AMI 利用方法が記載されてますが、利用したい AMI をサブスクライブする必要があります。

顧客は AWS Marketplace でソリューションの選択を参照し、1 回のクリックでサブスクライブして、提供した AWS CloudFormation テンプレートを使用して、デプロイできます。

実際にサブスクライブする

今回、 CentOS の AMI を使いたいため、該当の AWS Marketplace のページに移動します。

早速、まずは利用したい下記のソリューションをサブスクライブします。「Continu to Subscribe」をクリックします。

次にサブスクライブするかを確認されるため「Accept Terms」をクリックします。これで、サブスクライブが完了です。

そして、 CloudFormation で利用する AMI ID を確認します。「Continue to Configuration」をクリックします。

「Software Vertion」と「Region」を選択すると、AMI ID が表示されますので、メモしておきます。

確認した AMI ID で CloudFormaiton スタックを作成してみます。テンプレートはとてもシンプルなものにしました。

AWSTemplateFormatVersion: 2010-09-09

Resources:
  EC2TEST:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: ami-045f38c93733dd48d #メモしたAMI ID
      InstanceType: t3.micro

スタックを作成してみたところ成功しました。

まとめ

簡単になりますが、 CloudFormation の AWS Marketplace でのAMI利用についてまとめました。

ポイントは AWS Marketplace でのサブスクライブと AMI IDの確認ができていれば、CloudFormation で利用できます。

何かお役に立つ情報があれば幸いです。

CloudFront と Lambda@Edge による S3 内コンテンツの Basic 認証を Serverless Framework で実現する

$
0
0



はじめに

技術一課の山中です。
S3 のコンテンツに対して CloudFront と Lambda@Edge を利用して Basic 認証をかけたいとの要望があったので、検証してみました。

事前準備

S3 バケットの作成

静的コンテンツを配置するための S3 バケットを作成してください。
作成後、配信するコンテンツを配置します。

Serverless Framework のインストール

以下を実行し Serverless Framework をインストールしておいてください。

$ npm install serverless -g

セットアップ

Serverless Framework の設定

今回は以下 のプラグインを利用します。

このプラグインを利用することで Serverless Framework で Lambda@Edge をデプロイすることができます。

npm install --save-dev --save-exact @silvermine/serverless-plugin-cloudfront-lambda-edge

具体的な利用方法は、プラグインの README を参照ください。
serverless.yml は以下のように記載しました。

また、 config.yml を作成しバケット名を外出ししています。

s3:
  bucket_name: your-bucket-name

your-bucket-name は自身のバケット名に変更してください。

Basic 認証用コード作成

今回この検証を行っていて知ったことは以下です。
やっぱり何事も事前調査は大事ですよね。

コードは以下の方のものをそのまま使わせていただきました。
これをコピーして auth.js として保存します。

authUser にユーザ名、 authPass にパスワードを記載します。

デプロイ

準備が終わったので、デプロイします。

$ sls deploy

以下のように表示されるとデプロイ完了です。

Serverless: Checking Stack update progress...
........................
Serverless: Stack update finished...
Service Information
service: basic-auth-sample
stage: dev
region: us-east-1
stack: basic-auth-sample-dev
resources: 8
api keys:
  None
endpoints:
  None
functions:
  basic-auther: basic-auth-sample-dev-basic-auther
layers:
  None

試してみる

マネジメントコンソールから作成された CloudFront の URL を確認しアクセスしてみましょう!


想定通り Basic 認証のポップアップが表示されています。
Lambda に設定したユーザ名とパスワードを入力し Sign In ボタンをクリックすると

S3 に保存した HTML ファイルが表示されています!
ちなみに、 Basic 認証画面で Cancel ボタンをクリックすると以下の画面となり、コンテンツが表示されないことがわかります。

おわりに

Basic 認証を必要とする機会はそこまで多くはないと思いますが、 Serverless Framework を利用すると簡単に実現可能ですので、かなり便利ですね!

AWS CLIでEBSボリュームにタグ付けする

$
0
0

こんにちは、技術3課の城です。
3月で期が変わりまして、技術4課⇒技術3課に異動となりました。

さて、以前に当社渡辺がということで下記紹介してますが、AWS CLIでも簡単にやれますよ、というところをお見せしたいと思います。
EBSにタグをつけるスクリプトを作った

渡辺のものとは若干趣向を変えて、NameタグからEBSのボリュームIDを取得、タグ付けをする、といった内容をご紹介します。
具体例としてEC2にアタッチされた2つのEBSボリュームのタグ設定について、やってみたいと思います。

環境

実行環境はWindows10端末のWSLで、詳細は下記です。

$ cat /etc/issue | head -1
Ubuntu 16.04.3 LTS \n \l

$ bash --version -v | head -1
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

$ aws --version
aws-cli/1.16.101 Python/3.5.2 Linux/4.4.0-17763-Microsoft botocore/1.12.91

変数の設定

利用するユーザープロファイル、リージョンを指定します。
ユーザープロファイルについてm詳細はこちらのブログにて説明しています。

export AWS_DEFAULT_PROFILE="dev-admin"
export AWS_DEFAULT_REGION="ap-northeast-1"

変数の設定(Nameタグの値)

対象のNameタグの値を変数に設定します。

TAG_NAME="TEST-20190304"

変数の設定(EBSに設定するタグの値)

EBSに設定するタグの値を変数に設定します。

TAG_APPLICATION="WEB"
TAG_OWNER="JO"
TAG_STAGE="Production"

VolumeIDの取得

対象となるEBSのVolumeIDを取得します。

EC2_VOLUME_IDS=$( \
  aws ec2 describe-instances \
    --filter "Name=tag:Name,Values=${TAG_NAME}" \
    --query 'Reservations[].Instances[].BlockDeviceMappings[].Ebs[].VolumeId' \
    --output text \
) \
&& echo ${EC2_VOLUME_IDS}

結果(例)

vol-0b43716d783e44288 vol-09947341dba029cb3

事前確認

事前にタグが設定されていないことを確認します。

aws ec2 describe-volumes \
  --volume-ids ${EC2_VOLUME_IDS}

結果(例)

{
    "Volumes": [
        {
            "CreateTime": "2019-03-03T07:53:23.807Z",
            "Iops": 150,
            "SnapshotId": "snap-0490dd2cb58cf07c6",
            "State": "in-use",
            "VolumeType": "gp2",
            "Size": 50,
            "VolumeId": "vol-0b43716d783e44288",
            "AvailabilityZone": "ap-northeast-1a",
            "Attachments": [
                {
                    "AttachTime": "2019-03-03T07:53:23.000Z",
                    "InstanceId": "i-00ed48e6ebad270e9",
                    "Device": "/dev/sda1",
                    "DeleteOnTermination": true,
                    "State": "attached",
                    "VolumeId": "vol-0b43716d783e44288"
                }
            ],
            "Encrypted": false
        },
        {
            "CreateTime": "2019-03-03T07:53:23.923Z",
            "Iops": 100,
            "SnapshotId": "",
            "State": "in-use",
            "VolumeType": "gp2",
            "Size": 1,
            "VolumeId": "vol-09947341dba029cb3",
            "AvailabilityZone": "ap-northeast-1a",
            "Attachments": [
                {
                    "AttachTime": "2019-03-03T07:53:23.000Z",
                    "InstanceId": "i-00ed48e6ebad270e9",
                    "Device": "xvdf",
                    "DeleteOnTermination": true,
                    "State": "attached",
                    "VolumeId": "vol-09947341dba029cb3"
                }
            ],
            "Encrypted": false
        }
    ]
}

タグの設定

対象の全EBSにタグを設定します。

aws ec2 create-tags \
  --resources ${EC2_VOLUME_IDS} \
  --tags \
    Key=Name,Value=${TAG_NAME} \
    Key=Application,Value=${TAG_APPLICATION} \
    Key=Owner,Value=${TAG_OWNER} \
    Key=Stage,Value=${TAG_STAGE}

結果

返り値なし

事後確認

タグが設定されたことを確認します。

aws ec2 describe-volumes \
  --volume-ids ${EC2_VOLUME_IDS}

結果(例)

{
    "Volumes": [
        {
            "CreateTime": "2019-03-03T07:53:23.807Z",
            "Encrypted": false,
            "Attachments": [
                {
                    "InstanceId": "i-00ed48e6ebad270e9",
                    "State": "attached",
                    "Device": "/dev/sda1",
                    "VolumeId": "vol-0b43716d783e44288",
                    "AttachTime": "2019-03-03T07:53:23.000Z",
                    "DeleteOnTermination": true
                }
            ],
            "Size": 50,
            "SnapshotId": "snap-0490dd2cb58cf07c6",
            "VolumeId": "vol-0b43716d783e44288",
            "Tags": [
                {
                    "Value": "JO",
                    "Key": "Owner"
                },
                {
                    "Value": "Production",
                    "Key": "Stage"
                },
                {
                    "Value": "TEST-20190304",
                    "Key": "Name"
                },
                {
                    "Value": "WEB",
                    "Key": "Application"
                }
            ],
            "VolumeType": "gp2",
            "Iops": 150,
            "AvailabilityZone": "ap-northeast-1a",
            "State": "in-use"
        },
        {
            "CreateTime": "2019-03-03T07:53:23.923Z",
            "Encrypted": false,
            "Attachments": [
                {
                    "InstanceId": "i-00ed48e6ebad270e9",
                    "State": "attached",
                    "Device": "xvdf",
                    "VolumeId": "vol-09947341dba029cb3",
                    "AttachTime": "2019-03-03T07:53:23.000Z",
                    "DeleteOnTermination": true
                }
            ],
            "Size": 1,
            "SnapshotId": "",
            "VolumeId": "vol-09947341dba029cb3",
            "Tags": [
                {
                    "Value": "Production",
                    "Key": "Stage"
                },
                {
                    "Value": "WEB",
                    "Key": "Application"
                },
                {
                    "Value": "TEST-20190304",
                    "Key": "Name"
                },
                {
                    "Value": "JO",
                    "Key": "Owner"
                }
            ],
            "VolumeType": "gp2",
            "Iops": 100,
            "AvailabilityZone": "ap-northeast-1a",
            "State": "in-use"
        }
    ]
}

タグが設定されたことを確認できました。

最後に

今回はEBSボリュームのタグをAWS CLIにて設定する方法について、ご紹介しました。
AWS CLIはマネジメントコンソールよりも手順化しやすく、一括で設定することには秀でているかと思います。
もし、マネジメントコンソールでポチポチ手作業をしているような作業があれば、AWS CLIの利用を検討してみてはいかがでしょうか。

どなたかの助けになれば幸いです。

OneLoginのMFAを利用してWorkSpacesの2段階認証を実現する

$
0
0

宮澤です。

今回は、OneLoginとWorkSpacesを組み合わせて、2段階認証を実現する手順を紹介します。
紹介する手順は、事項の前提条件が構築、設定されている必要があります。

前提条件

OneLoginの設定

OneLoginに管理者でログインして”SETTINGS > RADIUS”へ移動し”NEW CONFIGURATION”を押します。

“Secret”の項目に、AWSのAD Connectorと連携するためのキーを設定します。
次の”IP Address”にVPC上に設定された、NATゲートウェイのEIPを設定します。
最後に、Attributesの項目を以下のように設定します。

  • User-Name → SAMAccountName
  • User-Password → OTP

AD Connectorの設定

AWSアカウントにログインし、該当するAD Connectorを選択し、”多要素認証”タブを開きます。
その後、多要素認証の有効化にチェックを入れて、RADIUSサーバーIPアドレスに、以下のURLに記載されれているIPアドレスを記入します。
https://onelogin.service-now.com/support?id=kb_article&sys_id=cbd99143db109700d5505eea4b96195d
そして、共有シークレートコードには、先程、OneLoginで設定した”Secret”を入力します。
最後に、サーバータイム愛とと最大試行回数を適切に設定し”ディレクトリの更新”を押します。

設定が完了するとRADIUSステータスが”完了済み”になります。
失敗する場合は”Secret”の設定やネットワークの疎通を確認しましょう。

動作確認

接続確認をするために、WorkSpacesのクライアントアプリを起動します。
多要素認証が有効になっていると、以下のように”MFAコード”の入力項目が追加されます。

今回の設定が完了している場合、MFAコードにOneLogin ProtectのMFAアプリに表示されている数字6桁を入力することで、WorkSpacesへのログインが可能になります。

ActiveDirectory環境でSSMをVPCエンドポイント経由で利用する際の注意点

$
0
0

こんにちは、技術3課の城です。

今回はAWSでActiveDirectory(以降、AD)環境にてSSMを利用する上でハマったポイントがあったので、共有したいと思います。

最初にまとめの3行

長くなりそうなので、最初にまとめておきます。

  • SSMをVPCエンドポイント経由で利用するにはAmazonProvidedDNSでの名前解決が必要
  • AD環境での解決策は条件付きフォワーダーの設定
  • 名前解決した際に返されるIPアドレスはフォワーダー先のAmazonProvidedDNSのあるVPCのVPCエンドポイント

ハマったポイント

とある環境にてSSM自体が利用が出来なくなる事象が発生していました。
原因を確認したところ、VPCエンドポイントを構築しているにもかかわらず、外部のIPに対してアクセスしようとしていることが原因でした。
更に調べたところ、インターフェースVPCエンドポイントを利用するにはAmazonProvidedDNSを利用する必要があるようです。
一般的にADサーバーにDNSサーバーを同居させることが多いと思いますが、デフォルトのDNS設定(AmazonProvidedDNS)から向け先を変更したことが原因でした。

実際にssm.ap-northeast-1.amazonaws.comを名前解決してみると、グローバルIPアドレスが返されていました。

構成パターン図

AWS環境にDNS(AD)サーバーが存在する場合

AWS環境のサーバー群がAWS環境のDNS(AD)サーバーを参照します。

オンプレミス環境にDNS(AD)サーバーが存在する場合

AWS環境のサーバー群がオンプレミス環境のDNS(AD)サーバーを参照します。

AWS環境にDNS(AD)サーバーが存在する場合の対応方法

こちらはシンプルで、DNSサーバーの条件付きフォワーダーの設定にて対応可能です。
※そもそものフォワーダーをAmazonProvidedDNSを向けている場合は対応不要ですが、今回は別のDNSサーバーを向いている前提で進めます。
SSMの場合は設定が必要なドメインは下記となります。(東京リージョンの場合)

  • ssm.ap-northeast-1.amazonaws.com
  • ssmmessages.ap-northeast-1.amazonaws.com
  • ec2.ap-northeast-1.amazonaws.com
  • ec2messages.ap-northeast-1.amazonaws.com

条件付きフォワーダーの設定

1.DNS(AD)サーバーにRDPログインします。

2.[スタートメニュー]⇒[Windows 管理ツール]⇒[DNS]とクリックしDNS マネージャーを開きます。

3.[条件付フォワーダー]を右クリックし、[新規条件付きフォワーダー]をクリックします。

4.DNSドメインに上記の対象ドメイン、IPアドレスにAmazonProvidedDNSのIPアドレスを入力し、[OK]をクリックします。


例ではAmazonProvidedDNSのIPアドレスは10.0.0.2となっていますが、VPCのCIDRの第4オクテットに2を足したアドレスとなります。
詳細は下記ドキュメントに記載があります。
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_DHCP_Options.html#AmazonDNS

5.項3及び4を登録するドメイン全てで実施します。

6.結果確認
ssm.ap-northeast-1.amazonaws.comを名前解決すると、プライベートIPアドレスが返されています。

オンプレミス環境にDNS(AD)サーバーが存在する場合の対応方法

こちらの場合は、AmazonProvidedDNSはVPC外からのDNSクエリを受け付けないという仕様があるため、Route53リゾルバーのインバウンドエンドポイントを条件付きフォワーダーの宛先として設定する必要があります。
https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resolver.html#resolver-overview-forward-network-to-vpc

Route53リゾルバー インバウンドエンドポイントの作成

VPCエンドポイントを作成したVPCにインバウンドエンドポイントを作成します。

1.Route53のダッシュボードにて[Inbound Endpoints]をクリックします。

2.[インバウンドエンドポイントの作成]をクリックします。

3.インバウンドエンドポイントの作成画面にて、必要項目を記載、選択していきます。

  • エンドポイント名
  • VPC
  • エンドポイントにアタッチするセキュリティグループ
  • IPアドレス
    • アベイラビリティゾーン
    • サブネット
    • IPアドレス指定 or 自動

※IPアドレスは2つ以上指定する必要があります。

項目の記載、選択が出来たら、[送信]をクリックします。

作成中・・・

出来ました!

5.IDをクリックすると詳細を見ることが出来ます。
赤枠がインバウンドエンドポイントのIPアドレスとなります。

条件付きフォワーダーの設定

オンプレミス環境のDNS(AD)サーバーに条件付きフォワーダーを設定します。
設定方法は前述と同様ですが、フォワード先にインバウンドエンドポイントのIPアドレスを設定すればOKです。

各VPCそれぞれのVPCエンドポイントを利用するには

今回紹介した構成では一つのVPCのエンドポイントを利用しています。
各VPCに作成した、それぞれのVPCエンドポイントを利用させたい場合は、下記の条件が必要なようです。

  • 各VPCにDNS(AD)サーバーを配置
  • 各VPCで異なる条件付きフォワーダーを設定(配置されたVPCのAmazonProvidedDNSを設定)
  • メンバーサーバーのDNSの向け先を各VPCに配置されたDNS(AD)サーバーを設定

終わりに

例えばRDSなどはパブリックの名前解決でプライベートIPアドレスを返してくれるなど、AWSでは上手い具合にやってくれるところも多いですが、やはり利用するサービス仕様をきちんと考慮して設計することが重要ですね。

どなたかの助けになれば幸いです。

【Pythonスクリプト】アカウント内のCloudFormationスタックを全部一気に削除保護する

$
0
0

こんにちは。3月より技術1課に正式配属となりました加藤和也です。
研修、OJTの1年間を経てついに配属です。頑張るしかねぇ。

さて今回は、アカウント内にあるCloudFormation(以後、CFn)スタック全ての削除保護を有効化するスクリプトを作成したので、気をつけるポイント含め共有していきます。

CFnスタックの削除保護とは

CFnにはスタックが誤って削除されることを防ぐために、削除保護という機能があります。
削除保護を有効化した状態でスタックを削除しようとすると、削除処理自体が失敗します。ステータスを含め、スタックの変更が行われないのです。
本番稼働するシステムなど、操作ミスなどによる誤った削除を起こしたくない場合には有効化しておくことが望ましいでしょう。

この設定はスタック作成時やスタック作成後にいつでも有効化できます。
もちろんマネージメントコンソールからぽちぽち設定することも可能なのですが、手間を省いたり漏れを防いだりするためにスクリプトで一気に設定してしまいましょう。

完成したスクリプト

import boto3
import json
import sys

args = sys.argv
enable = '--disable' not in args

client = boto3.client('cloudformation')
token = ''

while token is not None:
# Set params
  params = {
    'StackStatusFilter': ['CREATE_COMPLETE']
  }
  if token:
    params['NextToken'] = token
# Get list of CFn Stacks
  stacks = client.list_stacks(**params)['StackSummaries']

  if 'NextToken' in stacks:
    token = stacks['NextToken']
  else:
    token = None

# Get only root Stacks
  root_stacks = list(filter(lambda stack: 'ParentId' not in stack, stacks))
# Get root_stacks name
  stack_names = list(map(lambda stack: stack['StackName'], root_stacks))
# Enable Termination Protection
  for stack_name in stack_names:
    res = client.update_termination_protection(
      EnableTerminationProtection=enable,
      StackName=stack_name
    )
  message = 'protected: ' if enable else 'disabled: '
  print(message, res['StackId'])

enable/disableをどちらもできるようにした結果多少長めになりました。開発環境は、
– Python 3.7.2
– boto3 1.9.97
となっています。Python2系対応は行なっておりませんが、悪しからず。

使い方

クレデンシャル情報を設定

1. スタックに対し以下の権限を持つIAMユーザーを用意します。
– “cloudformation:ListStacks”,
– “cloudformation:UpdateTerminationProtection”

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "cloudformation:ListStacks",
      "cloudformation:UpdateTerminationProtection"
    ],
    "Resource": "*"
  }]
}

2. 払い出したIAMユーザーのアクセスキーを、環境変数に登録します

# windows
set AWS_ACCESS_KEY_ID=xxx #(アクセスキーを記載)
set AWS_SECRET_ACCESS_KEY=xxxx #(シークレットアクセスキーを記載)
set AWS_DEFAULT_REGION=ap-northeast-1

# Unix系
export AWS_ACCESS_KEY_ID=xxx #(アクセスキーを記載)
export AWS_SECRET_ACCESS_KEY=xxxx #(シークレットアクセスキーを記載)
export AWS_DEFAULT_REGION=ap-northeast-1

 

削除保護を有効化

任意の名前で保存したスクリプトを実行します

python script_name.py

削除保護を無効化

引数 --disable を与えてスクリプトを実行します

python script_name.py --disable

スクリプト解説

いくつかハマりやすい箇所があるため、解説を加えておきます。

1. ネストしたスタックへの対応

ネストしたスタックへの削除保護の設定は、必ずルートスタックに対してのみ行います。
子スタックに対して設定を行おうとすると、エラーが発生してうまくスクリプトが動きません。スタック一覧からルートスタックと子スタックを判別する際には ParentId または RootId を保持しているかどうかをみます。今回のスクリプトでは、

root_stacks = list(filter(lambda stack: 'ParentId' not in stack, stacks))

この行で ParentId を保持していないスタックを抽出することで、ルートスタックのみを取得しています。
filterとlambda記法でささっと書いてしまいたい人なのでこんな書き方をしていますが、普通にfor文で

root_stacks = []
for stack in stacks:
  if 'ParentId' not in stack:
    root_stacks.append(stack)

と書いてもOKです。

2. NextTokenの処理

list_stacksはレスポンスのサイズが1MBを超える場合、NextTokenという値とともに1MB以下の値のみを返す仕様になっています。続きの値が欲しい場合は、取得したNextTokenをつけて改めてlist_stacksを実行します。

レスポンスが1MBを超えることはそうないかもしれませんが、今回のスクリプトでは念のため、NextTokenが返ってきた場合の処理も追加しました。
以下の部分で対応を行なっています。

token = ''

while token is not None: 
# Set params
  params = {
    'StackStatusFilter': ['CREATE_COMPLETE']
  }
  if token:
    params['NextToken'] = token

# Get list of CFn Stacks
  stacks = client.list_stacks(**params)['StackSummaries']

  if 'NextToken' in stacks:
    token = stacks['NextToken']
  else:
    token = None

注意しなければいけないのが、list_stacksへの引数の渡し方です。

最初にリクエストを投げる際には当然 NextToken の値は持っていません。とりあえず一回目のリクエストではNextTokenに空文字やNoneを指定しておきたいところです。
ですが、list_stacks関数の仕様上、それができません。NextTokenを与えた場合は型や文字長のチェックが行われるため、空文字やNoneではエラーが発生してしまいます。

これを踏まえると、
– 最初は引数に StackStatusFilter のみを渡す
– 2回目以降(NextTokenを受け取って以降)は NextToken も渡す
という形を守る必要があります。

今回は**で引数を展開しましたが、普通に1回目と2回目以降の処理を分けて書いてもいいと思います。
その辺りはお好みで。

AWS CLI等でSQS VPC Endpointを利用するときの注意点

$
0
0

SQS向けのVPC Endpoint (Private Link)を利用するときの注意点です。特に、AWS CLIをご利用の方。
なお本ブログでは、下記のバージョンのAWS CLIで検証を行っています。(2019/03/03時点で最新)

[ec2-user@swx-bastion-l01 ~]$ aws --version
aws-cli/1.16.116 Python/2.7.14 Linux/4.14.88-88.76.amzn2.x86_64 botocore/1.12.106

SQSのAPIエンドポイントには実は2種類あります。
かつて使われていたエンドポイント(以下、レガシーエンドポイント)と、新しいエンドポイント(以下、現行エンドポイント)です。

レガシーエンドポイント: ap-northeast-1.queue.amazonaws.com
現行エンドポイント: sqs.ap-northeast-1.amazonaws.com

2019/03/03現在、AWS CLIはデフォルトではSQSのレガシーエンドポイントを利用してしまいます。
これがVPC Endpointを利用してSQSに接続しようとしたときに、少し問題になります。

検証してみます。
とあるVPCに、SQSのInterface VPC Endpointを作成しました。
同じVPCにEC2をローンチします。セキュリティグループのアウトバウンド通信ではVPC内のローカル通信だけを許可します。これでこのEC2は、インターネットには出れないが、VPC内にあるVPC Endpointへはアクセスができる状態です。

nslookupで、レガシーエンドポイントと現行エンドポイントの名前解決をしてみます。

[ec2-user@swx-bastion-l01 ~]$ nslookup ap-northeast-1.queue.amazonaws.com
Server:         192.168.0.2
Address:        192.168.0.2#53

Non-authoritative answer:
Name:   ap-northeast-1.queue.amazonaws.com
Address: 54.240.225.157

[ec2-user@swx-bastion-l01 ~]$ nslookup sqs.ap-northeast-1.amazonaws.com
Server:         192.168.0.2
Address:        192.168.0.2#53

Non-authoritative answer:
Name:   sqs.ap-northeast-1.amazonaws.com
Address: 192.168.4.179
Name:   sqs.ap-northeast-1.amazonaws.com
Address: 192.168.3.59

レガシーエンドポイントを名前解決したときは、パブリックIPが返ってきていることが分かります。
一方で現行エンドポイントを名前解決したときは、VPC EndpointのプライベートIPが返ってきていることが分かります。

AWS CLIでSQSのコマンドを実行してみます。

[ec2-user@swx-bastion-l01 ~]$ aws --region ap-northeast-1 sqs list-queues

Connect timeout on endpoint URL: "https://ap-northeast-1.queue.amazonaws.com/"

これはAWS CLIがデフォルトではレガシーエンドポイントを利用しようとしているため、パブリックIPに繋ぎに行こうとしてしまっており、タイムアウトしているのだと分かります。
ちなみに「 aws sqs send-message –queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/testqueue –message-body “Hello” 」のように、キューURLに現行エンドポイントが含まれているように見えてもAWS CLIだとレガシーエンドポイントに接続してしまいます。

ではAWS CLIさんに現行エンドポイントを使ってもらいましょう。
–endpoint-url オプションで現行エンドポイントを明示的に指定してあげます。

[ec2-user@swx-bastion-l01 ~]$ aws --region ap-northeast-1 sqs list-queues --endpoint-url https://sqs.ap-northeast-1.amazonaws.com
{
    "QueueUrls": [
        "https://sqs.ap-northeast-1.amazonaws.com/123456789012/test-queue"
    ]
}

成功しました。
このように、現行エンドポイントへアクセスしようとしているため、VPC Endpoint経由でアクセスされたことが分かります。
またCloudTrailでAPIアクセス履歴を見ると、接続元IPがEC2のローカルIPアドレスで記録されていることも分かります。
※ListQueues APIはCloudTrailに記録されないため、PurgeQueue APIで試してみました。

{
(中略)
    "eventSource": "sqs.amazonaws.com",
    "eventName": "PurgeQueue",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "192.168.1.10",
    "vpcEndpointId": "vpce-01234567890123456"
}

普通にパブリックなAPIエンドポイントからアクセスすると、このsourceIPAddressはEC2のElastic IPアドレスやNAT GatewayのIPアドレスになるはずです。
今回はVPC Endpointからしっかりアクセスできているので、VPC EndpointのIDまで記録されています。(上記例のIDは念のため適当な値にしています)

なお、AWS Tools for Powershellではデフォルトで現行エンドポイントを使うことも確認できました。
(念のため、お使いのCLI/SDKではどのような動きになるか、確認することを推奨いたします)


【AWS Organizationsアップデート!】SCPで柔軟な設定が可能に!- Conditionを設定して「特定のロールのみEC2の操作ができる」ようにしてみた –

$
0
0

http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_top.png
 こんにちは、サーバーワークスのこけしの人、坂本(@t_sakam)です。本日、Organizationsの機能アップデートが発表されました。このアップデートで、いままでざっくりとした設定しかできなかったSCP(サービスコントロールポリシー)で「Resource」や「Condition」の設定ができるようになり、柔軟な指定ができるようになった模様です。いままでは細かい設定ができなかったので、嬉しいアップデートですね!
 早速、どういったことが可能になったのか、簡単に確認してみたいと思います。

構成

 今回は、親アカウントのOrganizationsで管理している子アカウントが1つだけ、というシンプルな構成です。OU(Organizational Units)も1つだけです。親アカウントと子アカウントの間に「BasicChildOU」というOUを置きました。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_top.png
 まずは、このOUに「EC2DenyPolicy」というEC2の操作をすべてDeny(拒否)に設定したSCPをアタッチして、子アカウントのEC2が操作できないようにします。
 上記の設定に加えて今回はOrganizationsのアップデートで「Condition」が設定できるようになっているので、「Condition」を設定して踏み台アカウントから「PowerUserLoginRole」で子アカウントにログインした場合のみ、EC2の操作ができる状態にしたいと思います。子アカウントにrootでログインしたときは、EC2が使えないようになっているかも手順の中で確認していきます。
 
※アップデートで「Resource」も柔軟に設定できるようになりましたが、今回はすべてのリソースに適用したいので、「Resource」は「*」で設定しています。

親アカウントにログイン

 まずは、親アカウントにログインしてOrganizationsの画面で「ポリシーの作成」ボタンを押します。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_01.png

新しいポリシーの作成

 以下は、アップデート後のSCP作成画面です。UIがかなり変わりましたね。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_02.png
 ちなみに、アップデート前の画面は以下のようなUIでした。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_03.png

「EC2DenyPolicy」を作成

 まずは、ポリシー名と説明を入力します。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_04.png

サービスの選択

 左のメニューの検索ボックスで「EC2」と入力し、検索後「EC2」を選択します。すると、アクションが表示されます。
 今回はすべての操作を「Deny」にするので、一番上の「All actions (ec2:*)」にチェックを入れます。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_05.png

リソースを追加する

 次は、その下の「2. リソースを追加する」リンクを押します。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_06.png
 今回は「All Resources」を選び、リソース ARNは「*」にして、「リソースの追加」を押します。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_07.png

条件を追加する

 最後に、その下の「3. 条件を追加する」リンクを押します。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_08.png
 条件キーを「aws:PrincipalArn」、演算子を「StringNotEquals」にします。値は今回EC2の操作を制限したくないロール(「PowerUserLoginRole」)のARNである「arn:aws:iam::XXXXXXXXX376:role/PowerUserLoginRole」を入力します。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_09.png

ポリシーの作成

 最後に右下の「ポリシーの作成」ボタンを押して、SCPの作成は完了です。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_10.png

子アカウントにrootでログイン

 SCPをアタッチする前に子アカウントにrootでログインしてみます。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_19.png
 いまはまだ、EC2が操作できる状態であることが確認できます。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_11.png

親アカウントのOrganizationsでSCPをアタッチ

 再び親アカウントのOrganizationsを操作します。「BasicChildOU」に先程作成した「EC2DenyPolicy」をアタッチします。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_00.png
 アタッチできました。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_12.png

子アカウントで再確認

 再び子アカウントにrootで入り、EC2の画面を確認します。エラーがでてEC2が操作できなくなっていることがわかります。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_13.png

PowerUserLoginRoleの確認

 子アカウントのIAMの画面で「PowerUserLoginRole」を確認してみます。信頼されたエンティティに末尾3桁が「126」となっているアカウントが設定されていることを確認できます。これは、踏み台アカウントのアカウントIDです。踏み台アカウントから「PowerUserLoginRole」でスイッチロールすれば、EC2が使えるはずです。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_14.png

踏み台アカウントにログイン

 踏み台アカウントにログイン後、スイッチロールして子アカウントに入りたいと思います。末尾「126」のアカウントなので、踏み台アカウントであることも画面から確認できます。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_15.png

子アカウントにスイッチロール

 子アカウントのアカウントIDは、末尾「376」です。下の画面は、これから子アカウントに「PowerUserLoginRole」でスイッチロールするところです。アカウントIDとロール名を入力して、好きな色を選びます。最後に「ロールの切り替え」ボタンを押します。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_16.png
 子アカウントに入れました。最後にEC2の画面に移動しましょう。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_17.png

子アカウントのEC2が操作できるかを確認

 子アカウントのEC2の画面です。先程rootでログインしたときと違い、エラーがでていません。これで、踏み台アカウントから「PowerUserLoginRole」に子アカウントにスイッチロールした場合、ちゃんとEC2が使える状態になっていることを確認できました。
http://corporate-tech-blog-wp.s3-website-ap-northeast-1.amazonaws.com/tech/wp-content/uploads/2019/03/organizations_blog_18.png

まとめ

 今回は、アップデートで便利になったOrganizationsのSCPを試してみました!
 SCPで柔軟な設定ができるようになったことが確認できましたね。これで今後は「特定のロール権限のみ、サービスを使えるようにする」など、便利な設定ができそうです!

 いや〜、「AWS Organizations 」って本当にいいものですね!

【速報】Direct Connect Gateway のマルチアカウント対応が発表されました!

$
0
0

こんにちは、AWSセールスエンジニアの加藤一喜です。
何かと繋がっていたい昨今です。
そんな折、Direct Connect Gatewayのマルチアカウント対応の発表がありましたのでドカンと報告します。

従来のDirect Connect Gatewayはどうだった?

Direct Connect Gateway(DXGW)を利用する事で、同一アカウント内で利用される複数のVPCへの接続が可能です。
一方で、アカウントが異なる場合は従来、DXGWが利用出来ず、アカウントが異なる各々のVPCへの接続を個別に考慮する必要がありました。

※同一CIDRのVPCは収容出来ません。

マルチアカウント対応されるとどうなる?

今回のアップデートによって、異なるアカウントのVPCに対しても接続が可能となりました、やったね!

※同一CIDRのVPCは収容出来ません。
※収容可能なVPCの数は10です。

何が嬉しいの?

セキュリティポリシーや運用のルールでシステム単位やユーザ部門毎にアカウントを分けていた場合、従来であればアカウント毎に接続方法を検討する必要がありましたが、マルチアカウント対応された事によってシンプルなWANが構成出来る様になります。
これによりWANのコストや運用コストの最適化、削減が期待出来ます。

このアップデートに期待されていた方も多いのではないでしょうか?
以前の構成で運用されていた方は、是非WANの見直しをオススメいたします!

 

S3の署名バージョン2 廃止にAWS CLIやSDKをバージョンアップせずに対応する方法を調べてみた

$
0
0

S3における「署名バージョン2」が2019年6月24日に廃止されます

下記リンクに記載があるとおり、S3へのAPIリクエスト時の「署名バージョン2」が廃止され、「署名バージョン4」のリクエストのみを受け付けるようになります。

Amazon S3 における署名バージョン 2 は廃止され、署名バージョン 2 の最終サポートは 2019 年 6 月 24 日に終了します。2019 年 6 月 24 日以降、Amazon S3 は署名バージョン 4 を使用して署名された API リクエストのみを受けつけます。

AWS CLIやAWS SDKのバージョンによっては、S3へのAPIリクエスト時のデフォルトの署名バージョンが「署名バージョン2」になっているものがあり、2019年6月24日以降、S3側で「署名バージョン2」のAPIリクエストの受付が廃止されると、APIリクエストに失敗するようになります。

S3における「署名バージョン2」廃止により影響を受けるケース

S3における「署名バージョン2」廃止により影響を受けるのは下記のケースになります。

  • 古いAWS CLI、またはAWS SDKを利用している

具体的には下記リンクに記載されているバージョンのCLIやSDKが影響を受けます。

例えば、AWS CLIであれば、「1.11.108」より古いバージョンの場合、AWS Java SDKであれば「1.11.x」より古いバージョンの場合、デフォルトのS3へのAPIリクエストが「署名バージョン2」になっています。

スクリプト内でAWS CLIを利用しS3にオブジェクトをアップロードしたり、プログラムからAWS SDKを利用してS3上のオブジェクトを操作しているようなケースがあるかと思いますが、その中で古いバージョンのAWS CLIやAWS SDKを利用している場合に影響を受ける可能性がありますので、念のためバージョンをチェックされることをお勧めします。

また、サードパーティ製のツールやソフトウェアが内部的にAWS SDKを利用している場合も同様に、影響を受ける可能性がありますので確認が必要です。

S3へのAPIリクエストを「署名バージョン2」から「署名バージョン4」へ移行する方法

を見ると「古いAWS CLIやAWS SDKを利用している場合はバージョンアップが必要」のように読み取れますが、

古いAWS CLIやAWS SDKでも、署名バージョンの指定をすることで、「署名バージョン4」でAPIリクエストをすることができるようになっていました。

CLIやSDKでの署名バージョンの指定方法は下記に記載されています。

念のためAWSサポートにも確認しましたが、「署名バージョン4」への移行方法は、例えばAWS Java SDKの場合、下記の2通りがあるとのことでしたので、必ずしもCLIやSDKをバージョンアップする必要はなさそうです。

AWSサポートからの回答

次の「いずれか」の方法で署名バージョン4にご対応いただくことができます。

  • ご利用いただくAWS Java SDKを 1.11.x にバージョンアップする。
  • AWS Java SDKとして 1.6.10 以降のバージョンをご利用いただいた上で、javaコマンドの引数として「-Dcom.amazonaws.services.s3.enableV4」を指定する。

だだし「CLIやSDKは常にバージョンアップしており他の機能改善等も行われているため、アップデートによる対応も検討ください」とのことでした。

S3の署名バージョン2 廃止にAWS CLIやSDKをバージョンアップせずに対応する方法

AWS CLIやAWS SDKをバージョンアップするのには、それなりに修正やリスクが伴う可能性があります。

これらのバージョンアップが容易に行えない環境では、署名バージョンを指定する方法があります。

リクエスト認証での署名バージョンの指定」の内容に従って、いくつかの古いCLIバージョン、各言語の古いSDKで試してみました。

※ 以下に記載している方法は、SDKなどのバージョンによって挙動が異なる可能性もありますので、実際に動作をご検証のうえご利用ください。

AWS CLIの場合

AWS CLIの場合は、 aws configure set default.s3.signature_version s3v4 コマンドで、予めプロファイルのS3へのAPIリクエスト時の署名バージョンを指定しておくことで、「署名バージョン4」でリクエストをすることが可能でした。

動作確認したバージョン:「aws-cli/1.6.10」および「aws-cli/1.10.8」

※「aws-cli/1.6.3」から指定が可能になっているとのことです。

https://github.com/aws/aws-cli/blob/develop/CHANGELOG.rst#163

1.6.3 ・bugfix:Signature Version 4: You can enable Signature Version 4 for Amazon S3 commands by running aws configure set default.s3.signature_version s3v4 (issue 1006, botocore issue 382)

■ そのまま aws s3 ls コマンドを実行した場合
$ aws --version
aws-cli/1.6.10 Python/2.6.9 Linux/3.14.20-20.44.amzn1.x86_64

$ aws s3 ls sigv2-test-bucket
                       PRE test/

CloudTrailのログ (SignatureVersionSigV2 になっている)

:
    :
    "eventTime": "2019-XX-XXT08:04:25Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListObjects",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-cli/1.6.10 Python/2.6.9 Linux/3.14.20-20.44.amzn1.x86_64]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3-ap-northeast-1.amazonaws.com",
        "prefix": "",
        "delimiter": "/"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV2",
    :
    :
aws configure set default.s3.signature_version s3v4 を実行
$ aws --version
aws-cli/1.6.10 Python/2.6.9 Linux/3.14.20-20.44.amzn1.x86_64

$ aws configure set default.s3.signature_version s3v4

$ aws s3 ls sigv2-test-bucket

# リージョンを指定しない場合、下記エラーが出るようになる
A client error (PermanentRedirect) occurred when calling the ListObjects operation: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint: sigv2-test-bucket.s3.amazonaws.com
You can fix this issue by explicitly providing the correct region location using the --region argument, the AWS_DEFAULT_REGION environment variable, or the region variable in the AWS CLI configuration file.  You can get the bucket's location by running "aws s3api get-bucket-location --bucket BUCKET".

# デフォルトリージョンを設定
$ aws configure
Default region name [None]: ap-northeast-1

$ aws s3 ls sigv2-test-bucket
                       PRE test/

CloudTrailのログ(SignatureVersionSigV4 に変わっていることを確認)

:
    :
    "eventTime": "2019-XX-XXT08:17:58Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListObjects",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-cli/1.6.10 Python/2.6.9 Linux/3.14.20-20.44.amzn1.x86_64]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "s3-ap-northeast-1.amazonaws.com",
        "prefix": "",
        "delimiter": "/"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV4",
    :
    :

また .aws/config の中身は下記のように、

  • S3リクエスト時の署名バージョンの指定
  • デフォルトリージョンの指定

が入っている状態になっています

$ view .aws/config
[default]
s3 =
    signature_version = s3v4
region = ap-northeast-1

AWS Java SDKの場合

AWS Java SDKの場合はJava実行時のコマンド引数に -Dcom.amazonaws.services.s3.enableV4 を指定することで、「署名バージョン4」でリクエストをすることが可能でした。

この指定は「aws-sdk-java/1.6.10」 から可能になっているとのことです。

そのまま実行した場合

CloudTrailのログ (SignatureVersionSigV2 になっている)

:
    :
    "eventTime": "2019-XX-XXT02:34:42Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "GetObject",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-sdk-java/1.9.13 Windows_Server_2012_R2/6.3 Java_HotSpot(TM)_64-Bit_Server_VM/24.80-b11/1.7.0_80]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3.amazonaws.com",
        "key": "test.zip"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV2",
    :
    :
Java実行時のコマンド引数に -Dcom.amazonaws.services.s3.enableV4 を指定した場合

CloudTrailのログ(SignatureVersionSigV4 に変わっていることを確認)

:
    :
"eventTime": "2019-XX-XXT06:36:53Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "GetObject",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-sdk-java/1.9.13 Windows_Server_2012_R2/6.3 Java_HotSpot(TM)_64-Bit_Server_VM/24.80-b11/1.7.0_80]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3-ap-northeast-1.amazonaws.com",
        "key": "test.zip"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV4",
    :
    :

AWS Ruby SDK(v1)の場合

「aws-sdk-ruby/v1.31.0」より「s3_signature_version」の指定可能になっているとのことです。

https://github.com/aws/aws-sdk-ruby/commit/7abd9a7d72e386002a41315a6745bd64c1bba735#diff-73e2cad9fbe3e161575d145a3e3062f6

You can now configure the S3 signature version.
For example:
# as a global default AWS.config(:s3 => { :signature_version => :v4 })
# per service AWS::S3.new(:s3_signature_version => :v4)

動作確認したバージョン:「aws-sdk-ruby/1.51.0」

s3_signature_version の指定なし
AWS::S3.new(region: 'ap-northeast-1').buckets['bucket-name']

CloudTrailのログ (SignatureVersionSigV2 になっている)

:
    :
    "eventTime": "2019-XX-XXT10:25:20Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListObjects",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-sdk-ruby/1.51.0 ruby/2.0.0 x86_64-linux]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3-ap-northeast-1.amazonaws.com",
        "max-keys": "20",
        "prefix": "test/"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV2",
    :
    :
:s3_signature_version => :v4 の指定あり
AWS::S3.new(region: 'ap-northeast-1',:s3_signature_version => :v4).buckets['bucket-name']

CloudTrailのログ(SignatureVersionSigV4 に変わっていることを確認)

:
    :
    "eventTime": "2019-XX-XXT10:27:26Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListObjects",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-sdk-ruby/1.51.0 ruby/2.0.0 x86_64-linux]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3-ap-northeast-1.amazonaws.com",
        "max-keys": "20",
        "prefix": "test/"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV4",
    :
    :

S3へのリクエストの署名バージョンの確認方法

S3へのリクエストの署名バージョンの確認方法はいくつかありますが、簡単な方法としてS3の「オブジェクトレベルのログ記録」や「サーバーアクセスのログ記録」有効化する方法です。

「オブジェクトレベルのログ記録」を有効化して記録されたログは、CloudTrailで設定したS3バケットやCloudWatch Logsに出力されます。

注意点としては、CloudWatch Logsに出力されるまでに数分かかるため、CloudWatch Logsのログの時刻と、ログ内の eventTime が異なる点です。実際にS3のAPIが実行された時間はログ内の eventTime を確認するようにしてください。

署名バージョンは "SignatureVersion": "SigXX" の部分を確認します。

署名バージョン2のリクエストの場合は SigV2 となり、署名バージョン4のリクエストの場合は SigV4 となります。

「署名バージョン2」の場合のログ

:
    :
  "eventTime": "2019-XX-XXT08:33:36Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListObjects",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-cli/1.10.8 Python/2.7.10 Linux/4.4.5-15.26.amzn1.x86_64 botocore/1.3.30]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "s3-ap-northeast-1.amazonaws.com",
        "encoding-type": "url",
        "prefix": "",
        "delimiter": "/"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV2",
    :
    :

「署名バージョン4」の場合のログ

:
    :
  "eventTime": "2019-XX-XXT08:33:36Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListObjects",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-cli/1.10.8 Python/2.7.10 Linux/4.4.5-15.26.amzn1.x86_64 botocore/1.3.30]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "s3-ap-northeast-1.amazonaws.com",
        "encoding-type": "url",
        "prefix": "",
        "delimiter": "/"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV4",
    :
    :

まとめ

  • S3へのAPIリクエストにおける「署名バージョン2」が2019年6月24日に廃止される
  • これにより、S3へのAPIリクエストのデフォルトが「署名バージョン2」になっている古いAWS CLI や AWS SDKを利用した処理が動かなくなる
  • 対応方法には、CLIやSDKをバージョンアップする方法の他に、CLIやSDKでS3へのAPIリクエストに「署名バージョン4」を利用するように指定する方法がある

S3をAWS CLIやAWS SDKから利用されている方は、現在稼働中のバージョンをご確認いただき、上記ケースに該当する場合は、対象の環境にて入念に事前検証を実施いただくことをお勧めいたします。

IAMユーザにMFA設定を強制するにあたりiam:ListUsersが必須では無くなった話

$
0
0

CS課佐竹です。

はじめに

皆様、IAMユーザにMFAを強制されているでしょうか?
MFA とは Multi-Factor Authentication の略称で、日本では「多要素認証」や「2段階認証」と呼ばれています。このMFAを弊社ではお客様環境での作業にあたり、全員が 仮想 MFA デバイス を必須として作業をしています。
そして、MFA の設定を終えていないIAM Userは、ごく限られた動作(MFA デバイスの設定追加)しかできないよう制限がかけられています。この制限下において、過去はiam:ListUserの付与が必須となっておりましたが、現在はこれが不要になりましたというお話をします。

仮想 MFA デバイス、U2Fセキュリティキー

ちょっとしたご紹介ですが、仮想MFAのデバイスとしてスマホを利用する場合、Google AuthenticatorやAuthyというアプリが有名です。他には、本エンジニアブログでも紹介されておりますYubikeyもMFAデバイスとして利用することが最近では増えてきています。

2019年1月までのMFA強制 IAM Policy のベストプラクティス

古くは2015年6月に書かれた以下のAWSの公式ブログに記述があります。

AWS IAMユーザーの多要素認証管理を委任する方法

ここで「Force_MFA」という言葉が登場しております。ここでは 「Force_MFA」ポリシーでは、MFAデバイスを使用してログインしていない場合、「iam:*」以外のものへのアクセスを明示的に拒否します」 と記載があるように、制御が緩いものの「MFAデバイスの強制」がうたわれております。その後さらに制御は厳格になり、以下のIAM Policyが公式ドキュメントでも提供されています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAllUsersToListAccounts",
            "Effect": "Allow",
            "Action": [
                "iam:ListAccountAliases",
                "iam:ListUsers",
                "iam:ListVirtualMFADevices",
                "iam:GetAccountPasswordPolicy",
                "iam:GetAccountSummary"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToSeeAndManageOnlyTheirOwnAccountInformation",
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:CreateAccessKey",
                "iam:CreateLoginProfile",
                "iam:DeleteAccessKey",
                "iam:DeleteLoginProfile",
                "iam:GetLoginProfile",
                "iam:ListAccessKeys",
                "iam:UpdateAccessKey",
                "iam:UpdateLoginProfile",
                "iam:ListSigningCertificates",
                "iam:DeleteSigningCertificate",
                "iam:UpdateSigningCertificate",
                "iam:UploadSigningCertificate",
                "iam:ListSSHPublicKeys",
                "iam:GetSSHPublicKey",
                "iam:DeleteSSHPublicKey",
                "iam:UpdateSSHPublicKey",
                "iam:UploadSSHPublicKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowIndividualUserToViewAndManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ListMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ],
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Sid": "BlockMostAccessUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:ListVirtualMFADevices",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice",
                "iam:ListAccountAliases",
                "iam:ListUsers",
                "iam:ListSSHPublicKeys",
                "iam:ListAccessKeys",
                "iam:ListServiceSpecificCredentials",
                "iam:ListMFADevices",
                "iam:GetAccountSummary",
                "sts:GetSessionToken"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

ここで注目して頂きたいのが、最下部にある “BlockMostAccessUnlessSignedInWithMFA” の箇所です。この箇所に記載されているNotAction部分が、MFAを設定していないIAM Userが操作することができる、限られたアクションが記載されています。この中で最も問題となるのが “iam:ListUsers” です。

“iam:ListUsers”が問題になるシーン

これがあるとどんな問題が起きるでしょうか?想像すると簡単なことなのですが、このアクションが存在すると、他のIAM UserのListが丸見えになってしまいます。つまり、MFAを設定させるというベストプラクティスを守る結果、iam:ListUsers権限により、IAM Userの名前が、各ユーザに全て見えてしまうという別のセキュリティリスクが出てしまいます。
そしてIAM UserのNameは一意に特定するためにメールアドレスを利用されることが多い状況です。ベンダー様もIAM Userが払い出される場合、IAM Userのリストには、複数のベンダー様のメールアドレスも同時にリストになっています。それを、MFAの設定のために一度全て見せないといけない、というのがこのポリシーの最大の問題点でした。 想像してみてください。MFAを設定させようとすると、他のベンダーと自社のユーザのメールアドレスが一旦丸見えになる、これは少々恐ろしい状況です。

実際の設定画面を確認する

先に書いたIAM Policyを設定した状況で、どのような操作をユーザがすることになるのかマネジメントコンソールから確認してみます。

現在、「IAMTestUser1_Old」というIAM Userでログインしています。こちらには古いIAM Policyがアタッチされており、”iam:ListUsers” が利用可能なため、IAMユーザが全て閲覧可能になっています。この後、自分のUser名をクリックして操作を進めます。

開いた後「Security Credentials」のタブから「Assigned MFA device」の「Manage」ボタンを押下します。

後は上記の画面から、仮想 MFA デバイスの設定に進みます。上記の通り、過去のIAM PolicyではMFAの設定箇所にたどり着くまでに、「全てのIAM Userの一覧を表示する」⇒「そこから自分のIAM Userを選択する」という流れが必須でした。

現在のMFA強制 IAM Policy のベストプラクティス

最新のIAM Policyですが、こちらの公式ドキュメントで提供されています。ですが2019年4月1日現在、一部ポリシーとして不足しているアクションがあるため、今回はそれを追加し、以下を現時点でのベストプラクティス IAM Policyとして活用しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowViewAccountInfo",
            "Effect": "Allow",
            "Action": [
                "iam:GetAccountPasswordPolicy",
                "iam:GetAccountSummary",
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowManageOwnPasswords",
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:GetUser",
                "iam:CreateLoginProfile",
                "iam:DeleteLoginProfile",
                "iam:GetLoginProfile",
                "iam:UpdateLoginProfile"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnAccessKeys",
            "Effect": "Allow",
            "Action": [
                "iam:CreateAccessKey",
                "iam:DeleteAccessKey",
                "iam:ListAccessKeys",
                "iam:UpdateAccessKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnSigningCertificates",
            "Effect": "Allow",
            "Action": [
                "iam:DeleteSigningCertificate",
                "iam:ListSigningCertificates",
                "iam:UpdateSigningCertificate",
                "iam:UploadSigningCertificate"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnSSHPublicKeys",
            "Effect": "Allow",
            "Action": [
                "iam:DeleteSSHPublicKey",
                "iam:GetSSHPublicKey",
                "iam:ListSSHPublicKeys",
                "iam:UpdateSSHPublicKey",
                "iam:UploadSSHPublicKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnGitCredentials",
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceSpecificCredential",
                "iam:DeleteServiceSpecificCredential",
                "iam:ListServiceSpecificCredentials",
                "iam:ResetServiceSpecificCredential",
                "iam:UpdateServiceSpecificCredential"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnVirtualMFADevice",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice"
            ],
            "Resource": "arn:aws:iam::*:mfa/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnUserMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice",
                "iam:EnableMFADevice",
                "iam:ListMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "DenyAllExceptListedIfNoMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ChangePassword",
                "iam:GetUser",
                "iam:CreateLoginProfile",
                "iam:DeleteLoginProfile",
                "iam:GetLoginProfile",
                "iam:UpdateLoginProfile",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "iam:DeleteVirtualMFADevice",
                "sts:GetSessionToken"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

 

新しく増えた My Security Credentials (セキュリティ認証情報) ページ

以前までMFAの設定においてIAMのUserをリストする権限が必要であったのは、自分自身のIAM Userを選択し、User個別の画面にたどり着くために必要でした。現在は、その代わりとして My Security Credentials (セキュリティ認証情報) というページが用意されています。こちらのリリースは2019年1月24日でしたが、リンク先のニュースページでは一体何を言っているのかイマイチわからなかったため気付くのが遅れました。このニュースリリースから、My Security Credentialsは提供が開始されています。
そしてこれにより、IAM Userのリスト権限は不要となりました。以下、実際の操作をご紹介します。

実際の設定画面を確認する

今回は、Policyを新しくしたユーザである「IAMTestUser2_New」でログインしています。まずは先ほどと同じようにIAMのユーザをリストしてみましょう。上画像の通り必要な権限が付与されていないため、リストは不可能となっておりエラーメッセージが表示されます。エラーメッセージの中の赤枠の通り、”iam:ListUsers”は付与されていないためです。

コンソール右上にあるナビゲーションバーにおいて自分のユーザー名を選択し、その中から [My Security Credentials (セキュリティ認証情報)] を選択します。なお以下のリンクからでもジャンプ可能です。
https://console.aws.amazon.com/iam/home?region=ap-northeast-1#security_credential

[My Security Credentials (セキュリティ認証情報)] を選択すると上画像のページにジャンプします。この画面からMFA デバイスがアサインできるようになっています。

後は先ほどと同じで、仮想 MFA デバイスを選択して設定を継続してください。

DenyAllExceptListedIfNoMFA に iam:DeleteVirtualMFADevice が必要な理由

仮想 MFA デバイスの設定画面では、QRコードを生成するボタンを押下する操作があります。このQRコードを生成するあたりで一度MFAの登録を停止し、再度設定しようとすると、上記のエラー画面が発生します。
これは、AWSの裏側で一度QRコードを作成したタイミングで仮想 MFA デバイスは作成されてしまっており、MFAの設定が完了していない場合でも、次回設定時には iam:DeleteVirtualMFADevice がないと設定ができないという状況に陥ってしまうためです。それを鑑みて、上記のポリシーには iam:DeleteVirtualMFADevice を付与しています。

DenyAllExceptListedIfNoMFA に追加した他のActionについての説明

“iam:ChangePassword”, “iam:CreateLoginProfile”, “iam:DeleteLoginProfile”, “iam:GetLoginProfile”, “iam:UpdateLoginProfile” については、ログイン後即時パスワード変更を求められる場合に、MFAを設定するよりも先にパスワード変更をしなければなりません。そのようなシーンを鑑みて付与しました。

注意点

一度 MFA を設定したら、直ちに一度マネジメントコンソールからログアウトし、再度ログインしてください。その時に MFA の入力を求められるのか必ず確認をしましょう。また、一度ログアウトしてログインしなおさない限り、 MFA を利用したログインと見なされませんので、初回にMFAを設定するために利用したログインセッションは「サインアウト」して一度閉じてください。MFA を設定したらすぐに全ての権限が開放されるような動きにはならない点には注意が必要です。

まとめ

IAM のコンソールに新しく My Security Credentials というページが増えたため、今までMFAを強制する時に必須であった “iam:ListUsers” は不要になりました!この仕様に困っていらした方は、すぐさまIAM Policyを見直していただき、 “iam:ListUsers” のないPolicyに上書きしてしまいましょう。
なお、先に書いた「MFA強制 IAM Policy」につきましては、お客様の利用シーンにおいては他に必要なActionがあったり、減らす必要のあるActionがあったりするでしょう。例えば、AWSのドキュメントには記載がありますが  “AllowManageOwnAccessKeys” に記載がある “iam:CreateAccessKey” は本当に必要でしょうか?
また、いきなり本番環境の IAM Policy を上書きするのではなくしっかりとテストをし、さらに運用面等も鑑みて変更を実施頂けますと幸いです。例えば、第3者に提供する「MFA設定手順書」を書き直す必要があるかもしれませんね(心当たりがあります)。

以上になります。ではまたお会いしましょう。

AWSで始める機械学習その1『Comprehend Customを使おう!』

$
0
0

AWSではマネージドな機械学習サービスが様々提供されています。

ComprehendやTranscribe等で、ユーザーがInputを与え簡単に機械学習で予測することはもちろん、SageMakerで

しかし、私のような機械学習初心者からすると、いきなりSageMakerを使うのはハードルが高く、ComprehendやTranscribeでできる範囲で予測を行うにとどまってしまいます。

ということで、AWSのサービスを使いつつ、ざっくり機械学習についてできることを増やしていこうというのがこの記事の目的です。

Comprehend Custom<とは?

Amazon Comprehendは自然言語処理のマネージドサービスです。文章を与えればエンティティ分析・感情分析・キーフレーズ分析等々が簡単にできます。

Amazon ComprehendにはComprehend Customとおいう機能もあります。こちらは、ユーザーが学習データを用意するだけで簡単にモデルが作成できるというものです。

機械学習の知識がなくとも簡単に利用できるので、機械学習初心者ユーザーにとってはとてもありがたい機能です。

Comprehend Customでは2018/04/02時点でCustom ClassificationとCustom Entity Recognitionが利用できます。

Custom Classificationは、独自のデータでトレーニングしたモデルで文章の分類を行えます。Custom Entity Recognitionも同様に、独自のデータでトレーニングしたモデルでエンティティ分析ができます。

実際に使ってみる

今回は学習データの用意が簡単なCustom Classificationを利用します。

学習データ用意

Custom Classificationのドキュメントに学習データについて記載があります。各カテゴリにつき1000の文章があることが推奨されるそうです。今回はでお試しなのでEC2, IAM, Auroraのドキュメントから、それぞれ50の文章を抜粋して、以下のようなCSVファイルを作成し学習データとします(”,” や “.” は抜いてあります

EC2,Amazon Elastic Compute Cloud (Amazon EC2) provides scalable computing capacity in the Amazon Web Services (AWS) cloud Using Amazon EC2 eliminates your need to invest in hardware up front so you can develop and deploy applications faster You can use Amazon EC2 to launch as many or as few virtual servers as you need configure security and networking and manage storage Amazon EC2 enables you to scale up or down to handle changes in requirements or spikes in popularity reducing your need to forecast traffic
EC2,An instance is a virtual server in the cloud It's configuration at launch is a copy of the AMI that you specified when you launched the instance
EC2,You can launch different types of instances from a single AMI An instance type essentially determines the hardware of the host computer used for your instance Each instance type offers different compute and memory capabilities

あとはS3バケットへ保存すればOKです。

Comprehend Customでトレーニング

今回はComprehendのコンソールからトレーニングを実行します。

「Cutom Classification」の「Train Classifier」をクリック。

Nameを入力、言語を選択します。今回は英語です。

学習データの場所を指定します。

今回Comprehend Customを利用するのは初めてなので、IAMロールは新規作成します。

これで設定は終了。あとはステータスが「Trained」になるを待つだけです。

予測してみる

それではトレーニングしたモデルで予測してみます。

Inputとするデータは以下のように作成し、S3バケットへ保存しました。(AWSサポートナレッジセンターにあるEC2の質問文です

How do I launch an EC2 instance from a custom Amazon Machine Image (AMI)?
How do I create an EBS snapshot based on my EBS volume?
My Spot instance was terminated Can I recover it?

「Create Job」をクリック。

JobのNameを入力。Analysis typeとSelect classfierはすでに選択されています。
Inputの場所を指定します。

Outputの場所を指定します。IAMロールをしていします。

ジョブ作成はこれで完了。
あとは予測結果が出るのを待ちます。StatusがCompletedとなればOKです。

結果

結果は以下のようになりました。以下は上記で記載したInputの1行目の結果です。

{
    "File": "input.txt", 
    "Line": "0", 
    "Classes": [{
        "Name": "EC2", 
        "Score": 0.3337
    }, 
    {
        "Name": "Aurora", 
        "Score": 0.3332
    }, 
    {
        "Name": "IAM", 
        "Score": 0.3331
    }
    ]
}

…….

学習データが各カテゴリで50個ずつしかなかったのと、文章が短かったこともあり、まったく精度が出ていません…

まとめ

いかがでしたでしょうか。

今回は学習データが少なかったので、精度が出ませんでしたが、データを用意するだけで、簡単にモデルをトレーニングできるということが分かったかと思います。

次回はAmazon Machine Learningを扱いたいと思います。

[EC2]東京リージョンで構築可能なインスタンスタイプのアベイラビリティーゾーン別一覧表

$
0
0

CS課佐竹です。
前回は「IAMに関する話」を記載させて頂きましたが、今回はEC2になります。

はじめに

EC2には様々なインスタンスタイプ(Instance Type)が存在します。実際にどのくらい種類があるかというと、「こちら」のドキュメントを(可能ならEnglishで)ご確認ください。凄く・・・多いです。そして、それらすべてが東京リージョン(ap-northeast-1) で作成可能か?というと、実はそうではありません。
今回は、リージョンの制限と、さらに存在するアベイラビリティーゾーン制限の2つの詳細を追いかけます。なお、リージョンとアベイラビリティーゾーンについての詳しい説明は「こちら」の公式ドキュメントをご参照ください。

補足:2019年4月11日にmetal系のInstanceも調査に追加し、全185種類の結果を表示するよう更新しました

リージョンにおける構築可能インスタンスタイプの制限

まずはリージョンの制限です。具体的な例でご説明いたします。
例えば、今現在、以下の記事で紹介があります C5n というインスタンスタイプは、東京リージョンでは起動できません。

100 Gbps のネットワーク帯域幅を備えた Amazon EC2 C5n インスタンスの紹介

特に新しくリリースされたインスタンスタイプで多くみられますが、まずは「米国東部 (バージニア北部、オハイオ)、米国西部 (オレゴン)、欧州 (アイルランド)」の3つのリージョンで提供されることが多い状況です。このため、 C5n というインスタンスタイプが存在していても、C5nは東京リージョンでは起動(Launch)できないという制限が存在します(2019年4月11日現在)。「新しいインスタンスタイプが出たから早速東京リージョンで使おう!」としても構築できない場合もありますのでご注意ください。

アベイラビリティーゾーンにおける構築可能インスタンスタイプの制限

リージョンの制限と同じく、アベイラビリティーゾーン(Availability Zone:以下AZと省略します)にも同様の制限があります。今回はそれを詳しく調べました。このAZにおける構築可能インスタンスタイプの制限については公式なドキュメントが存在しないため、2019年4月11日時点の独自の調査結果となりますことを先に述べさせて頂きます。

まず、現在東京リージョンには ap-northeast-1a(単に1aとも言う)、ap-northeast-1c(1c)、ap-northeast-1d(1d) の3つのAZが存在します。ap-northeast-1b(1b) については古いAWSアカウントでは表示されますが、新しいAWSアカウントでは表示されないものとなりますため今回は1bは対象外として調査結果を報告します。
※ご利用中のアカウントによっては、1bの代わりに古いAZとして1aが表示されていないアカウントも存在するかと思います。その場合は、以後1bを1aに置き換えてお読みください

具体的な例ですが、最も新しい1dのAZでは、「旧世代のインスタンスタイプ」とされるm1等のインスタンスタイプは構築が不可能です。しかし、1a,1cではこれらは構築可能です。このようなAZにおけるキャパシティの差が現実問題存在しています。そしてこの差を鑑みて冗長構成をとらないといけない、というハードルも存在します。これを把握していないと「冗長構成のためにAZを1aと1d」で組みましょうと提案していたのに「すみません、実際に構築してみたら、1dでは m3のインスタンスタイプが全て利用できませんでしたため、冗長構成が取れないことが判明しました」という事態に陥る可能性があります。今回はこれを予め避けるための調査及び報告となります。

補足ですが、今現在m3のインスタンスタイプは旧世代にあたりますため、実際にご利用を推奨することは減ってきています。

具体的な調査方法

「どのAZでどのインスタンスタイプが構築可能か?」というのは、実際問題、試してみないとわかりません。ということになるのですが、全ての組み合わせをLaunchすると(EC2が大量に構築されて)大変なことになってしまうため、今回は run-instances のAPIを利用しました。今現在、 run-instances には –dry-run のオプションが存在します。これは、APIが成功しても実際にはエラーとなり構築が行われないもので、 run-instances のAPIが実際にワークするのか?を検証するために利用されます。今回はこれを活用します。

実際に利用したコマンド

以下のような run-instances のコマンドを全AZ、全インスタンスタイプで実行します。AZはSubnetに紐づいているので、このコマンドをインスタンスタイプ別に 3つのSubnet = 3つのAZで実行したら完了となります。さらっと書いてますが、インスタンスタイプは 185 種類、AZは 3 ですので、掛け算で 555 回の実行となります。

aws ec2 run-instances --dry-run --image-id ami-086063d8c95bfa211 --key-name satake_tokyo_Test --count 1 --security-group-ids sg-XXXXXXXX --subnet-id subnet-XXXXXXXX --instance-type a1.medium

なお、ami-086063d8c95bfa211 はAWSが出荷しているAmazon LinuxのImageになっています。

結果(アベイラビリティーゾーン別一覧表)

以下の表に結果を表示します。前提として、私のローカルアカウントのため、上限緩和申請はほぼほぼ初期状態ということをご理解ください。なお「成功」となっているものが、問題なく構築可能とご理解頂いて問題ありません。

nstance Type 1a (apne1-az4) 1c (apne1-az1) 1d (apne1-az2)
a1.medium 東京Region未対応 東京Region未対応 東京Region未対応
a1.large 東京Region未対応 東京Region未対応 東京Region未対応
a1.xlarge 東京Region未対応 東京Region未対応 東京Region未対応
a1.2xlarge 東京Region未対応 東京Region未対応 東京Region未対応
a1.4xlarge 東京Region未対応 東京Region未対応 東京Region未対応
m4.large 成功 成功 成功
m4.xlarge 成功 成功 成功
m4.2xlarge 成功 成功 成功
m4.4xlarge 成功 成功 成功
m4.10xlarge 成功 成功 成功
m4.16xlarge 成功 成功 成功
m5.large 成功 成功 成功
m5.xlarge 成功 成功 成功
m5.2xlarge 成功 成功 成功
m5.4xlarge 成功 成功 成功
m5.12xlarge 成功 成功 成功
m5.24xlarge 成功 成功 成功
m5.metal 成功 成功 成功
m5a.large 成功 他のAZで構築可能 成功
m5a.xlarge 成功 他のAZで構築可能 成功
m5a.2xlarge 成功 他のAZで構築可能 成功
m5a.4xlarge 成功 他のAZで構築可能 成功
m5a.12xlarge 成功 他のAZで構築可能 成功
m5a.24xlarge 成功 他のAZで構築可能 成功
m5ad.large 東京Region未対応 東京Region未対応 東京Region未対応
m5ad.xlarge 東京Region未対応 東京Region未対応 東京Region未対応
m5ad.2xlarge 東京Region未対応 東京Region未対応 東京Region未対応
m5ad.4xlarge 東京Region未対応 東京Region未対応 東京Region未対応
m5ad.12xlarge 東京Region未対応 東京Region未対応 東京Region未対応
m5ad.24xlarge 東京Region未対応 東京Region未対応 東京Region未対応
m5d.large 成功 成功 他のAZで構築可能
m5d.xlarge 成功 成功 他のAZで構築可能
m5d.2xlarge 成功 成功 他のAZで構築可能
m5d.4xlarge 成功 成功 他のAZで構築可能
m5d.12xlarge 成功 成功 他のAZで構築可能
m5d.24xlarge 成功 成功 他のAZで構築可能
m5d.metal 東京Region未対応 東京Region未対応 東京Region未対応
t2.nano 成功 成功 成功
t2.micro 成功 成功 成功
t2.small 成功 成功 成功
t2.medium 成功 成功 成功
t2.large 成功 成功 成功
t2.xlarge 成功 成功 成功
t2.2xlarge 成功 成功 成功
t3.nano 成功 成功 成功
t3.micro 成功 成功 成功
t3.small 成功 成功 成功
t3.medium 成功 成功 成功
t3.large 成功 成功 成功
t3.xlarge 成功 成功 成功
t3.2xlarge 成功 成功 成功
c4.large 成功 成功 成功
c4.xlarge 成功 成功 成功
c4.2xlarge 成功 成功 成功
c4.4xlarge 成功 成功 成功
c4.8xlarge 成功 成功 成功
c5.large 成功 成功 成功
c5.xlarge 成功 成功 成功
c5.2xlarge 成功 成功 成功
c5.4xlarge 成功 成功 成功
c5.9xlarge 成功 成功 成功
c5.18xlarge 成功 成功 成功
c5d.xlarge 成功 成功 他のAZで構築可能
c5d.2xlarge 成功 成功 他のAZで構築可能
c5d.4xlarge 成功 成功 他のAZで構築可能
c5d.9xlarge 成功 成功 他のAZで構築可能
c5d.18xlarge 成功 成功 他のAZで構築可能
c5n.large 東京Region未対応 東京Region未対応 東京Region未対応
c5n.xlarge 東京Region未対応 東京Region未対応 東京Region未対応
c5n.2xlarge 東京Region未対応 東京Region未対応 東京Region未対応
c5n.4xlarge 東京Region未対応 東京Region未対応 東京Region未対応
c5n.9xlarge 東京Region未対応 東京Region未対応 東京Region未対応
c5n.18xlarge 東京Region未対応 東京Region未対応 東京Region未対応
r4.large 成功 成功 成功
r4.xlarge 成功 成功 成功
r4.2xlarge 成功 成功 成功
r4.4xlarge 成功 成功 成功
r4.8xlarge 成功 成功 成功
r4.16xlarge 成功 成功 成功
r5.large 成功 成功 成功
r5.xlarge 成功 成功 成功
r5.2xlarge 成功 成功 成功
r5.4xlarge 成功 成功 成功
r5.12xlarge 成功 成功 成功
r5.24xlarge 成功 成功 成功
r5.metal 東京Region未対応 東京Region未対応 東京Region未対応
r5a.large 成功 他のAZで構築可能 成功
r5a.xlarge 成功 他のAZで構築可能 成功
r5a.2xlarge 成功 他のAZで構築可能 成功
r5a.4xlarge 成功 他のAZで構築可能 成功
r5a.12xlarge 成功 他のAZで構築可能 成功
r5a.24xlarge 成功 他のAZで構築可能 成功
r5ad.large 東京Region未対応 東京Region未対応 東京Region未対応
r5ad.xlarge 東京Region未対応 東京Region未対応 東京Region未対応
r5ad.2xlarge 東京Region未対応 東京Region未対応 東京Region未対応
r5ad.4xlarge 東京Region未対応 東京Region未対応 東京Region未対応
r5ad.12xlarge 東京Region未対応 東京Region未対応 東京Region未対応
r5ad.24xlarge 東京Region未対応 東京Region未対応 東京Region未対応
r5d.large 成功 成功 成功
r5d.xlarge 成功 成功 成功
r5d.2xlarge 成功 成功 成功
r5d.4xlarge 成功 成功 成功
r5d.12xlarge 成功 成功 成功
r5d.24xlarge 成功 成功 成功
r5d.metal 東京Region未対応 東京Region未対応 東京Region未対応
u-6tb1.metal 東京Region未対応 東京Region未対応 東京Region未対応
u-9tb1.metal 東京Region未対応 東京Region未対応 東京Region未対応
u-12tb1.metal 東京Region未対応 東京Region未対応 東京Region未対応
x1.16xlarge 緩和申請が必要 緩和申請が必要 緩和申請が必要
x1.32xlarge 緩和申請が必要 緩和申請が必要 緩和申請が必要
x1e.xlarge 成功 成功 他のAZで構築可能
x1e.2xlarge 成功 成功 他のAZで構築可能
x1e.4xlarge 成功 成功 他のAZで構築可能
x1e.8xlarge 緩和申請が必要 緩和申請が必要 他のAZで構築可能
x1e.16xlarge 緩和申請が必要 緩和申請が必要 他のAZで構築可能
x1e.32xlarge 緩和申請が必要 緩和申請が必要 他のAZで構築可能
z1d.large 成功 成功 他のAZで構築可能
z1d.xlarge 成功 成功 他のAZで構築可能
z1d.2xlarge 成功 成功 他のAZで構築可能
z1d.3xlarge 成功 成功 他のAZで構築可能
z1d.6xlarge 成功 成功 他のAZで構築可能
z1d.12xlarge 成功 成功 他のAZで構築可能
z1d.metal 成功 成功 他のAZで構築可能
d2.xlarge 成功 成功 成功
d2.2xlarge 成功 成功 成功
d2.4xlarge 成功 成功 成功
d2.8xlarge 成功 成功 成功
h1.2xlarge 東京Region未対応 東京Region未対応 東京Region未対応
h1.4xlarge 東京Region未対応 東京Region未対応 東京Region未対応
h1.8xlarge 東京Region未対応 東京Region未対応 東京Region未対応
h1.16xlarge 東京Region未対応 東京Region未対応 東京Region未対応
i3.large 成功 成功 成功
i3.xlarge 成功 成功 成功
i3.2xlarge 成功 成功 成功
i3.4xlarge 成功 成功 成功
i3.8xlarge 成功 成功 成功
i3.16xlarge 成功 成功 成功
i3.metal 成功 成功 成功
f1.2xlarge 東京Region未対応 東京Region未対応 東京Region未対応
f1.4xlarge 東京Region未対応 東京Region未対応 東京Region未対応
f1.16xlarge 東京Region未対応 東京Region未対応 東京Region未対応
g3s.xlarge 成功 成功 他のAZで構築可能
g3.4xlarge 成功 成功 他のAZで構築可能
g3.8xlarge 成功 成功 他のAZで構築可能
g3.16xlarge 成功 成功 他のAZで構築可能
p2.xlarge 成功 成功 他のAZで構築可能
p2.8xlarge 成功 成功 他のAZで構築可能
p2.16xlarge 緩和申請が必要 緩和申請が必要 他のAZで構築可能
p3.2xlarge 成功 成功 他のAZで構築可能
p3.8xlarge 成功 成功 他のAZで構築可能
p3.16xlarge 緩和申請が必要 緩和申請が必要 他のAZで構築可能
p3dn.24xlarge 東京Region未対応 東京Region未対応 東京Region未対応
m1.small 成功 成功 他のAZで構築可能
m1.medium 成功 成功 他のAZで構築可能
m1.large 成功 成功 他のAZで構築可能
m1.xlarge 成功 成功 他のAZで構築可能
m3.medium 成功 成功 他のAZで構築可能
m3.large 成功 成功 他のAZで構築可能
m3.xlarge 成功 成功 他のAZで構築可能
m3.2xlarge 成功 成功 他のAZで構築可能
t1.micro 成功 成功 他のAZで構築可能
c1.medium 成功 成功 他のAZで構築可能
c1.xlarge 成功 成功 他のAZで構築可能
cc2.8xlarge 成功 成功 他のAZで構築可能
c3.large 成功 成功 他のAZで構築可能
c3.xlarge 成功 成功 他のAZで構築可能
c3.2xlarge 成功 成功 他のAZで構築可能
c3.4xlarge 成功 成功 他のAZで構築可能
c3.8xlarge 成功 成功 他のAZで構築可能
m2.xlarge 成功 成功 他のAZで構築可能
m2.2xlarge 成功 成功 他のAZで構築可能
m2.4xlarge 成功 成功 他のAZで構築可能
cr1.8xlarge 東京Region未対応 東京Region未対応 東京Region未対応
r3.large 成功 成功 他のAZで構築可能
r3.xlarge 成功 成功 他のAZで構築可能
r3.2xlarge 成功 成功 他のAZで構築可能
r3.4xlarge 成功 成功 他のAZで構築可能
r3.8xlarge 成功 成功 他のAZで構築可能
hs1.8xlarge 東京Region未対応 東京Region未対応 東京Region未対応
i2.xlarge 成功 成功 他のAZで構築可能
i2.2xlarge 成功 成功 他のAZで構築可能
i2.4xlarge 成功 成功 他のAZで構築可能
i2.8xlarge 成功 成功 他のAZで構築可能
g2.2xlarge 成功 成功 他のAZで構築可能
g2.8xlarge 成功 成功 他のAZで構築可能

エラーメッセージと判定条件

上記の判定には以下のエラーメッセージを利用しています。

成功

An error occurred (DryRunOperation) when calling the RunInstances operation: Request would have succeeded, but DryRun flag is set.

このメッセージは、DryRunOperation が引数として存在しているために失敗と判断されたもので、実際に –dry-run を外せば「成功」するものと判定しています。つまり、成功と記載があるものは、そのAZにて構築が可能と判断されるものです。

他のAZで構築可能

An error occurred (Unsupported) when calling the RunInstances operation: Your requested instance type (m5a.large) is not supported in your requested Availability Zone (ap-northeast-1c). Please retry your request by not specifying an Availability Zone or choosing ap-northeast-1d, ap-northeast-1a.

このエラーは、 m5a.large を ap-northeast-1c にて構築しようとしたときのメッセージです。ap-northeast-1d, ap-northeast-1aでリトライするよう、エラーが表示されています。このような「is not supported in your requested Availability Zone」というエラーメッセージを「他のAZで構築可能」として表に記載しています。
ようは、特定のリージョンでは、特定のInstance Typeが構築できないのが現状であり今回お伝えしたい制限となります。

東京Region未対応

An error occurred (Unsupported) when calling the RunInstances operation: The requested configuration is currently not supported. Please check the documentation for supported configurations.

このエラーは、東京リージョンでは起動できない(サポートされていない)Instance Typeと判断し、一覧では「東京Region未対応」としています。これは、a1 系のInstance Typeが全て同様のエラーメッセージを返したことから、そのような判定としました。

緩和申請が必要

An error occurred (InstanceLimitExceeded) when calling the RunInstances operation: You have requested more instances (1) than your current instance limit of 0 allows for the specified instance type. Please visit http://aws.amazon.com/contact-us/ec2-request to request an adjustment to this limit.

このエラーは、利用予定のAZにおいて、上限緩和申請が必要であることを表しているエラーとなります。インスタンスタイプによっては、初期の構築可能数が 0 台のインスタンスも存在しており、利用には予め緩和申請を実施することが前提とされています。このエラーが表示された場合は、上限緩和申請をクリアしてから構築をしてください。

EC2の上限緩和申請につきましては「こちら」のドキュメントをご参照ください。

まとめ

いかがだったでしょうか。上記の通り、東京リージョンの内部においてもAZごとに構築可能なインスタンスタイプに制限がかけられていることがご理解いただけたかと思います。
特徴をまとめますと

  • 旧世代のインスタンスタイプは、東京リージョンの1dでは構築できない
  • m5dとc5d、z1dについては東京リージョンの1dでは構築できない
  • m5aとr5aについては東京リージョンの1cでは構築できない
  • 1aは現状全てのインスタンスタイプに対応している

となります。
なお、これらは2019年4月11日時点の情報となりますため、最新の対応状況は各自APIを実行して結果を確認頂けますと幸いです。

それではまたお会いしましょう。

Lambda上でAWSCLIを動かしてS3 Syncする

$
0
0
こんにちは、技術一課の加藤です。
 
AWS CLIのS3 Sync、便利ですよね。
コピー元とコピー先の付き合わせやバージョンの比較など、Sync処理において面倒だな、と思うことを全部端折ってくれるS3 Syncは、まさにバケット間データ移動の最適解といえるでしょう。
 
しかしこれを定期実行したい、となるとやや面倒です。実はAWS SDKにはS3 Syncと同様の機能がないため、Lambdaでいい感じに実装しようと思うと考慮すべきことが色々出てきてしまいます。
 
S3バケットのSyncがしたい! でもAWS SDKで実装するのも面倒くさい!
 
そうしてやってみたのが「Lambda上でAWS CLIを動かす」というアクロバティック実装です。

実装方法

極力AWS CLIをLambda内で使うために必要な手順に絞って解説を行うため、

  • S3バケット同士のSync
  • 2つのS3バケットおよびLambdaは同一アカウント上に存在
という前提でご説明をします。
クロスアカウントで実装したい場合(そのパターンが圧倒的に多いと思いますが)この辺の記事を参照しつつLambdaからS3へのアクセス許可を設定してみてください。
 
また以下のリソースはご自身で用意しておいてください。
  • 送信元/先のS3バケット(計2つ)
  • 作ったバケットに対するアクセス権限を持つLambda
なおS3 Syncの仕様上、Lambdaの実行権限には最低でも
  • s3:ListBucket
  • s3:GetObject
  • s3:PutObject
が必要となります。もし権限を絞るのが面倒であれば、S3へのフルアクセスを与えておいてください。
ちなみに対象リソースは「バケット自体」と「バケット以下のオブジェクト全て」を指定する必要があります。
バケット名が「src-bucket」であれば、「arn:aws:s3:::src-bucket」および「arn:aws:s3:::src-bucket/*」へのアクセス権限を与えてください。
 

関数の作成

まずディレクトリを作成しAWS CLIをローカルインストールします
以降のコマンド・コードはPython 3.7.2環境にて動作確認済みになります。他のバージョンで実行する際にはご注意ください。)

$ mkdir lambda-cli
$ cd lambda-cli
$ pip install awscli -t .

次に、AWS CLIをPythonスクリプトから呼ぶためのラッパースクリプトを作成します。
 
AWS CLIは文字通りCLIから呼び出すことを想定して作られているため、ローカルインストールしたAWS CLIを普通にプログラムにimportして使おうと思うと引数の与え方などがやや面倒です。このため、コマンド的に利用できるようにラッパースクリプトを挟んでやる必要があります。
$ touch aws
$ chmod +x aws

awsファイルには以下を書き込んでください。
#!/usr/bin/env python3
import sys
import awscli.clidriver


def main():
    return awscli.clidriver.main()


if __name__ == '__main__':
    result = main()
    sys.exit(result)
awsファイルが正しく動作するか確認してください。helpが表示されればOKです。
$ ./aws
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: the following arguments are required: command
最後にlambda_functionファイルを作成します
$ touch lambda_function.py

以下のコードを書き込んでください。subprocessを用いて実際にawsコマンドを呼び出すスクリプトになります。
import subprocess


def lambda_handler(event, context):
    cmd = './aws s3 sync s3://<src bucket name> s3://<dest bucket name>'
    result = subprocess.run(
        cmd.split(" "),
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT
    )
    print(result.stdout.decode())
 
以上が完了したら、コードをzip化しLambdaにデプロイします。
$ zip -r lambda-cli ./*
今回は特に渡すパラメータもないので、送信元バケットにファイルをおき、Lambdaのテスト実行を行うと動作が確認できます。
 
処理に意外と時間がかかるので、1ファイルのSyncであってもタイムアウトを10秒程度まで伸ばしておくことをお勧めします。
 

おわりに

LambdaでAWS CLIを動かしたい場合、カスタムランタイムを使うという方法もあります。こちらも後日試しに実装してみる予定なので、また記事にしますね。
とはいえやっぱりアクロバティック感は否めないので、ご利用は自己責任でお願いしますね。
 

DSaaSのライセンス超過時の動作を確認した

$
0
0

Trend MicroのDSaaS(Deep Security as a Service)で消費ライセンスをどうカウントしているかが気になったので検証してみました。

検証環境

5台分のライセンスがあり、コンピュータ5台を保護対象し、すでにライセンスを使い切っている状態です。
ちなみにトライアルライセンスで検証しているので無償と表示されています。

ライセンス超過する数のコンピュータを追加した時の動作

DSM(Deep Security Manager)からダウンロードできるインストールスクリプトを実行したところ下記のようになりました。
Error: activation was not successful となっているがわかります。
(こちらのログはインストールスクリプトを何回か試した後の物なので、「既にインストールされています」となっていますが、そこは気にしないでください。)

[ec2-user@ip-10-1-1-10 ~]$ sudo bash install.sh
Downloading agent package…
Installing agent package…
準備しています… ################################# [100%]
パッケージ ds_agent-11.3.0-235.amzn2.x86_64 は既にインストールされています。
HTTP Status: 200 – OK
Activation will be re-attempted 30 time(s) in case of failure
dsa_control
HTTP Status: 400 – OK
Response:
Attempting to connect to https://agents.deepsecurity.trendmicro.com:443/
SSL handshake completed successfully – initiating command session.
Connected with (NONE) to peer at agents.deepsecurity.trendmicro.com
Received a ‘GetHostInfo’ command from the manager.
Error: activation was not successful. The manager may not be configured to allow agent-initiated activation,
or the manager may not be configured to allow re-activation of existing hosts.
Check the manager’s System Events for more information.
Operation failed, 30 attempts left; will retry in about 10 seconds
Retrying getting new client connection
dsa_control
HTTP Status: 400 – OK
Response:
Attempting to connect to https://agents.deepsecurity.trendmicro.com:443/
SSL handshake completed successfully – initiating command session.
Connected with (NONE) to peer at agents.deepsecurity.trendmicro.com
Received a ‘GetHostInfo’ command from the manager.
Error: activation was not successful. The manager may not be configured to allow agent-initiated activation,
or the manager may not be configured to allow re-activation of existing hosts.
Check the manager’s System Events for more information.
Operation failed, 29 attempts left; will retry in about 300 seconds

追加したコンピュータのステータスは 複数のエラー となり、管理対象(オンライン)とはなりません。

管理対象(オンライン)のコンピュータを停止した時の動作

管理対象(オンライン)となっている1台のEC2インスタンスを停止してみました。
管理対象(オンライン)から管理対象(VM停止)に変化しました。

数分経過後、複数のエラーとなっていたコンピュータが自動的に管理対象(オンライン)となりました。
そういえば、Activationに失敗した時のログを見ると、Operation failed, 29 attempts left; will retry in about 300 seconds とあります。
どうもデフォルトで5分間隔・最大30回のActivationリトライを繰り返すようです。
ここら辺の数値は、インストールスクリプトを修正することで変更できるようです。(Command-line basics

まとめ

DSaaSのライセンスは停止しているコンピュータには消費されないことがわかりました。
また、5分間隔で再アクティベーションを繰り返すことがわかりました。

Marketplace(Centos.org)提供CentOS7AMIのマイナーバージョンを調べてみた(2019/4/15現在)

$
0
0

こんちには、技術3課の城です。

当社ではAWS環境でLinuxを利用する多くのケースでAmazonLinux2をお勧めしています。
ただ、アプリケーション要件により、どうしても他のOSを利用する必要がある場合があります。
先日も、とある案件にてCentOS7を利用する必要があり、かつ動作保証のマイナーバージョンが限られていたため、どのAMIが対応しているか確認しました。
Centos.orgが提供しているMarketplaceの中やAMI情報にはマイナーバージョンの記載がなかったため、実際に構築して確認しました。
内容について備忘としてブログを残しておきます。

Centos.orgのAMI一覧

Marketplaceの画面で対象AMIを確認することもできますが、AWSCLIでサクッと一覧を出すことが出来ます。

【コマンド】

aws ec2 describe-images \
    --region ap-northeast-1 \
    --owners aws-marketplace \
    --filters Name=product-code,Values=aw0evgkw8e5c1q413zgy5pjce \
    --query "reverse(sort_by(Images, &CreationDate))[].[ImageId,Description,ImageLocation]"

【結果】

[
    [
        "ami-045f38c93733dd48d",
        "CentOS Linux 7 x86_64 HVM EBS ENA 1901_01",
        "aws-marketplace/CentOS Linux 7 x86_64 HVM EBS ENA 1901_01-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-05713873c6794f575.4"
    ],
    [
        "ami-8e8847f1",
        "CentOS Linux 7 x86_64 HVM EBS ENA 1805_01",
        "aws-marketplace/CentOS Linux 7 x86_64 HVM EBS ENA 1805_01-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-77ec9308.4"
    ],
    [
        "ami-3185744e",
        "CentOS Linux 7 x86_64 HVM EBS ENA 1804_2",
        "aws-marketplace/CentOS Linux 7 x86_64 HVM EBS ENA 1804_2-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-55a2322a.4"
    ],
    [
        "ami-91c4d3ed",
        "CentOS Linux 7 x86_64 HVM EBS ENA 1803_01",
        "aws-marketplace/CentOS Linux 7 x86_64 HVM EBS ENA 1803_01-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-8274d6ff.4"
    ],
    [
        "ami-4dd5522b",
        "CentOS Linux 7 x86_64 HVM EBS 1708_11.01",
        "aws-marketplace/CentOS Linux 7 x86_64 HVM EBS 1708_11.01-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-95096eef.4"
    ]
]

製品コードについて

対象AMIのエントリの中に含まれていますので、下記コマンドで確認可能です。

【コマンド】

aws ec2 describe-images \
    --image-ids ami-045f38c93733dd48d \
    --query 'Images[].ProductCodes[].ProductCodeId'

【結果】

[
    "aw0evgkw8e5c1q413zgy5pjce"
]

また、対象のAMIから構築したインスタンスが存在する場合はインスタンスメタデータでも確認することが出来ます。

【コマンド】

$ curl http://169.254.169.254/latest/meta-data/product-codes

【結果】

aw0evgkw8e5c1q413zgy5pjce

バージョン確認

いざ本題ですが、/etc/redhat-releaseの内容となります。

AMI Description AMI ID OSバージョン
“CentOS Linux 7 x86_64 HVM EBS ENA 1901_01” ami-045f38c93733dd48d CentOS Linux release 7.6.1810 (Core)
“CentOS Linux 7 x86_64 HVM EBS ENA 1805_01” ami-8e8847f1 CentOS Linux release 7.5.1804 (Core)
“CentOS Linux 7 x86_64 HVM EBS ENA 1804_2” ami-3185744e CentOS Linux release 7.5.1804 (Core)
“CentOS Linux 7 x86_64 HVM EBS ENA 1803_01” ami-91c4d3ed CentOS Linux release 7.4.1708 (Core)
“CentOS Linux 7 x86_64 HVM EBS 1708_11.01” ami-4dd5522b CentOS Linux release 7.4.1708 (Core)

※2019/4/15現在、東京リージョンにおける情報です。

最後に

単純に確認した結果ではありますが、どなたかの助けになれば幸いです。

【参考ドキュメント】
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/paid-amis.html

S3の署名バージョン2 廃止に対応する方法を調べてみた(Embulk S3プラグイン編)

$
0
0

S3の「署名バージョン2」廃止と、サードパーティツールのS3プラグインへの影響

S3の署名バージョン2 廃止にAWS CLIやSDKをバージョンアップせずに対応する方法を調べてみた

に関連して、S3を利用するサードパーティツールへの影響についても調べてみました。

S3はデータのETL処理(Extraction Transformation and Load)において、加工前データ・加工後データの保存先として利用されることが多く、サードパーティのETLツールにも、S3用のプラグインが用意されています。

これらサードパーティツールのS3プラグインの内部では、AWS SDKが利用されているため、これらのバージョンが古い場合、S3へのAPIリクエスト時の署名バージョンが「署名バージョン2」になっている可能性があり、プラグインの入れ替えやツール自体のアップデートが必要になる可能性があります。

今回は、ETL処理で良く利用される「Embulk」のS3プラグイン「embulk-input-s3」で、S3の署名バージョン2 廃止に対応する方法を調べてみました。

Embulkの「embulk-input-s3」で S3の「署名バージョン2」廃止に対応する方法

※ あくまで対応方法の一つになりますが、ご参考にしていただければ幸いです。また、以下に記載している方法は実際の環境で動作をご検証のうえご利用ください。

Embulkの「embulk-input-s3」のバージョンと、利用されている「aws-sdk」のバージョンを調べる

インストール済みの「embulk-input-s3」プラグインのバージョンを確認

$ embulk gem list
2019-XX-XX 05:12:55.465 +0000: Embulk v0.8.8

(中略)

embulk-input-s3 (0.2.7)

「embulk-input-s3」プラグインの classpath ディレクトリに移動し、利用されている「aws-java-sdk」のバージョンを調べます。

$ ls ~/.embulk/jruby/2.2.0/gems/embulk-input-s3-0.2.7/classpath/
aws-java-sdk-core-1.10.33.jar  embulk-input-s3-0.2.7.jar
aws-java-sdk-kms-1.10.33.jar   httpclient-4.3.6.jar
aws-java-sdk-s3-1.10.33.jar    httpcore-4.3.3.jar
commons-codec-1.6.jar          jcl-over-slf4j-1.7.12.jar

上記のように「aws-java-sdk/1.11.xx」より以前のバージョンが利用されている場合、S3へのアクセスの署名バージョンはデフォルトで署名バージョン2になっているため対応が必要になります。

実際にEmbulkを実行し、S3バケットにアクセス、その際の署名バージョンを確認してみる

config.yml は対象のS3バケットにアクセスする設定

in:
  type: s3
  bucket: sigv2-test-bucket
  path_prefix: test/
 :
 :

Embulkを実行

$ embulk run config.yml

CloudTrailのログを確認してみるとやはり、 SignatureVersionSigV2 となっていました。

:
    :
  "eventTime": "2019-XX-XXT05:19:11Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListObjects",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-sdk-java/1.10.33 Linux/4.4.5-15.26.amzn1.x86_64 Java_HotSpot(TM)_64-Bit_Server_VM/24.80-b11/1.7.0_80]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3.amazonaws.com",
        "max-keys": "1024",
        "prefix": "test/"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV2",
    :
    :

「embulk-input-s3」をバージョンを指定してアップグレードする

下記の手順でプラグインをアップデートすることができます。

$ embulk gem install embulk-input-s3 -v 0.2.21

2019-XX-XX XX:XX:XX.XXX +0900: Embulk v0.8.8
Fetching: embulk-input-s3-0.2.21.gem (100%)
Successfully installed embulk-input-s3-0.2.21
1 gem installed

注意点としては、最新バージョンに上げてしまうとJavaのバージョンとの互換性の問題で、プラグインが動きませんでしたので、「embulk-input-s3」の0.2系の最新バージョンである、「embulk-input-s3 0.2.21」を指定しました。

内部で利用されている「aws-java-sdk」のバージョンを確認すると「1.11.253」が利用されています。

$ ls ~/.embulk/jruby/2.2.0/gems/embulk-input-s3-0.2.21/classpath/

aws-java-sdk-core-1.11.253.jar          ion-java-1.0.2.jar
aws-java-sdk-kms-1.11.253.jar           jackson-annotations-2.6.0.jar
aws-java-sdk-s3-1.11.253.jar            jackson-core-2.6.7.jar
commons-codec-1.9.jar                   jackson-databind-2.6.7.1.jar
embulk-input-s3-0.2.21.jar              jackson-dataformat-cbor-2.6.7.jar
embulk-util-aws-credentials-0.2.21.jar  jcl-over-slf4j-1.7.12.jar
httpclient-4.5.2.jar                    jmespath-java-1.11.253.jar
httpcore-4.4.4.jar

下記の手順は必須ではないですが、古いバージョンのプラグインを削除したい場合は、下記のコマンドで削除することができます。

$ embulk gem uninstall embulk-input-s3
2019-04-04 03:15:59.397 +0000: Embulk v0.8.8

Select gem to uninstall:
 1. embulk-input-s3-0.2.7
 2. embulk-input-s3-0.2.20
 3. All versions
> 1
Successfully uninstalled embulk-input-s3-0.2.7

再度、Embulkを実行

$ embulk run config.yml

CloudTrailのログを確認し、 SignatureVersionSigV4 になっていることを確認できました。

:
    :
    "eventTime": "2019-XX-XXT05:45:48Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListObjects",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-sdk-java/1.11.253 Linux/4.4.5-15.26.amzn1.x86_64 Java_HotSpot(TM)_64-Bit_Server_VM/24.80-b11 java/1.7.0_80 jruby/9.0.5.0]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3.ap-northeast-1.amazonaws.com",
        "max-keys": "1024",
        "encoding-type": "url",
        "prefix": "test/"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV4",
    :
    :

まとめ

  • S3へのAPIリクエストにおける「署名バージョン2」が2019年6月24日に廃止されます
  • S3を利用するサードパーティツールにも影響があります(内部で利用しているaws-sdkが古い場合)
  • Embulkのようなプラグイン方式でS3プラグインを提供しているツールでは、プラグインの入れ替えで対応が可能です

S3をサードパーティツールから利用されている方は、内部で利用されているaws-sdkのバージョンをご確認いただくことをお勧めいたします。

また、下記関連記事もご参考にいただければ幸いです

参考記事:「S3の署名バージョン2 廃止にAWS CLIやSDKをバージョンアップせずに対応する方法を調べてみた
参考記事:「ETLツール「Talend」でS3署名バージョン2廃止に対応する方法

CUIでGmail

$
0
0

はじまり

こんにちはCI部の千葉です。
当社では、お客さまとのコミュニケーションには Backlog 、社内のコミュニケーションには Slack を使っているので多くのエンジニアは日々の業務でメールを利用しません。

とは言え、名刺にメールアドレスを書いているのでメールチェックしない。ってワケにもいかないのでWebブラウザGmailを開いているのが実情です。

わたしは、ずっと Inbox by Gmail を好きで使っていたのですが、残念ながら2019年3月末をもってサービス終了してしまいました。
しかたがないので4月からは Gmail を使っているのですが、これがウンザリする程にメモリを喰うんです。(なんと1.5GB!)

業務でメインに使うツールがリソースを消費するのは良いのですが、上記のとおり殆ど利用しないメールにメモリを掴まれるなんて許せません。
ってワケで、なんとか最小のリソースでGmailを使えないかと挑戦したので結果をココに報告したいと思います。

実行環境

  • macOS Mojave (Version 10.14.4)
  • iTerm 3.2.8
  • Homebrew 2.1.1

Mutt のインストール

Mutt(マット) はテキストベースのメールクライアントです。
これをGmailのキーボードショートカットで操作できるようにカスタマイズしたいと思います。

$ brew install mutt

Google アカウントのアプリパスワードを生成

Sign in using App Passwords の『アプリ パスワードの生成方法』手順に従ってアプリパスワードを生成します。

設定ファイルの作成

Gmailのショートカットキーと操作感を合わせておきたいので以下の内容で ~/.muttrc ファイルを作成します。

set realname = "{{first and last name}}"
set from = "{{gmail username}}@gmail.com"
set use_from = yes
set envelope_from = yes
set smtp_url = "smtps://{{gmail username}}@gmail.com@smtp.gmail.com:465/"
set smtp_pass = "{{app password}}"
set imap_user = "{{gmail username}}@gmail.com"
set imap_pass = "{{app password}}"
set folder = "imaps://imap.gmail.com:993"
set spoolfile = "+INBOX"
set ssl_force_tls = yes
set hostname = gmail.com
set mail_check = 300
set timeout = 300
set postponed = "+[GMail]/Drafts"
set header_cache=~/.mutt/cache/headers
set message_cachedir=~/.mutt/cache/bodies
set certificate_file=~/.mutt/certificates
set signature =~/.mutt/signature
set move = no
set include
set sort = 'threads'
set sort_aux = 'reverse-last-date-received'
set auto_tag = yes
set editor = "vim"
set charset = "utf-8"
set record = ""
set pager_index_lines = 10
set pager_context = 3
set pager_stop
set menu_scroll
set tilde
unset markers
set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+"
alternative_order text/plain text/enriched text/html
ignore "Authentication-Results:"
ignore "DomainKey-Signature:"
ignore "DKIM-Signature:"
hdr_order Date From To Cc
alternative_order text/plain text/html *
auto_view text/html

# Shortcuts
macro index,pager y "<enter-command>unset trash
 <delete-message>" "Gmail archive message"
macro index,pager d "<enter-command>set trash=\"imaps://imap.googlemail.com/[GMail]/Bin\"
 <delete-message>" "Gmail delete message"
macro index,pager gi "<change-folder>=INBOX<enter>" "Go to inbox"
macro index,pager ga "<change-folder>=[Gmail]/All Mail<enter>" "Go to all mail"
macro index,pager gs "<change-folder>=[Gmail]/Starred<enter>" "Go to starred messages"
macro index,pager gd "<change-folder>=[Gmail]/Drafts<enter>" "Go to drafts"
bind pager k previous-line
bind pager j next-line
bind attach <return> view-mailcap

# Side
set sidebar_visible = yes
set sidebar_width = 30
color sidebar_new color221 color233
bind index,pager <down> sidebar-next
bind index,pager <up> sidebar-prev
bind index,pager <right> sidebar-open

# Status
set status_chars = " *%A"
set status_format = "---[ Folder: %f ]---[%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]---%>-%?p?( %p postponed )?---"

# Index
set date_format = "%m/%d"
set index_format = "[%Z] %D %-20.20F %s"
set sort = threads
set sort_aux = reverse-last-date-received
set uncollapse_jump
set sort_re
set reply_regexp = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*"

# Deleted message
color index red default "!~N ~D"
color index red white "~N ~D"

動的な値は以下を参考に編集してください。

項目
{{first and last name}} 名前 User Name
{{gmail username}} Gmail のアカウント名 account_name
{{app password}} Google のアプリパスワード example_secret

実行

以下のコマンドを実行してメーラーを起動します。

$ mutt

起動されたイメージが↓こちらです。
実際のメールが表示されちゃうのでモザイクだらけになってしまいましたが、ブラウザ版のGmailのデザイン・ショートカットキーを踏襲しています。

この状態でのiTerm2が利用しているメモリが150MBでした。ブラウザ利用の1/10で済むようになったので大満足です。

ども

ETLツール「Talend」でS3署名バージョン2廃止に対応する方法

$
0
0

TalendのS3コンポーネントと「S3署名バージョン2廃止」の影響

S3の署名バージョン2 廃止にAWS CLIやSDKをバージョンアップせずに対応する方法を調べてみた
S3の署名バージョン2 廃止に対応する方法を調べてみた(Embulk S3プラグイン編)

に引き続き、ETLツールである、Talend で提供されているS3用コンポーネント(「t3Get」など)が、「S3署名バージョン2廃止」による影響があるかを調べました。

検証に利用したTalendのバージョンなどの情報は下記になります。

古いバージョンでの検証なので、あまり需要は無いかもしれませんが、参考情報として載せておきたいと思います。

項目 バージョン
検証したTOSのバージョン Talend Open Studio 「TOS_DI-20150508_1414-V5.6.2」
検証したS3用コンポーネント t3Get
内部で利用されているAWS Java SDK aws-sdk-java/1.9.13

上記のようにaws-sdk-javaのバージョンは、署名バージョン 2 から署名バージョン 4 への移行 に記載のある aws-sdk-java/1.11.x より古い、バージョンになっていました。

先に結論:「t3Get」コンポーネントのRegion設定の内容によって、署名バージョンが異なる

色々と試行錯誤したのですが、先に検証結果の結論を書いておきますと、

「t3Get」コンポーネントのRegion設定の内容によって、署名バージョンが異なる

でした。

「t3Get」コンポーネントのRegion設定に「Default」を指定した場合

下記画像のように、「t3Get」コンポーネントには、Regionの指定をする欄があり「Default」を指定すると署名バージョン2になります。

CloudTrailのログ (SignatureVersionSigV2 になっている)

:
    :

    "eventTime": "2019-XX-XXTXX:XX:XXZ",
    "eventSource": "s3.amazonaws.com",
    "eventName": "GetObject",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-sdk-java/1.9.13 Windows_Server_2012_R2/6.3 Java_HotSpot(TM)_64-Bit_Server_VM/24.80-b11/1.7.0_80]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3.amazonaws.com",
        "key": "test/s3.png"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV2",
    :
    :

「t3Get」コンポーネントのRegion設定に明示的にリージョンを指定した場合

Regionの指定をする欄に明示的にリージョンを指定すると署名バージョン4になりました。

CloudTrailのログ (SignatureVersionSigV4 になっている)

:
    :
    "eventTime": "2019-XX-XXTXX:XX:XXZ",
    "eventSource": "s3.amazonaws.com",
    "eventName": "GetObject",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "xxx.xxx.xxx.xxx",
    "userAgent": "[aws-sdk-java/1.9.13 Windows_Server_2012_R2/6.3 Java_HotSpot(TM)_64-Bit_Server_VM/24.80-b11/1.7.0_80]",
    "requestParameters": {
        "bucketName": "sigv2-test-bucket",
        "Host": "sigv2-test-bucket.s3-ap-northeast-1.amazonaws.com",
        "key": "test/s3.png"
    },
    "responseElements": null,
    "additionalEventData": {
        "SignatureVersion": "SigV4",
    :
    :

S3の署名バージョン2 廃止にAWS CLIやSDKをバージョンアップせずに対応する方法を調べてみた」にも記載しましたが、 AWS Java SDKとして 1.6.10 以降のバージョンであれば、署名バージョン2から署名バージョン4に切り替えるように、署名バージョンの指定が可能になっています。

おそらくですが、「t3Get」コンポーネントの設定で明示的にリージョンが指定された場合、内部的に署名バージョン4を指定するようなロジックになっているのではないかと推測されます。

※ 上記挙動は、Talendのバージョンによって異なるかもしれませんので、実際に検証いただくことをお勧めいたします。

まとめ

  • S3へのAPIリクエストにおける「署名バージョン2」が2019年6月24日に廃止されます
  • S3を利用するサードパーティツールにも影響があります(内部で利用しているaws-sdkが古い場合)
  • TalendのS3プラグインもコンポーネントの設定によって影響があることがわかった
  • S3をサードパーティツールから利用されている方は、内部で利用されているaws-sdkのバージョンをご確認いただくことをお勧めいたします。

また、下記関連記事もご参考にいただければ幸いです

参考記事:「S3の署名バージョン2 廃止にAWS CLIやSDKをバージョンアップせずに対応する方法を調べてみた
参考記事:「S3の署名バージョン2 廃止に対応する方法を調べてみた(Embulk S3プラグイン編)

Viewing all 1210 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>