AWS PrivateLinkが登場 EC2やELBでどのように使うか

AWS Private link について

先日 AWS Private linkという機能が発表されました。
https://aws.amazon.com/jp/blogs/aws/new-aws-privatelink-endpoints-kinesis-ec2-systems-manager-and-elb-apis-in-your-vpc/

これまでの方式(DynamoDB,S3)はエンドポイントのゲートウェイ経由で各サービスのAPIに接続する形でしたが
新しい方式ではエンドポイントがENIに紐付き、VPCのプライベートIPを持つかたちになります。
この方式のメリットとしては
・セキュリティグループでエンドポイントへのアクセスを管理できるようになる
・エンドポイントにDirect Connectを介してアクセスすることができる
というのが大きいかなと思います。

Private linkに対応するサービス

今回のタイミングで、 以下のサービスが新たにVPCの中から使えるようになりました。
その他のサービスもComing Soonでサポート予定とのこと。

  • Kinesis
  • Service Catalog
  • Amazon EC2
  • EC2 Systems Manager
  • Elastic Load Balancing

EC2やELBでの使いどころ

Kinesisの対応はわかりやすいです。
プライベートなEC2からKinesisにデータプッシュできるとか最高やないか。
でもEC2やELBのエンドポイントって?と私は思ってしまったのでした。
例えば、EC2なら別VPCのパブリックなEC2にプライベートに接続?とかよく分からないことを考え初めてしまった。

基本に立ち返ってドキュメントを確認しました。
新しい方式(インターフェースVPCエンドポイント)についてはまだ日本語のドキュメントはありませんが
原文のドキュメントは以下のURLから参照できます。
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/vpce-interface.html

ページ下部のAccessing an AWS Service Through an Interface EndpointにELBの
エンドポイントにAWS CLIからアクセスする例がありました。

aws elbv2 describe-load-balancers --endpoint-url https://vpce-0f89a33420c193abc-bluzidnv.elasticloadbalancing.us-east-1.vpce.amazonaws.com/

単純にAWS CLIやSDKからAPI操作する際に使えば良いイメージでしょうか。
言われてみれば冒頭のBlogのタイトルも ~Amazon EC2 APIs, and ELB APIs in your VPC でした。

EC2でやってみる

まずは単純にプライベートなEC2でAWS CLIを操作してみます。
当然ですが、接続エラーになりました。

$aws ec2 describe-availability-zones

HTTPSConnectionPool(host='ec2.ap-northeast-1.amazonaws.com', port=443): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<botocore.awsrequest.AWSHTTPSConnection object at 0x7f002bf53e10>, 'Connection to ec2.ap-northeast-1.amazonaws.com timed out. (connect timeout=60)'))

PrivateLinkの作成

コンソールのVPCのメニューからエンドポイント → Create Endpoint と進みます。
S3とDynamodbのエンドポイントしか選択できない場合は、一度コンソールの言語設定を英語にすると
以下のような画面が表示されました。

image.png

Service Name: com.amazonaws.ap-northeast-1.ec2 を選択

VPC, subnet, SecurityGroup:それぞれ任意のものを指定します。
SecurityGroupでは443のインバウンドを許可する必要があります。

Enable for this endpoint:
PrivateLinkのエンドポイントはVPCのIPアドレスを使用するため、VPCのプライベートDNSを使用して
AWSサービスのDNS名を上書きすることができます。
チェックを入れると「ec2.ap-northeast-1.amazonaws.com」のVPC内のルックアップが、
作成するエンドポイントのIPアドレスに解決されます。

上記を指定したら、画面下部のCreate endpointを押下します。

動作確認

先ほどと同じく、プライベートなEC2からAWS CLIを実行します。

$ aws ec2 describe-availability-zones
{
    "AvailabilityZones": [
        {
            "State": "available",
            "ZoneName": "ap-northeast-1a",
            "Messages": []
            "RegionName": "ap-northeast-1"
        },
        {
            "State": "available",
            "ZoneName": "ap-northeast-1c",
            "Messages": [],
            "RegionName": "ap-northeast-1"
        }
    ]
}

