- 投稿日:2020-10-24T22:56:02+09:00
MinIOを使ったAWS S3利用アプリのテストバケット・オブジェクトの準備
目的
AWS S3を利用したアプリのローカルのデバッグのモックやユニットテストなどで、
- バケットはすでにインフラ側の設定として準備されている
- バケット内のオブジェクト/データは別処理が作成している
の様な構成の場合、MinIOのDockerコンテナーを使うのが良さそう。クライアント側からバケットを作り必要なデータをputするというのもあるかと思うが、コンテンテナー立上たら必要がデータが入っていてるのが便利かなぁと。
こちらのQiita記事 docker-composeでMinio起動時にデフォルトのbucketを作成する を参考にバケットの用意はできたが、テスト用のデータも仕込んでみた。
ディレクトリ構成
. ├── docker-compose.yml ├── entrypoint.sh └── test_data ├── README.md # テストデータの説明などを書いておく ├── foobucket # テストデータ入りバケット | ├── myobject1.csv | └── myobject2.json └── barbucket # 空バケットの準備はディレクトリだけ掘っておくDocker Compose
エントリーポイントの差替え
参考にした記事の様に
docker-compose.yml
に展開して書いても良いのでしょうが、長くなるので別ファイルにした。この中で事前データを準備する。内容的にはホスト側の
./test_data
をさらってコンテナ側の/data
にMinIOが認識できる形にコピーしMinIO serverを立ち上げる。#!/bin/sh SRC=/test_data DATA=/data files=$SRC/* for file in ${files}; do if [ -d ${file} ] ; then bucket=$(basename ${file}) mkdir -p ${DATA}/${bucket} mkdir -p ${DATA}/.minio.sys/buckets/${bucket} cp -pr ${SRC}/${bucket}/ ${DATA}/ fi done minio server /dataカスタムポリシーとかは不要だったので準備してませんが、リンク先の記事のように
policy.json
って用意したほうが良いのかなぁ?docker-compose.yml
version: "3" services: minio: image: minio/minio:latest ports: - "9000:9000" volumes: # - ./srv/data:/data - ./test_data:/test_data:ro - ./entrypoint.sh:/entrypoint.sh entrypoint: sh command: /entrypoint.sh environment: MINIO_ACCESS_KEY: AKIAIOSFODNN7EXAMPLE MINIO_SECRET_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEYDockerホスト側にデータを残すならコメントアウトを削除。
起動
$ docker-compose up -d && docker-compose logs -fテスト
# 事前にAWS_PROFILEとか設定済みで $ aws --endpoint-url http://localhost:9000 s3 ls 2020-10-24 20:28:10 barbucket 2020-10-24 20:28:10 foobucket $ aws --endpoint-url http://localhost:9000 s3 ls s3://foobucket 2020-10-24 20:21:30 11 myobject1.csv 2020-10-24 20:22:28 12 myobject2.json $ aws s3 ls s3://barbucket --endpoint-url http://localhost:9000 $実はまだ現物とは組み合わせてないですがデバッグ・テストに使用する予定。
- 投稿日:2020-10-24T16:17:18+09:00
[AWS SAM] Swaggerを使用したAPI定義
- [AWS SAM] 概要、Hello World
- [AWS SAM] Lambda関数からS3アクセス
- [AWS SAM] Swaggerを使用したAPI定義 (※本記事)
Swaggerについて
RESTful APIを構築するためのオープンソースのフレームワーク
記述形式はJSONまたはYAML
バージョン2と3があり記述方法が異なるため注意
Swaggerで定義したAPIをSAMテンプレートから参照して使用する【SAM】API定義とSwaggerファイル連携
必須項目のみでのAPI定義
以下のようにAPI Gatewayを表すTypeと、デプロイするステージ名が必須項目
Resources: RestApi: Type: AWS::Serverless::Api # API Gateway Properties: StageName: Dev # デプロイするステージ名このAPIをLambdaのトリガとする場合、Lambdaの定義は以下のようになる
GetDataFunction: Type: AWS::Serverless::Function Properties: CodeUri: get-data/ Handler: function.lambda_handler Runtime: python3.8 Events: getData: Type: Api Properties: Path: /api/devices/{SerialNumber} Method: get RestApiId: !Ref RestApi # RestApiの定義を参照SAMからSwaggerの参照
以下のようにDefinitionBodyでSwaggerファイルのパスを指定する
RestApi: Type: AWS::Serverless::Api Properties: StageName: Dev DefinitionBody: Fn::Transform: Name: AWS::Include Parameters: Location: swagger.yaml # swaggerファイルのパス指定【Swagger】API定義
パス
/api/devices/{SerialNumber}
のGET、POSTメソッドを以下で定義openapi: 3.0.1 info: description: 'REST API 定義' version: '1.0.0' title: Fn::Sub: ${AWS::StackName}_restApi # API Gatewayに生成されるAPI名 paths: /api/devices/{SerialNumber}: # APIのパス get: # GETメソッド summary: 'デバイス情報取得API' parameters: - name: SerialNumber in: path # パラメータの場所:パスパラメータ description: 'デバイスシリアル番号' required: true # 必須パラメータ schema: # パラメータ構造 type: string responses: 200: description: '成功時のレスポンス' content: application/json: schema: $ref: '#/components/schemas/device' x-amazon-apigateway-integration: uri: # APIからキックするLambda関数のARN Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetDataFunction.Arn}/invocations passthroughBehavior: when_no_templates httpMethod: POST # Lambda関数を呼び出す場合はPOST type: aws_proxy # Lambda関数を呼び出す場合はaws_proxy post: # POSTメソッド summary: 'デバイス情報設定API' parameters: - name: SerialNumber in: path description: 'デバイスシリアル番号' required: true schema: type: string requestBody: # bodyでデータを受け取る content: application/json: schema: $ref: '#/components/schemas/device' responses: 200: description: '成功時のレスポンス' x-amazon-apigateway-integration: uri: Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SetDataFunction.Arn}/invocations passthroughBehavior: when_no_templates httpMethod: POST type: aws_proxy components: schemas: device: # {'SerialNumber': 'abc-001', 'type': 1, 'status': 'working', 'power': 50}を定義 type: object properties: SerialNumber: type: string type: type: integer status: type: string power: type: integer deviceList: # deviceのListを定義 type: object properties: items: type: array items: $ref: '#/components/schemas/device'
x-amazon-apigateway-integration:
はAPI Gateway, Lambda連携で必要な設定、詳細は公式ドキュメント参照【SAM】その他API設定
API Gatewayへのアクセスのコントロール設定
今回はIAMアクセス許可を設定したいため以下のようにAuthを追加
RestApi: Type: AWS::Serverless::Api Properties: StageName: Dev Auth: DefaultAuthorizer: AWS_IAM # IAMアクセス許可 DefinitionBody: Fn::Transform: Name: AWS::Include Parameters: Location: swagger.yamlその他のアクセスコントロールについては公式ドキュメントを参照
CORS対応
RestApi: Type: AWS::Serverless::Api Properties: StageName: Dev Auth: DefaultAuthorizer: AWS_IAM DefinitionBody: Fn::Transform: Name: AWS::Include Parameters: Location: swagger.yaml Cors: # CORS追加 AllowOrigin: "'*'"Lambdaプロキシ統合を使用している場合は、
上記と合わせてLambda側でレスポンスヘッダを設定する必要があるreturn { 'statusCode': 200, 'headers': { 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'OPTIONS,POST,GET' } }Stageにデプロイされる問題
勝手に
Stage
ステージにデプロイされてしまうため以下のようにOpenApiVersionを追加するRestApi: Type: AWS::Serverless::Api Properties: StageName: Dev Auth: DefaultAuthorizer: AWS_IAM DefinitionBody: Fn::Transform: Name: AWS::Include Parameters: Location: swagger.yaml Cors: AllowOrigin: "'*'" OpenApiVersion: 3.0.2 # 追加参考記事
【初心者向け】SwaggerとAWS SAMを使ってWebAPIを簡単に作ってみた
API仕様書書くならswagger v2.0からv3.0に変更する際のポイント
- 投稿日:2020-10-24T13:27:35+09:00
AWSコンソールにログインしてインスタンスをポチポチするのはもう嫌なのでターミナルに極振りしたいと思います
AWSを複数アカウント扱っていると、コンソールに入って〜インスタンスを起動・停止して〜別のアカウントに切り替えるてコンソールに入って〜インスタンス起動・停止して〜また別のアカウントに切り替えてコンソールに入って〜インスタンス起動・停止して〜・・・・・・
うわああああんっ!!んもぅっいい加減にしてっ!!!!
と言うくらいにもううんざりしてきたので、基本的な操作は全部ターミナルから行うことを固く決意しました。
ということで、EC2/RDS
のインスタンス操作を行うためのAWS CLI
を使ったワンライナーをザザザッと並べていきたいと思います。EC2
EC2 の操作から見ていきましょう。
確認
単体確認
まずは、基本の確認から。起動/停止するにも情報が必要になりますからね。
EC2単体確認% aws ec2 describe-instances --profile [profile-name] --instance-ids <instance-id>複数確認
複数インスタンスを確認したい場合は、
--instance-ids オプション
にインスタンスIDを複数並べていくだけですね。EC2複数確認% aws ec2 describe-instances --profile [profile-name] --instance-ids <instance-id> ... <instance-id>全確認
次に、全インスタンスの確認。
といっても、全インスタンスの情報を垂れ流しても把握しづらいので、以下の情報だけを取得するようにしています。
- Nameタグの値
- インスタンスID
- パブリックIP
- プライベートIP
- インスタンスタイプ
- 起動時刻
- インスタンスの状態
AWS CLI の
--query オプション
でフィルタリングしてもいいのですが、イマイチ分かりづらいので私はjq
コマンドでフィルタリングしています。EC2全インスタンス確認% aws ec2 describe-instances --profile [profile-name] --instance-ids <instance-id> | jq -r '.Reservations[].Instances[] | { name: .Tags[] | select(.Key == "Name").Value, instanceId: .InstanceId, publicIP: .PublicIpAddress, privateIP: .PrivateIpAddress, InstanceType: .InstanceType, launchTime: .LaunchTime, status: .State.Name }'describe-instances の詳細は以下を参照。
https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html起動
単体起動
まずは、基本的な単体起動から。
EC2単体起動% aws ec2 start-instances --profile [profile-name] --instance-ids <instance-id>複数起動
複数インスタンスを起動させたい場合は、
--instance-ids オプション
にインスタンスIDを複数並べていくだけですね。EC2複数起動% aws ec2 start-instances --profile [profile-name] --instance-ids <instance-id> ... <instance-id>全起動
最後に、停止している全インスタンスの起動。
EC2全起動% aws ec2 start-instances --profile [profile-name] --instance-ids $(aws ec2 describe-instances | jq -r '[.Reservations[].Instances[] | select(.State.Name == "stopped") | .InstanceId] | join(" ")')start-instances の詳細は以下を参照。
https://docs.aws.amazon.com/cli/latest/reference/ec2/start-instances.html停止
単体停止
まずは、基本的な単体停止から。
EC2単体停止% aws ec2 stop-instances --profile [profile-name] --instance-ids <instance-id>複数停止
複数インスタンスを停止させたい場合は、起動と同じように
--instance-ids オプション
にインスタンスIDを複数並べていくだけですね。EC2複数停止% aws ec2 stop-instances --profile [profile-name] --instance-ids <instance-id> ... <instance-id>全停止
最後に、起動している全インスタンスの停止。
EC2全停止% aws ec2 stop-instances --profile [profile-name] --instance-ids $(aws ec2 describe-instances | jq -r '[.Reservations[].Instances[] | select(.State.Name == "running") | .InstanceId] | join(" ")')stop-instances の詳細は以下を参照。
https://docs.aws.amazon.com/cli/latest/reference/ec2/stop-instances.htmlRDS
RDS の操作も見ていきましょう。
確認
単体確認
まずは、基本的な単体確認から。
RDS単体確認% aws rds describe-db-instances --profile [profile-name] --db-instance-identifier <db-instance-identifier>複数(全インスタンス)確認
単体確認で指定されている
--db-instance-identifier オプション
を外してやれば、複数インスタンスというか全インスタンス確認出来ます。RDS全インスタンス確認% aws rds describe-db-instances --profile [profile-name]といっても、全インスタンスの情報を垂れ流しても把握しづらいので、以下の情報だけを取得するようにしています。
- インスタンス名
- インスタンスタイプ
- DBエンジン
- DBエンジンバージョン
- MultiAZの有無
- ステータス
RDS全インスタンス確認% aws rds describe-db-instances --profile [profile-name] | jq -r '.DBInstances[] | { instanceIdentifier: .DBInstanceIdentifier, instanceType: .DBInstanceClass, engine: .Engine, engineVersion: .EngineVersion, multiAZ: .MultiAZ, status: .DBInstanceStatus }'describe-db-instances の詳細は以下を参照。
https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html起動
単体起動
基本的な起動はこちら。
RDS単体起動% aws rds start-db-instance --profile [profile-name] --db-instance-identifier <db-instance-identifier>全起動
停止している全インスタンスの起動はこちら。
--db-instance-identifier オプション
では複数インスタンスIDを渡すことが出来ないため、私はfor-in
で回してます。RDS全起動% for i in $(aws rds describe-db-instances --profile [profile-name] | jq -r '[.DBInstances[] | select(.DBInstanceStatus == "stopped") | .DBInstanceIdentifier] | join(" ")'); do aws rds start-db-instance --profile [profile-name] --db-instance-identifier $i; donestart-db-instances の詳細は以下を参照。
https://docs.aws.amazon.com/cli/latest/reference/rds/start-db-instance.html停止
単体停止
基本的な停止はこちら。
RDS単体停止% aws rds stop-db-instance --profile [profile-name] --db-instance-identifier <db-instance-identifier>全停止
起動している全インスタンスの停止はこちら。
こちらも起動の時と同じくfor-in
で回してます。RDS全停止% for i in $(aws rds describe-db-instances --profile [profile-name] | jq -r '[.DBInstances[] | select(.DBInstanceStatus == "available") | .DBInstanceIdentifier] | join(" ")'); do aws rds stop-db-instance --profile [profile-name] --db-instance-identifier $i; donestop-db-instances の詳細は以下を参照。
https://docs.aws.amazon.com/cli/latest/reference/rds/stop-db-instance.htmlさいごに
皆様のAWSライフがターミナルでフルになっていただければ幸いでございます。
参考
ec2 — AWS CLI Command Reference
rds — AWS CLI Command Reference
jq Manual (development version)
- 投稿日:2020-10-24T11:51:20+09:00
[AWS認定SAP]アプリケーション移行戦略(6R)
6Rとは
2011年に調査会社であるGartner社が定義したクラウド移行の5つのアプローチに基づいて定義された以下の6つの移行戦略。
- Rehost ("lift and shift"):ホスト変更
- Replatform ("lift, tinker and shift"):プラットフォーム変更
- Repurchase ("drop and shop"):再購入
- Refactor / Re-architect:再設計
- Retire:リタイア
- Retain:保持
1. Rehost ("lift and shift")
現在の環境をそのままクラウド移行し、随時最適化する。
2. Replatform ("lift, tinker and shift")
コアの部分を変えず部分的に最適化した上で移行する。
3. Repurchase ("drop and shop")
現在のシステムやアプリケーションの使用を廃止し、新しいシステムやアプリケーションに移行す。
4. Refactor / Re-architect
現在のシステムやアプリケーションを見直し再設計した上で移行する。
5. Retire
不要なシステム・アプリケーションの使用を停止する。
6. Retain
移行しない。
参考
・https://aws.amazon.com/jp/cloud-migration/
それぞれのメリット・デメリットの説明有り
↓
・https://blog.mmmcorp.co.jp/blog/2020/07/07/Six_Strategies_Migrating_to_AWS_ProsandCons/
- 投稿日:2020-10-24T11:41:19+09:00
【Windows】通常の通信はVPNを経由したくないけどAWS向けはVPNを経由したい
はじめに
リモートワークでVPNを使っているんですけれども、Windowsで普通にVPNを設定するとすべての通信がVPNを経由してしまいます。
そこで、VPN先のネットワークへの通信だけVPNを経由し、普通にググったりツイッターで脱線情報収集したりするのは直接インターネットに出ていきたい。
しかしながら、特定のIPだけはVPNを経由したい。
そんな環境があって、特定の数個のIPアドレスだけ手動で登録して使ってました。しかし、AWSのEC2スポットインスタンスをポコポコ立ち上げてアクセスする必要が出てきました。セキュリティ上、拠点以外からのアクセスは遮断しています。
スポットインスタンスを立ち上げるたびにいちいちパブリックIPを調べて手動でルーティング設定するのは面倒です。
そこで、AWS向けは全部VPN経由にする方法を考えました。
たまたまAWSが使われているサービスへの通信(例の52.68.96.58とか)もVPN経由になってしまいますが、まあ、許容範囲内でしょう。前提条件
・AWS Tools for Windows PowerShell がインストールされている
参考 AWS Tools for PowerShell ことはじめ
(今回の使い方では、Credential情報の設定は不要です。)・通常の通信はVPNを経由しない指定は設定済み
参考 【Windows】指定した宛先の通信のみVPN経由にするAWSのIP範囲取得
AWSのIP範囲って変わっていくんじゃないかと思ったのですが、プログラマブルに取得する方法が用意されていました。
公式ドキュメントの AWS IP アドレスの範囲 をご覧ください。だけだと不親切なので、とりあえず取得するコマンドを
awsipv4.ps1Get-AWSPublicIpAddressRange -Region ap-northeast-1 -ServiceKey EC2 | Where-Object {$_.IpAddressFormat -eq "Ipv4"} | Select-Object IpPrefixこれを応用して、ルーティング設定コマンドに流し込みます。
出来上がり
VPN接続をトリガにスクリプトを走らせられないかと調べたのですが、見つからなかったので、スクリプトを走らせると設定したうえでVPN接続をする方法にしました。
connectVpn.ps1$vpnName = "MyVPN" $vpnUser = "username" $vpnPass = "password" # 現状のルーティング設定を全部削除 (Get-VpnConnection $vpnName).Routes | ForEach-Object { Remove-VpnConnectionRoute $vpnName -DestinationPrefix $_.DestinationPrefix } # AWSのIP範囲を取得(東京リージョンのEC2だけ) Get-AWSPublicIpAddressRange -Region ap-northeast-1 -ServiceKey EC2 | #IPv4に絞る Where-Object {$_.IpAddressFormat -eq "Ipv4"} | #おのおのルーティング設定 ForEach-Object { Add-VpnConnectionRoute $vpnName -DestinationPrefix $_.IpPrefix } #AWS以外でルーティングが必要ならここに記述 #Add-VpnConnectionRoute $vpnName -DestinationPrefix xxx.xxx.xxx.xxx #VPN接続 C:\windows\system32\rasdial.exe $vpnName $vpnUser $vpnPass実際に使うときは
$vpnName
$vpnUser
$vpnPass
をご自身の環境に合わせて変更してください。
(WindowsのUIから接続するときはVPN名だけで接続できるので、スクリプトからもVPN名だけでいけないか調べたのですが、どうも出来ないようで、ユーザー名・パスワードもスクリプト内に記述しております)また、自分の利用範囲ということでAWSの東京リージョン・EC2・IPv4に絞ってますが、ここもご自身が利用するAWSのサービスに合わせて書き換えましょう。
PowerShellのお作法として、BOM付UTF-8で保存しましょう。(←それがベストプラクティスなのかはよくわかってない)
ルーティングテーブルが大量にあると速度低下の懸念がありますが、上記設定(40件ぐらい)では目立った速度低下は無いようです。(NURO光で変わらず800Mbpsぐらいでてます。)
- 投稿日:2020-10-24T02:41:57+09:00
Railsのbundle installで見かけないエラーが…それに対する解決法
はじめに
最近、講義やゼミでの研究も相まってAWS Cloud9でrailsを使う機会が増えている。
そんな中で初めて見たエラーだった。ネットで検索してもいまいち解決法が分かりにくかったので、ここにメモがてら残そうと思う本題
では、どんなエラーが出たのか。以下の様なエラーだ。
$ budle install There was an error while trying to write to `/tmp/bundler-compact-index-xxxxxxxxx(date)-xxxxxx-xxxxxxx/versions`. There was insufficient space remaining on the device.ほほう…何だろう。最後の一文を見るとデバイスの容量が足りないという事みたいです。
という事は・・・デバイスのボリューム自体を増やす。もしくは使いそうにないファイルの中身を消去して、空きを作るなどが考えられます。では、前者を解決策1、後者を解決策2としたいと思います。解決策1
これは、AWS Cloud9のボリュームを増やすという事です。記事がすでに上がっているので割愛したいと思います。
解決策2
では、何処のファイルの中身を消去しようとなりますが、私は/var/logを使う事が今回は無さそうなのでそちらを消去することにしました。その際に使用したコマンドが以下です。
$ sudo find /var/log/ -type f -name \* -exec cp -f /dev/null {} \;最後に
という訳で、2つの解決策を提示しました。これで、容量が足りるようになると思うので、再度bundle installして貰えれば大丈夫です。
恐らくもっと良いやり方もあると思います。最後までお読みいただきありがとうございました。
- 投稿日:2020-10-24T00:08:00+09:00
AWSとネットワーク(基礎)
はじめに
AWSはAmazon Web Servisesの略で、Amazonが提供しているクラウドサーバーのサービスです。
AWSへの理解度を高めるために、学んだことをアウトプットします。
今回はネットワークとの関係を記載します。AWSを使う目的
AWSを使う目的は、簡単に言うとネットワークやサーバーを構築する手間を省くためです。
ネットワークやサーバーを構築するには、インターネット回線や複数のサーバー、接続するためのハブやルーターなどのネットワーク機器の用意が必要です。
AWSを使うことで仮想的なネットワークやサーバーを構築することが可能です。リージョンとアベイラビリティーゾーン
リージョン
AWSでは世界に数十箇所のデータセンター群があり、それぞれの地域に存在するデータセンター群のことをリージョンと言います。アベイラビリティゾーン
アベイラビリティゾーンとはリージョンをさらに分割したものです。
アベイラビリティゾーンはそれぞれ独立した設備を用いているため、一つのアベイラビリティゾーンが災害などの被害を受けて使用できなくなっていても、別のアベイラビリティゾーンには影響を受けないようになっています。Amazon VPC
AWSにて自由なネットワークを作れる領域です。
Amazon VPCを作成する時は、使用するIPアドレス範囲を指定します。
サブネット
Amazon VPCを作成した後、いくつかのネットワークに分割して使用します。
この分割したネットワークのことをサブネットと呼びます。Amazon EC2 (Amazon Elastic Compute Cloud)
サブネットの中に配置できるサーバー。
各サーバーの個体はインスタンスと呼ばれます。
インスタンスを作る時はCPUのスペックやディスクの容量を決めることができます。
尚、1年間無償利用できるタイプは「t2.micro」参考
「Amazon Web Services 基礎からのネットワーク&サーバー構築」
著者:大澤文孝、玉川憲、片山暁雄、今井雄太最後に
本投稿が初学者の復習の一助となればと幸いです。