Enable for this endpointにチェックを入れているので全く同じコマンドで実行することができました。
プライベートDNS名を有効にしない(チェックを入れない)場合は –endpoint-url で
エンドポイント固有に割り当てられているDNS名を指定すると接続することができます。

$ aws ec2 describe-availability-zones --endpoint-url https://vpce-xxxxxxxxxx-xxxxxx.ec2.ap-northeast-1.vpce.amazonaws.com
{
    "AvailabilityZones": [
        {
            "State": "available",
            "ZoneName": "ap-northeast-1a",
            "Messages": [],
            "RegionName": "ap-northeast-1"
        },
        {
            "State": "available",
            "ZoneName": "ap-northeast-1c",
            "Messages": [],
            "RegionName": "ap-northeast-1"
        }
    ]
}

基本的な内容かもしれませんが、参考になれば幸いです。
以上です。

続きを読む

DynamoDBのAutoscalingがスケジュール対応したので試してみる【AWS CLI】

DynamoDB AS

DynamoDBのキャパシティの値を事前に指定した値でスケーリングさせる機能です。
現在、DynamoDBのテーブルを新しく作成するときにはdefaultで有効化にチェックが入る機能です。

なぜ、スケジュール機能が必要?

DynamoDBのオートスケールを有効化していると、
日中は最低値200で使用して夜間は50にしたい
と言ったことを解決するには、夜間のみオートスケールを解除して・・・といった面倒な事が必要でした。

これを時限起動で出来るようになったのがスケジュール機能!

CLI

awscli
aws application-autoscaling

を使用します。

  • 登録: put-scheduled-action
  • 確認: describe-scheduled-actions
  • 削除: delete-scheduled-action

それぞれ見ていきます。

登録

awscli
aws application-autoscaling put-scheduled-action 
    --service-namespace dynamodb 
    --schedule "cron(01 00 * * ? *)" 
    --scheduled-action-name TestAcction 
    --resource-id table/table_name 
    --scalable-dimension dynamodb:table:ReadCapacityUnits 
    --scalable-target-action MinCapacity=10,MaxCapacity=50   

schedule

cloudwatchで指定しているのと同じ指定方法です。
ルールのスケジュール式

注意する点はUTCで認識されるのでそのへんは気をつけて下さい。

start-time/end-time

その時点から有効・その時点で無効

"2017-11-09T14:10:00+09:00"
みたいに指定

resource-id

  • DynamoDBのテーブル: table/テーブル名
  • DynamoDBのGSI: table/テーブル名/index/インデックス名

scalable-dimension

  • 読み込みキャパシティ: dynamodb:table:ReadCapacityUnits
  • 書き込みキャパシティ: dynamodb:table:WriteCapacityUnits
  • インデックスの読み込みキャパシティ: dynamodb:index:ReadCapacityUnits
  • インデックスの書き込みキャパシティ: dynamodb:index:WriteCapacityUnits

scalable-target-action

最小値と最大値を設定

MinCapacity=INT,MaxCapacity=INT

の形式で指定

確認

awscli
aws application-autoscaling describe-scheduled-actions 
    --service-namespace dynamodb 
    --scheduled-action-names TestAcction

scheduled-action-names

登録の時に指定した scheduled-action-name を指定する

“hogehoge” の形式

削除

awscli
aws application-autoscaling delete-scheduled-action 
    --service-namespace dynamodb 
    --scheduled-action-name TestAcction 
    --resource-id table/table_name 
    --scalable-dimension dynamodb:table:ReadCapacityUnits

参考

put-scheduled-action
ルールのスケジュール式

続きを読む

S3にアップロードできなかった時の対処法

過去のデータをS3に保存しようと考え、いちいちGUIで操作するのはめんどくさかった。

AWS CLI

このページを参考にしていただけば、できるはず
(https://aws.amazon.com/jp/getting-started/tutorials/backup-to-s3-cli/)

私はうまくできなかった。
元から在ったバケットに対して追加を行いたかったが以下のエラーが返されてしまう…

$ aws s3 cp アップロードするファイルorディレクトリ s3://バケット名/バケット内パス;
A client error (AccessDenied) occurred when calling the PutObject operation: Access Denied

今回は、インスタンスのIPが設定されていないため出たエラーであった。
追加したいバケットのアクセス権限→バケットポリシーに自分のインスタンスのIPを記述すれば無事に送ることができた。

続きを読む

AWSでAPI GatewayのステージにLambdaのエイリアスを対応させた際にハマったこと&解決方法

AWSでAPI GatewayのステージにLambdaのエイリアスを対応させた際にハマったこと&解決方法

本題まで長いです。

API GatewayのステージにLambdaのエイリアスを対応させる

API Gatewayのステージとは?

APIをデプロイする際に設定できます。

APIデプロイ時のステージ設定

このステージをいい感じに設定することで、開発用と本番用の運用ができます。

例えば、開発用ではDevelopというステージにデプロイし、本番用ではProductというステージにデプロイすることで、開発者とユーザが使用するAPIを切り替えることができます。

Lambdaのエイリアスとは?

Lambdaでは任意の状態のスナップショットをバージョンとして発行することができます。
エイリアスとは、特定のバージョンに対して付与する名前のことです。(ポインタと表現されています。)

Gitみたいなモノですね。(考え方はGitで良いと思います。)

  • Lambdaのバージョン → Gitのコミットに相当
  • Lambdaのエイリアス → Gitのタグに相当

Lambdaのバージョンとエイリアス

以下のように、Lambdaの設定画面からバージョンとエイリアスを作成することができます。

Lambdaのバージョンとエイリアスの作成方法

対応させるとは?

API GatewayのステージLambdaのエイリアスを対応させることです。

つまり、以下のことが実現できます。

  • 開発用のAPI Gateway(ステージ:Develop)から、開発用のLambda(エイリアス:Develop)を実行できる
  • 本番用のAPI Gateway(ステージ:Product)から、本番用のLambda(エイリアス:Product)を実行できる

対応させる方法

以下を参照してください。

本題:ハマったこと

ようやく本題です。

API Gatewayのステージにaliasという変数を定義し、実行するLambda関数を以下のように設定します。

実行するLambda関数の設定

設定すると、以下のような画面が表示され、「このコマンドを実行してね」と表示されます。

実行すべきコマンドが表示される

このコマンドの${stageVariables.alias}の部分は、Lambdaのエイリアスに合わせて変更するため、TestAPIGateway:DevelopTestAPIGateway:Productにして2回実行します。(今回の例の場合です。Lambdaのエイリアスに合わせてください。)

なお、AWS CLIのインストールと設定は以下を参照してください。

ようやくハマったことです。このコマンドが失敗しました。

エラーメッセージ

An error occurred (ValidationException) when calling the AddPermission operation: 1 validation error detected: Value ''arn:aws:execute-api:ap-northeast-1:xxxxxxxx:yyyyyyyyyyy/TestAPIGateway'' at 'sourceArn' failed to satisfy constraint: Member must satisfy regular expression pattern: arn:(aws|aws-us-gov):([a-zA-Z0-9-])+:([a-z]{2}(-gov)?-[a-z]+-d{1})?:(d{12})?:(.*)

原因

--source-arnのあとに「’」が含まれているとNGでした。

解決方法

コマンドから「’」を取り除いて実行します。

NGのコマンド

aws lambda add-permission --function-name arn:aws:lambda:ap-northeast-1:xxxxxxxx:function:TestAPIGateway:Develop --source-arn 'arn:aws:execute-api:ap-northeast-1:xxxxxxxx:yyyyyyyyyyy/TestAPIGateway' --principal apigateway.amazonaws.com --statement-id zzzzzzzzzzzzzz --action lambda:InvokeFunction

OKのコマンド

aws lambda add-permission --function-name arn:aws:lambda:ap-northeast-1:xxxxxxxx:function:TestAPIGateway:Develop --source-arn arn:aws:execute-api:ap-northeast-1:xxxxxxxx:yyyyyyyyyyy/TestAPIGateway --principal apigateway.amazonaws.com --statement-id zzzzzzzzzzzzzz --action lambda:InvokeFunction

最後に

分かってしまえば単純な原因でしたが、解決するまで苦労しました。
同じ症状に遭遇した方の役に立てば幸いです。

続きを読む