20220131のAWSに関する記事は22件です。

AWS日記35 (Amplify)

はじめに 今回は AWS Amplify を試します。 チュートリアルのJavaScriptの手順を参考に、サンプルWebアプリケーションをホスティングします。 初回設定 チュートリアルの Prerequisites 環境設定 適切なバージョンの Node.js , npm , git をインストールします。 本記事における Node.jsのバージョンは 16.13.2 です。 Amplify CLI インストール npm または curl コマンドで Amplify CLI をインストールします。 チュートリアルの Option 2: Follow the instructions Amplify用のユーザーを追加 AdministratorAccess を許可したユーザーを新規に追加します。 プロジェクト作成 チュートリアルの Set up fullstack project ファイル作成 mkdir -p amplify-js-app/src && cd amplify-js-app touch package.json index.html webpack.config.js src/app.js パッケージのインストール npm install ローカル環境で起動 起動後にlocalhost:8080で動作を確認します。 npm start バックエンド初期化 amplify init API作成 チュートリアルの Connect API and database to the app API作成 amplify add api APIデプロイ amplify push 状態確認 amplify status src/app.js の最終形 import Amplify, { API, graphqlOperation } from "aws-amplify"; import awsconfig from "./aws-exports"; import { createTodo } from "./graphql/mutations"; import { listTodos } from "./graphql/queries"; import { onCreateTodo } from "./graphql/subscriptions"; Amplify.configure(awsconfig); async function createNewTodo() { const todo = { name: "Use AppSync", description: `Realtime and Offline (${new Date().toLocaleString()})`, }; return await API.graphql(graphqlOperation(createTodo, { input: todo })); } async function getData() { API.graphql(graphqlOperation(listTodos)).then((evt) => { evt.data.listTodos.items.map((todo, i) => { QueryResult.innerHTML += `<p>${todo.name} - ${todo.description}</p>`; }); }); } const MutationButton = document.getElementById("MutationEventButton"); const MutationResult = document.getElementById("MutationResult"); const QueryResult = document.getElementById("QueryResult"); const SubscriptionResult = document.getElementById("SubscriptionResult"); MutationButton.addEventListener("click", (evt) => { createNewTodo().then((evt) => { MutationResult.innerHTML += `<p>${evt.data.createTodo.name} - ${evt.data.createTodo.description}</p>`; }); }); API.graphql(graphqlOperation(onCreateTodo)).subscribe({ next: (evt) => { const todo = evt.value.data.onCreateTodo; SubscriptionResult.innerHTML += `<p>${todo.name} - ${todo.description}</p>`; }, }); getData(); Webアプリケーションのホスティング・公開 チュートリアルの Deploy and host app ホスティング amplify add hosting 公開 amplify publish 動作確認 終わりに AWS Amplify を試しました。 コマンドだけでも簡単にアプリケーションを開発できます。 Amplify Studioを利用することでブラウザ上で開発することができる為、今後試そうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS ELB (Elastic Load Balancing)についてまじで簡単にまとめてみた

はじめに SAA対策の中で特に私がいつもつまずいてしまうところをまとめておく。 多分以下のような観点が特に自分は弱いと分析している。 - レジリエントアーキテクチャの 設計 - セキュアなアプリケーションと アーキテクチャの設計 ちょっとあまり理解できてなさそうなサービスをまとめておく。 まずはELBについて。 Elastic Load Balancingについて ELBと略される。 ELBは、受信した通信を指定した複数の宛先に自動的に負荷分散をしてくれるもの。 このELBを使用することによって、耐障害性を高めることができ、万が一システムに障害が発生したときにサービスへの影響を最小限に抑えることができる。 ELBの特徴 - ロードバランサーにはDNS名のアクアセスポイントが付与される。 - ヘルスチェック機能がある。 - SSL/TLS通信の終端になる。 ELBの種類 ELBには3つ種類がある。 ①ALB Application Load Balancer ②NLB Network Load Balancer ③CLB Classic Load Balancer ③のCLBは古いタイプのロードバランサーらしく、現在は非推奨となっている。 基本的にはALBかNLBを選択することになる。 ALB このALBはL7レイヤー(HTTP/HTTPS)の負荷分散に使用される。 SAAの試験では、よくこの「L7レイヤーで使用する・・・」みたいな問題が出題されている気がするので覚えておきたい。 主にこのALBはユーザーからのアクセスを受け付けて、配下のサービス(例えばEC2やLambda)に負荷分散するために使用される。 NLB NLBはL4レイヤー(TCP/UDP/TLS)の負荷分散に使用される。 基本的にはAWS内部で負荷分散が必要な際に使用され、ALBと組み合わせて使用されることもある。 NLBの特徴としてはこのようなものがある。 - 高可用性 - 高スループット - 低レイテンシー 要するに、停止しづらく、処理可能なデータ量が多く、データの転送をするときに遅延が少ないということ。 NLBの特徴としては急激なアクセス増加でも自動的にスケーリングしてくれるためエラーは発生しない。 対して、ALBを使用していた場合は503エラーが出てサービス利用不可となる可能性もある。らしい。 ELBの特徴のヘルスチェックについて - ロードバランサーにはDNS名のアクアセスポイントが付与される。 - ヘルスチェック機能がある。 - SSL/TLS通信の終端になる。 この3つの特徴の中の、ヘルスチェックについてまとめておく。 そもそもヘルスチェックとは、ELBで複数のEC2に負荷分散をするときにEC2が停止していたらどうだろう。 ELBのヘルスチェックは、このターゲットグループに所属しているEC2が正常に動いているかどうかを確認してくれる機能。 ヘルスチェックの流れ ヘルスチェックは次のような流れで動いているらしい。(NLBの場合) ①NLBはターゲットグループに所属しているターゲット(EC2)にヘルスチェックのためのpingを実行する。 ②ヘルスチェック3回連続失敗をすると、NLBはターゲットのステータスを「Unhealthy」に変更をする。そのあと、Unhealtyのターゲットにはアクセスを振り分けることはしない。(ちなみにヘルスチェックの回数は変更可能) ③サービス停止中のターゲットに対しても定期的にヘルスチェックしていく。 ④サービス停止中のターゲットに対してpingが3回連続成功すると、NLBはターゲットのステータスを「Healthy」に戻し、アクセスの割り振りを再開する。 このような流れでヘルスチェックは行われている。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LINEでつくる 音声翻訳機(ほんやくコンニャク)

はじめに AWS AIのサービスに、下記のようなものがある。 音声をテキストに変換するtranscribe テキストを他言語翻訳するtranslate テキストを音声に変換するpolly これらを組み合わせれば、ほんやくコンニャクができるのではないか? ちなみに私はおみそ味を食べてみたい。 ということでほんやくコンニャクのLINEBOTを作ってみた。 基本的にはAWSサービスをぽちぽちと繋げていくだけで、LINE設定含め半日あればできる。 世の中のN番煎じではあるが、いろいろとハマッた部分もあったので記録。 構成と流れ 1.LINEから音声データを取得し,S3へ保存(.mp4) 2.S3から1.の音声データを取得してtranscribeで書き起こし,S3へ保存(.json) 3.S3から2.の書き起こしデータを取得してtranslateでテキスト翻訳 4.上記の3.の翻訳データをPollyで音声合成し,S3へ保存(.mp3) 5.S3内の4.のmp3データについて,認証付きURLを発行 6.ffmpegを用いてmp3をm4aフォーマットに変換し,S3へ保存(.m4a) 7.S3内の6.のm4aに5.を適用し,LINEで送信 ざっとコード解説 各手順を関数化したコードを晒していきます。 全体のコードはgithubにて。 1.LINEから音声データを取得し,S3へ保存(.mp4) s3 = boto3.resource('s3') def get_content_from_line(event,bucket_name,bucket_key): if event['message']['type']=='audio': MessageId = event['message']['id'] # メッセージID AudioFile = requests.get('https://api-data.line.me/v2/bot/message/'+ MessageId +'/content',headers=HEADER) #Audiocontent取得 Audio_bin = BytesIO(AudioFile.content) Audio = Audio_bin.getvalue() # 音声取得 obj = s3.Object(bucket_name,bucket_key) obj.put( Body=content ) return 0 else: return -1 LINEから送られてきたメッセージがオーディオの場合は,音声の値を取得。 BytesIOを経由して音声ファイルをS3に保存している。 このとき,引数のbucket_keyには.mp4拡張子を付与する。 2.S3から音声データ取得→書き起こし結果をS3へ保存(.json) transcribe = boto3.client('transcribe') def speech_to_text(job_name, bucket_name, bucket_key_src, bucket_key_dst): job_uri = "s3://%s/%s"%(bucket_name,bucket_key_src) transcribe.start_transcription_job( TranscriptionJobName=job_name, Media={'MediaFileUri': job_uri}, MediaFormat='mp4', LanguageCode='ja-JP', OutputBucketName=bucket_name, OutputKey=bucket_key_dst, ) while True: status = transcribe.get_transcription_job(TranscriptionJobName=job_name) if status['TranscriptionJob']['TranscriptionJobStatus'] in ['COMPLETED', 'FAILED']: break print("Not ready yet...") time.sleep(5) return 0 transcribeは,s3のuriを指定することができる。また,保存先のS3キーも引数で指定。 そしてwhile TrueでステータスがCOMPLETED/FAILEDになるまで抜けられない。 後述するが,このパートはとても時間がかかる。(もともと、議事録等の長文でこそ力を発揮するサービスのため) 3.S3から2の書き起こしデータを取得→translateでテキスト翻訳 #3-1. def get_content_from_s3(bucket_name,bucket_key): obj = s3.Object(bucket_name,bucket_key) body = obj.get()['Body'].read() json_data = json.loads(body.decode('utf-8')) print(json.dumps(json_data)) transcript=json_data['results']['transcripts'][0]['transcript'] return transcript #3-2. translate = boto3.client('translate') def translate_transcript(transcript): res_trans = translate.translate_text( Text=transcript, SourceLanguageCode='ja', TargetLanguageCode='en', ) res_text=res_trans['TranslatedText'] print('original:%s'%transcript) print('translated:%s'%res_text) return res_text 2で保存したtranscriptのファイル(json)を,3-1でstringとして取得している。 そしてそれを3-2のAWS translateに食わせてテキスト翻訳をしている。 SourceLanguageCodeにja(日本語),TargetLanguageCodeをen(英語)に指定。 TargetLanguageCodeの設定により,任意の言語での翻訳機を実現できる。 4.翻訳データをPollyで音声合成し,S3へ保存(.mp3) def synthesize_speech(text,bucket_name,output_key): bucket=s3.Bucket(bucket_name) response = polly.synthesize_speech( Text=text, Engine="neural", VoiceId="Joanna", OutputFormat="mp3", ) with closing(response["AudioStream"]) as stream: bucket.put_object(Key=output_key, Body=stream.read()) return 0 pollyを用いた音声合成。Engine=neuralにするとより自然な音声になる。VoiceIdはお好みで。OutputFormatは,mp3を指定(のちにffmpegでm4aに変換)。 5.データの認証付きURLを発行 def get_signed_url(bucket_name, bucket_key): s3_source_signed_url = s3_client.generate_presigned_url( ClientMethod='get_object', Params={'Bucket': bucket_name, 'Key': bucket_key}, ExpiresIn=10, ) return s3_source_signed_url ffmpegへmp3データを渡すため,Pollyで生成したmp3データの認証付きURLを発行する。 この操作は,ffmpeg目的以外に,LINEへメディアを送信する際にも必要になる。 これにより,S3のデータを第三者が一時的に操作できる。「一時的」な時間は引数のExpiresIn(秒)で指定。 6.ffmpegを用いてmp3をm4aフォーマットに変換し,S3へ保存(.m4a) def convert_mp3_to_aac(url, bucket_name, bucket_key_dst): ffmpeg_cmd = "/opt/bin/ffmpeg -i \"" + url + "\" -f adts -ab 32k -" command1 = shlex.split(ffmpeg_cmd) p1 = subprocess.run(command1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) resp = s3_client.put_object(Body=p1.stdout, Bucket=bucket_name, Key=bucket_key_dst) return 0 ここでffmpegを用いた処理を行っている。ffmpegコマンドの詳細は割愛するが,「mp3をm4aに変換」を行っている。末尾に「-」を付与することで標準出力として変換データを得られる。これにより,s3に保存する際もp1.stdoutとすることでm4aフォーマットでのデータを保存可能。 7.LINEで音声ファイルを送信 REQUEST_MESSAGE = [ { 'type': 'audio', 'originalContentUrl': url, 'duration': 5000 #ms }, ] payload = {'to': userId, 'messages': REQUEST_MESSAGE} response = requests.post( 'https://api.line.me/v2/bot/message/push', #not the 'reply' message headers=HEADER, data=json.dumps(payload) ) print('request sent!') ここでREQUEST_MESSAGEに音声を指定。ContentUrlには,先ほど5で述べた認証URLを発行し指定する。 ここでのポイントは,replyでなくpushメッセージとしてリクエストを送信すること。 replyTokenには30秒の期限があり,処理が30秒を超えるとtokenが無効となり送り返すことができない。 そこで,replyではなくUserIDを指定してpushメッセージとして送信する。 ハマりポイント 特にハマッた二つのポイントについて詳細説明。 6. LINEへの音声ファイル送信エラーの対策 LINEに音声メッセージを送る際,その対応フォーマットはm4aのみ。 一方で,Pollyで合成された音声の出力フォーマットはmp3/ogg/pcm。 つまり,Pollyの音声をそのままLINEに送ることはできない。 そこで,ffmpegを用いてmp3をm4aに変換してあげる。 幸い公開LamdaLayerが存在するので,これを使わせていただく。 7. LINEのreplyTokenタイムアウトの対策 今回の構成ではreplyTokenのタイムアウトを超えるため,対処が必要。 というのも、AWS transcribeは非常に時間がかかる。5秒の音声でも書き起こしに20秒近くかかる(※)。 今回は短文想定なので,その他処理を合わせるとLINEのreplyTokenのタイムアウト時間(30秒)を超えてしまう。 これに対処するために,LINEにメッセージを送り返すとき,replyTokenによるreplyリクエストではなく,ユーザー指定によるpushリクエストを発行してあげる。 詳しくはLINE Developersの公式ドキュメントを参照されたい。 いや,そもそも応答に30秒以上かかるbotなんてありえない→ごもっともです。今回はAWSで全部試した結果こうなりました。 (※)補足:AWS transcribeは,本来は議事録などの長文書き起こし向け。なので例えば60分の音声が15分で書き起こし完了する,という点ではウマミがある。 まとめ 今回はやっつけで全部AWSで実現させました。そのためbotと呼ぶにはおこがましいほどの高遅延翻訳機になりました。 とりあえず書いてみたレベルですが,一個人が半日でこういうシステムを作る時代になりました。 今後は各種モジュールの高速化を図って,使い物になるLINEbotにできれば良いですね(他人目線)。 議事録などの長文であれば,WEBアプリ化しても良いかもしれません。需要は低そう。 詳細コードはgithubにて。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Wavelength上にNTPサーバー(chrony)を立てる

AWS Wavelength zone内のサブネット上に、chronyを使ったNTPサーバーを立ててみました。 問題点 AWS Wavelength zone内に普通にインスタンスを立てるだけでは、chronyをインストールしても、WavelengthはUDPを通さないので、外部のNTPサーバーに接続して時間情報を取得することができません。 (補足)正確に言いますと、Wavelength上のEC2とKDDIのモバイルネットワーク上にあるデバイスはUDPで通信できるのですが、外部のNTPサーバーがauで通信しているわけない(当然固定回線でしょう!)ので、結局、「通信できない」となります。 下記は、AWS Wavelengthのマニュアルからの抜粋です。 解決策 仕方がないので、下記の2つの方法を試してみることとしました。 1. 同じVPC内の東京リージョン側に同様のNTPサーバーを立てて、それを参照する 2. Amazon Time Sync Serviceを利用する それでは、下記の構成図のような形で設定していきます。 東京リージョン(Public Subnet)のinstanceへchronyをインストール Ctrl+Alt+Tでターミナルを開いて、コマンドでchronyをインストールします。 sudo apt install chrony 次に、/etc/chrony/chrony.confをエディターで開いて、chronyのコンフィグファイルを編集します。 sudo nano /etc/chrony/chrony.conf そうすると下記のような画面が開きますので、デフォルトで入っているサーバーを消して、下記の画面のような感じで、サーバーを追加しましょう。 ちなみに、169.254.169.123は、Amazon Time Sync Serviceのアドレス、ntp.nict.jpは情報通信研究機構が運営する時刻サーバーのドメインとなります。(それ以外は適当に選びました。) また、最後の行にWavelength上のサーバー(10.50.50.234)で稼働しているchronyから参照できるように、下記のような設定を1行追加します。 allow 10.50.50.234 もし、複数のサーバーからのアクセスを許可したい場合は、複数の行にして、それぞれ記入するか、または、CIDRフォーマット(例えば、10.50.50.0/24)で記述します。 allow 10.50.50.0/24 ここで一度、chronyサービスをリスタートしましょう。 sudo systemctl restart chrony.service chronyを有効にするためのサーバーの設定変更 さらに、上記のallow 10.50.50.234の設定はあくまでもchronyの話なので、サーバーのセキュリティグループも同時に設定変更する必要があります。 Wavelength側のchrony(10.50.50.234) => 東京リージョン側のchrony(10.50.10.252)という形のアクセスになりますので、東京リージョン側のEC2インスタンスにおけるセキュリティグループのインバウンドルールの設定において、すべてのトラフィック(all traffic, all protocol)について10.50.50.234を許可しましょう。 EC2 > セキュリティグループの設定 > 該当するセキュリティグループにおいて、インバウンドルールを編集します。 ルールを1行追加して、typeでall trafficを選択、Sourceは10.50.50.234を入力 Wavelength Subnet上のinstanceへchronyをインストール Wavelength上のインスタンスに接続するためには、通常は、踏み台サーバー(Jump Box)を立てて、それを経由してアクセスします。Jump Boxを使った接続方法については、Public Subnet上にあるJump BoxからPrivate Subnet上にあるサーバーにアクセスする方法と全く同じですので、その部分については省略させていただきます。 ちなみに、auの携帯を持っている方であれば、Jump Boxなしで、au携帯のテザリングで直接接続することもできます。(この場合、インターネットゲートウェイは通らず、Wavelength側のキャリアゲートウェイを通ってサーバーにアクセスします。) サーバーに接続できたら、先ほどと同様に、chronyをインストールしましょう。 sudo apt install chrony 次に、/etc/chrony/chrony.confをエディターで開いて、chronyのコンフィグファイルを編集します。 sudo nano /etc/chrony/chrony.conf そうすると、また下記のような画面が開きますので、デフォルトで入っているサーバーを消して、こちらも下記の画面のような感じで、サーバーを追加しましょう。 169.254.169.123はAmazon Time Sync ServiceのIPアドレス、10.50.10.252は、東京リージョン側のchronyが稼働しているサーバーのアドレスとなります。 この10.50.10.252を入れることで、chronyが自動的に東京リージョン側のchrony(NTPサーバー)へアクセスするようになります! 設定が終わりましたので、一度、chronyサービスをリスタートしましょう。 sudo systemctl restart chrony.service chronyが稼働しているかどうか、サービスのステータスを見てみましょう。 sudo systemctl status chrony 東京リージョン側のchrony(NTP Server)の稼働状況を確認 chronyc sourcesコマンドによって、情報ソース毎の状況を確認できます。-vをつけると、説明が付きます。 上から6番目の星印が付いているサーバーが現在同期しているサーバーであり、調整されたオフセットが百万分の98秒であると表示しています。 Stratumは、時間ソースサーバーを階層化していて、Startum 0が原子時計に直結している時間サーバー、Stratum 1はStratum 0の時間サーバーに同期していて、Stratum 0の次に正確な時間を供給するサーバーとなります。 chronyc sources -v chronyc sourcestatsは、chronyc sourcesによって表示されない詳細な統計情報を表示するコマンドです。 chronyc sourcestats -v また、chronyc trackingコマンドによって、現時点でのトラッキング情報(選択している時間サーバーをベースとした時間情報の追跡状況)を表示します。 chronyc tracking さらに、chronyc clientsコマンドによって、このサーバー(東京リージョン側のchrony)へアクセスしているクライアントの情報が得られます。 ip-10-50-50-234.ap-north...は、Wavelength側のサーバー(10.50.50.234)のDNSネームになりますので、このサーバー(10.50.10.252)へアクセスしていることがわかります! chronyc clients Wavelength側のchronyの稼働状況を確認 利用するコマンドは同じですが、下記のようなステータスが確認できます。 時間ソースがAmazon Time Sync Serviceと東京リージョンに建てたNTPサーバー(chrony)の2つとなります。 いずれの調整後のオフセット値も1ミリ秒以下の数値(百万分の884など)となっており、悪くないのでは?!と思っていますが、いかがでしょうか。。 chronyc sources -v chronyc sourcestats -v トラッキング情報を見ると、System timeのところで、NTPタイムと比較して百万分の154秒(1万分の1.54秒)早いとのこと。 chronyc tracking Amazon Time Sync Serviceについて こうしてみると、Linux系、FreeBSD系、MacOSであれば、すべてchronyをインストールできるので、AWSの内部では、片っ端からchronyを入れて、単に、configファイルに、下記のサーバーの記述を入れてしまえば、まあまあの精度が得られるということでしょうか。 ※ ただし、この記事では、Amazon Time Sync Serviceに固定されてしまっては面白くないので、下記のサーバーの記述からpreferは外しています。 server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4 参考情報
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ローカル環境 KMS で暗号鍵を固定化する (LocalStack)

AWS Key Management Service (KMS)は暗号鍵の生成・管理と、アプリケーションデータの暗号化・復号を提供してくれるサービスです。KMS を利用することで、暗号鍵ファイルを直接扱うリスクを回避することでできます。 以前の記事で紹介した LocalStack Docker コンテナで KMS モックサーバを実行し KMS を利用するアプリケーションを開発した際、他の開発メンバーの環境で暗号化したテストデータを復号できるよう、鍵ファイルを固定する必要があり、事前に作成した暗号鍵ファイルをインポートした KMS キーを生成するよう自動化しました。 その手順を共有します。 Docker compose file 設定 docker-compose.yml version: '3.8' services: localstack: container_name: localaws-container-localstack image: localstack/localstack:0.13.3 platform: linux/amd64 environment: SERVICES: kms EDGE_PORT: 4566 INIT_SCRIPTS_PATH: /docker-entrypoint-initaws.d DEFAULT_REGION: 'ap-northeast-1' KMS_PROVIDER: 'local-kms' ports: - '4566:4566' volumes: - ./init:/docker-entrypoint-initaws.d:ro - ./data:/data:rw 環境変数 SERVICES に kms を追加 環境変数 KMS_PROVIDER に local-kms 設定 初期化スクリプトを配置する init ディレクトリを /docker-entrypoint-initaws.d にマウント インポートする鍵ファイルを配置する data ディレクトリを /data にマウント ※Apple Silicon (M1)で実行する場合、通常 ARM 向けイメージが使用されますが、ARM 向けイメージでは本手順が実行できない不具合があるため platform: linux/amd64 で AMD64 用イメージを実行しています インポートする鍵ファイルを作成 以下のコマンドで生成した PlaintextKeyMaterial.b64 を data ディレクトリに配置 openssl rand -base64 -out PlaintextKeyMaterial.b64 32 docker-compose.ymlや初期化スクリプトとともに、このファイルをGitリポジトリにコミットし、開発メンバー間で共有 初期化スクリプト 以下のようなスクリプトを init ディレクトリに配置 init/kms.sh #!/bin/bash # JSONファイルを扱うために jq をインストール apt update -y && apt install jq -y cd /data # 暗号鍵をバイナリファイルに変換 openssl enc -d -base64 -A -in PlaintextKeyMaterial.b64 -out PlaintextKeyMaterial.bin # KMSキーを生成しKeyId取得 awslocal kms create-key --origin EXTERNAL > create-key-output.json KeyId=`jq -r '.KeyMetadata.KeyId' create-key-output.json` # PublicKeyとImportTokenを取得 awslocal kms get-parameters-for-import \ --key-id ${KeyId} \ --wrapping-algorithm RSAES_OAEP_SHA_1 \ --wrapping-key-spec RSA_2048 \ > get-parameters-for-import-output.json jq -r '.PublicKey' get-parameters-for-import-output.json > PublicKey.b64 openssl enc -d -base64 -A -in PublicKey.b64 -out PublicKey.bin jq -r '.ImportToken' get-parameters-for-import-output.json > ImportToken.b64 openssl enc -d -base64 -A -in ImportToken.b64 -out ImportToken.bin # 暗号鍵をインポート用に暗号化 openssl rsautl -encrypt \ -in PlaintextKeyMaterial.bin \ -oaep \ -inkey PublicKey.bin \ -keyform DER \ -pubin \ -out EncryptedKeyMaterial.bin # 暗号化した鍵マテリアルをインポート awslocal kms import-key-material \ --key-id ${KeyId} \ --encrypted-key-material fileb://EncryptedKeyMaterial.bin \ --import-token fileb://ImportToken.bin \ --expiration-model KEY_MATERIAL_DOES_NOT_EXPIRE # KMSキーのエイリアス awslocal kms create-alias --target-key-id ${KeyId} --alias-name 'alias/local-kms-key' # KMSキーの情報を確認 awslocal kms describe-key --key-id 'alias/local-kms-key' docker compose up でコンテナを起動すると シェルスクリプトが自動的に実行され、KMS キーを生成し鍵ファイルをインポートします KMS キー ID は毎回変わりますが、アプリケーションからはエイリアス 'alias/local-kms-key' を指定して利用できます 暗号化 aws kms encrypt --key-id 'alias/local-kms-key' --plaintext 'プレインテキスト' --endpoint http://localhost:4566 --region ap-northeast-1 復号 aws kms decrypt --key-id 'alias/local-kms-key' --ciphertext-blob '暗号化文字列(base64)' --endpoint http://localhost:4566 --region ap-northeast-1 参考資料
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS アクセスキーについてとTerraformでのアクセスキーに関して

アクセスキーとは AWSのアクセスキーとは認証情報のことで、IAMユーザまたはAWSアカウントの長期的認証情報を指す。AWSのアクセスキー認証により、外部からAWSのサービスへプログラムアクセスが可能。 AWSのアクセスキーは、アクセスキーIDとシークレットアクセスキーから構成されている。また、ユーザ名とパスワードによる認証と同様の処理をプログラムアクセス時にアクセスキーIDとシークレットアクセスキーを用いて行う。 この為、ユーザ名とパスワード更新の影響を受けずにプログラムアクセスが可能。 プログラムアクセスがユーザ名とパスワードなしに実行できるために、重大なセキュリティリスクが生じる為、アクセスキー管理の徹底が必須!!! AWSのアクセスキー管理が不十分な場合のセキュリティリスク ・アクセスキーの漏洩  アクセスキーはアクセスキーIDとシークレットアクセスキーから構成される文字列のため、外部サイトに流出したり公開リポジトリ―に誤ってプッシュ登録したりすることで生じます。 ・AWSサービス内の情報漏洩  アクセスキーを利用して、サービス内に蓄積された業務データが持ち出しされるリスクがあります。 ・サービスの不正利用  1度外部にアクセスキー情報が漏洩してしまうと、AWSサービスを不正利用されたり、それによって高額なAWSサービス利用費の請求が発生したりすることが懸念されます。 ・セキュリティ攻撃に悪用 AWSのサービスを経由した成りすましや、仲介者攻撃として第3者へのセキュリティ攻撃に悪用されるリスクがあります。 セキュリティ対策 ・極力使用しない  AWSのアクセスキーは、外部からのプログラムアクセスを用います。外部からのプログラムアクセスをしない場合はアクセスキーを使用せず、可能であれば不要なアクセスキーを削除します。 ・共有しない  不特定の方への情報共有を避け、必要最低限のメンバーのみ共有とするか、全く共有しない運用をします。 ・権限を絞る  アクセスキーを開示する場合は、専用の権限を絞ったアクセスキーを作成し提示します。 ・MFAを設定する  多要素認証(MFA)により、第3者の利用をブロックします。 ・IAM ユーザーのアクセスキー定期更新  IAM ユーザーは定期的にアクセスキーを更新し、意図しない流出影響を抑えます。 ・IAM ロールの使用  アクセスキーを用いず、処理するためにIAMロールをインスタンスに設定します。 参考:AWS ドキュメント リファレンスガイド AWS アクセスキーを管理するためのベストプラクティス 参考:AWS Identity and Access Management ユーザーガイド IAM でのセキュリティのベストプラクティス IAM ロールの使用 (アクセスキーを用いないプログラムアクセス) AWSのアクセスキーは情報漏洩のリスクがありますので、慎重な管理が求められます。そのため、AWSのアクセスキーを極力使用せずに運用することが望まれます。AWSでは、IAMを用いてロールを作成することができるので、AWS アクセスキーを用いずにプログラムアクセスを実行することが可能です。これにより、慎重な管理を要するアクセスキーのセキュリティリスクを低減することが可能です。 IAM ロールの設定方法 AWSのコンピューティングサービスであるAmazon Elastic Compute Cloud(EC2)を用いたロールの設定について説明します。Amazon EC2のロールは、立ち上げ時に指定します。 アクセスキーに付与するポリシーについて アクセスキーを取得するIAMユーザーに付与するポリシーは最低限に留めることがセキュリティ上、重要。 Terraform用AWSアクセスキーのポリシーをスイッチロールだけに限定し、セキュリティをあげる方法 個人開発の場合、Full権限を与えたアクセスキーを用いてしまいがちだが、アクセスキーが流出してAWSを不正利用される怖さがある。 その対応策としてTerraformのコマンド実行をスイッチロールを用いた形に差し替え、不正利用できにくいようにする方法をメモしておく。  目指す体制 アクセスキー自体にはスイッチロール(Assume Role)するためだけの最低限の権限のみ。(アクセスキー単体ではAssume Role以外は何もできない) Terraformのインフラ実装自体はスイッチロール後のIAMロールが持つ権限で行う スイッチロール自体の実行条件を絞り込む 手順 スイッチ用ロールの作成 スイッチ用ロールの「信頼関係」の設定 IAMユーザーの権限設定 Terraform側の設定 具体的な方法は上記参考サイトに画像付きで説明してある。 ただし、Terraform側の設定に関しては、今回は下記Terraform側の設定コードで記した。 IAMロールの参考サイト 「AssumeRoleはRoleArnを入力するとCredentialsを返すAPIだ」 ・・・(中略) RoleArnというのは、IAM Roleの一意な名前で、arn:aws:iam::123456789012:role/role-nameといった文字列 *4です。返されるCredentialsは一時キー *5で、有効期限は1時間でした。 ・・・(中略) ロールに設定された権限を持った一時キーを入手することを「役割(role)の引き受け(assume)」と言います。 Terraform側の設定コード IAM User に sts:AssumeRole の権限を与えることで IAM Role の権限を引き受けることができます。・・・(中略)・・・ Terraform でも AssumeRole した権限で実行できるので、その方法を紹介します。・・・(中略)・・・ providers.tf 等のファイル名で provider を定義します。 providers.tf # Definition of Variables variable "aws_access_key_id" {} variable "aws_secret_access_key" {} # Definition of AWS provider provider "aws" { region = "ap-northeast-1" access_key = var.aws_access_key_id secret_key = var.aws_secret_access_key assume_role { role_arn = "arn:aws:iam::<自分のAWSアカウントID>:role/<スイッチロール先のIAMロール名>" } ポイント:assume_roleブロックを追加する providers.tf # assume_roleブロック assume_role { role_arn = "arn:aws:iam::<自分のAWSアカウントID>:role/<スイッチロール先のIAMロール名>" AWSアカウントIDは外部に漏れると危険なので、git等を使う場合は変数を用いて.tfvarsファイルで管理し、gitの管理外におくこと。 terraform.tfvars role_arn = "xxxxxxxxxxxxxxxxxxx" main.tf provider "aws" { access_key = "${var.access_key}" secret_key = "${var.secret_key}" region = "ap-northeast-1" # assume_roleブロック assume_role { role_arn = "${var.role_arn}" #<自分のAWSアカウントID>:role/<スイッチロール先のIAMロール名> } } AWSアクセスキーの取得方法 アクセスキーとシークレットアクセスキーはAWSにグループを作成しユーザを作成したタイミングに発行される。 シークレットアクセスキーはユーザを新規作成したタイミングでのみ確認可能(新規作成後にシークレットアクセスキーが分からなくなってしまった場合は再度キーを作成する必要がある)。 手順 グループの作成 ユーザの作成 各キーの確認 詳細は上記サイトを参照。下記サイトは公式。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Linux】S3環境でのllコマンドについて

Linuxを触る人は、llコマンドをこれでもかと使うと思います。 私もその一人です。 そもそもllコマンドは何ぞやという話ですが、以下コマンドの略です。 ls -l ファイルの作成日やサイズなど様々な情報が箇条書きで見れますので 私用する人は多いと思います。 aws s3 ll s3://xxx/xxx/ S3環境で使用すると上記のようになりますが、残念なことにエラーとなります。 理由は簡単で、略コマンドが使用できないからです。 ですので、S3環境では下記のようになります。 aws s3 ls s3://xxx/xxx/ 以上です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon EC2について簡潔にまとめました

はじめに 私は、AWSクラウドプラクティショナーの資格を取るために1月から勉強を始めた者です。 今回は、EC2について勉強したことをまとめましたので、みなさまの勉強の参考にしていただければと思います。 参考 AWSエンジニア入門講座――学習ロードマップで体系的に学ぶ EC2とは AWS EC2とは「Amazon Elastic Compute Cloud」の略称で、AWS(Amazon Web Service)で利用できるシステムです。 AWS上に仮想サーバーを構築して利用することができます。 Elasticは、「伸縮性が高い」という意味があり、システム規模に応じて性能や容量を拡張できます。 AWSクラウド内で作成したサーバーは「インスタンス」と呼ばれます。 従来のオンプレミスの場合、自社で物理的なコンピュータを用意するため、選定、導入、構築、準備まで含めると最低でも1ヶ月以上かかります。 また、物理サーバーは容量などが決まっているため、アクセスが急激に増えると対応できなくなり、最悪、サーバーがダウンするようなこともありえます。 EC2の場合、Web上で必要なスペックや台数を選択することで、最短の時間でユーザーが望む環境を構築することができます。 従量課金制のため、インスタンスを稼働した時間をスペックに対して使用料金がかかる仕組みとなっています。 EC2は、CPU使用率などのメトリクスに応じてサーバーの台数を自動で増減してくれるAuto Scalingと組み合わせると、コストを最適化することができます。 AMI AMI(Amazon Machine Image)とは、EC2インスタンスを構築する際に必要となる設計書のようなものです。 AMIには、コンピュータを動かすために必要なOSの情報や、提供したいサービスをインストールしているソフトウェアなどの情報がテンプレートとしてまとまっており、これらをもとにEC2は構築されます。 AWS側で事前に用意されているAMIを使用してもいいですし、ユーザー自身が作成したAMIを使うこともできます。 作成したAMIからEC2インスタンスを構築することで、それと同様の環境を複製することも可能です。 ユーザーデータ ユーザーデータとは、EC2インスタンスの初期設定で使用されるテキストデータのことです。 これを設定することで、EC2インスタンスの初回起動時、インスタンス内部のOSの設定やソフトウェアのインストールを自動化することができます。 シェルスクリプトを利用する方法や、cloud-initを利用する方法によって記述します。 どちらの記述法を使っても、EC2インスタンスの初回起動時にのみ実行され、自動的にインスタンスの初期化処理を実行できる便利な機能です。 インスタンスメタデータ インスタンスメタデータとは、EC2インスタンス内部からのみアクセス可能なインスタンスに関するデータのことを指します。 インスタンスIDや、インスタンスのパブリックIDアドレスなどが当てはまります。 サーバーの内部情報を利用したい場合に使われるものだと押さえておいてください。 ちなみに、パブリックIPアドレスについて、EC2を構築しただけでは取得できません。 インスタンスメタデータを利用することで付与されるパブリックIDアドレスを取得し、インスタンスに対してタグを付けることができます。 インスタンスタイプ インスタンスタイプとは、EC2の性能を決定するための要素であるCPU、メモリ、ストレージ、ネットワークパフォーマンスの組み合わせのことです。 インスタンスタイプは、「ファミリー」と「サイズ」という組み合わせで構成されています。 「ファミリー」では、汎用やコンピューティング最適化などの用途を選択し、「サイズ」では、CPU、メモリなどのスペックを選択します。 業務要件に合わせてリソースサイズを決定することとなります。 後から変更できるので、まずは必要最低限の要件を満たすインスタンスタイプを選択することになるでしょう。 EBS Amazon EBS(Elastic Block Store)とは、EC2インスタンスにアタッチして利用するブロックストレージサービスです。 KMS(AWS Key Management Service)を使用したディスクデータの暗号化や、スナップショットを使用したバックアップ機能などを備えています。 全てのボリュームは99.999%の可用性を実現するように設計されています。 耐久性は、ボリュームの種類で異なるため、要件に合わせて適切なボリュームを設計することとなります。 EBSでは、SSDタイプとHDDタイプのボリュームをサポートしています。 SSDは、サイズの小さいI/O操作を高頻度に処理する場合に利用します。 「汎用SSD」と「プロビジョンドIOPS SSD」タイプが存在します。 主に、ディスクI/Oの多いデータベースやアプリケーションなどで利用されます。 デフォルトでは「汎用SSD」がアタッチされ、特に要件が定められていなければ、汎用SSDをそのまま使用します。 処理が多くなる場合は、より高性能な「プロビジョンドIOPS SSD」を使用します。 HDDは、サイズの大きいI/O操作を処理する場合に利用します。 「スループット最適化HDD」と「Cold HDD」タイプが存在します。 安定したスループットを要求する場合は、I/Oサイズが大きくアクセス頻度の高さに対応できる「スループット最適化HDD」を使用します。 アクセス頻度が少ない場合は、最も低コストなボリュームタイプである「Cold HDD」を使用します。 EFS Amazon EFS(Elastic File System)は、フルマネージメント型のネットワークファイルストレージサービスです。 EFSは、99.999999999%(イレブンナイン)の耐久性を実現するよう設計されています。 デフォルトでは、ファイルシステム内のデータは複数のアベイラビリティゾーンに冗長的に保存されるなど、高い耐久性と高可用性を実現しています。 先ほど紹介したEBSは、基本的に1つのEC2インスタンスにアタッチして利用されるブロックストレージです。 一方、EFSはファイルストレージであり、共有ファイルシステムを前提としていることから、1〜数千のEC2インスタンスからの同時アクセスに対応しています。 EFSには、アクセス頻度の差や冗長性の差に対応したいくつかのストレージクラスが存在します。 ・標準ストレージクラス ・低頻度アクセスストレージクラス(標準ーIA) ・1ゾーンストレージクラス ・1ゾーン低頻度アクセスストレージクラス(1ゾーンーIA) Systems Manager AWS Systems Managerとは、EC2などのAWSリソースやオンプレミスのインフラストラクチャを管理・制御するためのサービスです。 Systems Managerを利用することで、リソース状況の可視化、定型作業の実施・自動化、アプリケーションの設定管理などを実現できるようになります。 機能タイプは、 ・高速セットアップ ・運用管理 ・アプリケーション管理 ・変更管理 ・ノード管理 ・共有リソース といった分類があります。 キーペア AWSでは、キーペアが推奨されています。 公開鍵(パブリックキー)と秘密鍵(プライベートキー)が生成され、2本で1組の対関係で利用します。 これを「公開鍵暗号方式」と呼んだりしますが、詳細は割愛します。 EC2の購入方法 EC2インスタンスの購入方法は3つです。 (1)オンデマンドインスタンス 特に指定しない限り、デフォルトで適用される購入方法となります。 EC2のスペックに応じた従量課金が行われます。 (2)リザーブドインスタンス EC2のスペックや配置するリージョンを1年または3年の期間、変更しないことを条件に割引価格が適用される購入方法です。 「全て前払い」「一部前払い」「前払いなし」といった支払いオプションを選べます。 (3)スポットインスタンス AWSの余ったリソースを使用してEC2を購入する方法です。 AWSのリソースの余り具合に応じて「スポット価格」と呼ばれる価格が変動していきます。 注意点としては、EC2のリソースが購入した分を超えた場合、EC2が終了してしまうところです。 こちらを選択する際は、アプリケーションの仕様について入念に構成しておく必要があるでしょう。 参考 AWSエンジニア入門講座――学習ロードマップで体系的に学ぶ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon S3へWordPressの画像を保存しようとするとうまくいかなかった

概要 AmazonS3へWordpressの画像を保存するべく、プラグインWP Offload Media Liteを使用し、Mediaに画像をアップロードしたが、S3に保存されない 理由と対応 2021年末に、バケットのパーミッションに「オブジェクトの所有権」の設定が導入されたことによるもの バケットのアクセス許可>オブジェクト所有者からACL有効に変更する 行った手順 Udemy (https://www.udemy.com/share/104nUE3@Tfuara8l9My57RTQylry8AZeTWCPC8rHQxwzMboE6A-k5zAph0b7BjZkCAYrS0RFKA==/) を参考に、下記を実施 1.AmazonS3バケットを作成 2.WebサーバからS3へのIAMロールを作成しEC2にアタッチ、ポリシーは下記の通り 3.wordPressからS3にアクセスするために必要なPHPモジュールのインストール php-xml php-gd php-develをインストール 4.WordPressのプラグインからWP Offload Media Liteをインストール、有効化し、設定から下記を設定 5.mediaから任意の画像をアップロードするが、ファイルURLがALBのものとなり、S3にもオブジェクトがない 解決策 バケット>アクセス許可>オブジェクト所有者を編集し、ACL有効にする 結果 S3に保存できるようになりました まとめ お寿司はイカではなくアジが好きです 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

外部攻撃からAWS環境を守れ!(アソシエイト試験対策)

SAAやSOAの試験勉強をしていて、こういう攻撃がきたときはこれ使う! っていうセキュリティ系のサービスが紛らわしかったのでまとめておく。 試験対策なので問題ありきかつ、覚えやすいように体系的っぽい感じでかいていきます。 概要図 試験での対策 ①SQLインジェクション、クロスサイトスクリプティング SQLインジェクション:入力フォームにSQL入れて実行させる クロスサイトスクリプティング:リンクのURLに危険なURLを仕込む 考え方:どっちもアプリケショーンの階層から攻撃してくるので、この階層で守る 回答:WAF(Web Application Firewall) ②DDos攻撃 DDoS攻撃:大量データの送信 考え方:大量データだから防御的(シールド)なものが必要(こじつけ) 回答:AWS Shield Shieldには「Standard」と「Advanced」があるのでその違いも。 ・Standard:DDos(レイヤー3、4)防ぐ。無料。 ・Advanced:上記に加えアプリケーション層(レイヤー7)での検知と保護が可能。有料。 そしてDDoS食らって料金がいきすぎたら払い戻しあり(神) ③APIコール、ブルートフォース、マルウェア等 APIコール:設定していないIPからAPIを読んでいる ブルートフォース:パスワードの総攻撃(パスワードが仮に4桁なら0000〜9999まで順に全部うちこむ) マルウェア:ウィルスとか。昔からよくあるやつ。 考え方:もうやられちゃってる系 回答:GuardDuty(Dutyは義務とか任務とかそんなイメージの単語らしいです) 感覚的にもっとあるかなと思ってましたが、よくきく攻撃に対するサービスは基本的にこの3つです。 もちろんセキュリティ的の基本としてIAM、EC2、VPC、Trail、Config、Inspecterなどがあります。 これで、この攻撃は〜ってのがきたときの対策はばっちりですね。 良いAWSスタディーライフを!! 以下参考にさせていただいたサイトです。感謝。 ・DDos対策 https://www.stylez.co.jp/columns/ddos_prevention_in_aws/#DDoSAWS_Shield_Standard ・AWSセキュリティサービスまとめ https://www.ragate.co.jp/blog/articles/10233#h2-3-h3-3 ・Shield https://zenn.dev/mn87/articles/255e9b9357ea3f ・GuardDuty https://recipe.kc-cloud.jp/archives/11935
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Visual Studio Code 上でAWS Lambda が編集できるようになるまで

Visual Studio Code 上でAWS Lambda 編集できるようになるまで (自分用のメモとして残しておきます) タイトルの通りです。 AWS Lambdaを学習中ですが…Lambdaだとソースが見にくい… ので、Visual Studio Code 上で以下のことができるようにしました。  ・ソースのダウンロード&直接編集  ・テストの実行  ・(編集した)ソースのアップロード 事前準備 (1) Visual Studio Code のインストール   https://azure.microsoft.com/ja-jp/products/visual-studio-code/ (2) Visual Studio Code のプロキシ設定(※必要な場合のみ)        (記載例:http://userName:password@proxy.xxxTsts.jp:8080 )   (記載場所)  (3) AWS ToolKit のインストール   (Ctrl + Shift + X で拡張機能を開き、「AWS Toolkit」を検索)   (ダウンロード後は、「AWS」アイコンが追加されます)    (4) AWS CLI のインストール   (AWSとローカル環境をつなぐ経路を作るイメージ)   https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-windows.html   (中段にリンクがあります)   (インストールはポチポチ進んでくだけでOK) (5) (4)でインストールしたAWS CLI のインストール確認 & 設定   ① AWS CLI のインストール確認     コマンドプロンプトで「aws --version」入力        ② AWS CLI の設定     コマンドプロンプトで「aws configure」入力     以下の入力を求められます      ・AWS Access Key    :※絶対に他人に知られてはいけません      ・AWS Secret Access Key :※絶対に他人に知られてはいけません      ・Default region name  :ap-northeast-1 (アジアパシフィック(東京)のコード)      ・Default output format :json     (補足:AWS Access Key の取得方法は、https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html) (6) (5)で設定した情報が、Visual Studio Codeでも見れることを確認   ① Ctrl + Shift + p 押下   ② 「AWS Create Creditals Profile」を選択       ③ 開かれたファイルに、(5)で設定した情報が記載されているはずです (7) Visual Studio Code からAWS への接続   プロファイルを選択するよう求められるので、先程作成したのを選ぶ   接続がうまくいくと、AWS の各サービスが見られるようになります。    本題 (0) 事前に、AWS Lambda 上で関数(aaa_test_file)で作成しました。   この関数に対して、以下(1)~(3)をやっていきます。    (1) ソースのダウンロード方法    ① visual Studio Code のエクスプローラーを更新          ② 対象のファイルを選び、「Download」を選択      (ワークスペースは適当に選択)          ③ ソースファイルが確認できました。       (2) テスト実行    ① 対象のファイルを選び、「Invoke on AWS」を選択          ② リクエストデータ入力し、「Invoke」を押下。      今回は動かすのが目的なので、適当にjson形式で値を設定します。      (ファイルから選択などもできます)         ③ 出力結果が表示されました。      (3) ソース編集&アップロード    ① Visual Studio Code 上で以下のようにソース編集しました。(7行目を追加)         ② 対象のファイルを選び、「Upload Lambda」を選択         ③ 「zip」か「ディレクトリ」を求められるので、「ディレクトリ」を選択          ④ 本題①-(2) で作成されたディレクトリ(関数名のディレクトリ)を選択         ⑤ ここでは「No」を選択 (ポップアップで確認されますが…OK)         ⑥ Successfully と表示されたら、AWS Lambda 上も更新されているはずです。          
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS向け基礎知識その2

1.はじめに この記事ではSnowファミリーをはじめとしたAWSのサービスについて書いていきます。 2.Snowファミリー SnowファミリーはTB(テラバイト)を超えるような大量のデータをAWSストレージへ転送するサービスです。その転送は、AWSから貸し出される機器にデータを取り込み、その機器をAWSに返送するとデータが「Amazon S3」というストレージに保存されるという流れで行います。 Snowファミリーには以下の3つのサービスがあります。 ・AWS Snowcone:デバイスが小さいのでIoTや持ち運びができます。1台につき80TB分のストレージとして利用でき、「AWS Datasync」を使用してオンラインで転送することも可能です。また、エッジコンピューティング荷も対応しています。 ・AWS Snowball:ペタバイト規模の大量のデータを転送することができます。このサービスは2つのオプションがあります。 ①Snowball Edge Storage Optimized:ローカルストレージや大量のデータを転送したいときに選択するオプションです。 ②Snowball Edge Compute Optimized:エッジコンピューティング向けで、vCPUやメモリが潤沢に搭載されており、オフラインでも高度な処理を行いたいときに選択するオプションです。 ・AWS Snowmobile:エクサバイト規模の大量のデータを転送することができます。そのため、デバイスのサイズも非常に大きく、14mのコンテナにストレージを搭載したトレーラーです。 3.その他のAWSサービス(一例) 他にもAWSのサービスは様々なものがありますのでその中から3つ紹介します。 ・Elastic Beanstalk:「S3」や「RDS」などのAWSのアプリケーションが動作するための環境を自動で構築することができるサービスです。 ・OpsWorks:ChefやPuppetを使って設定をコード化し、「EC2インスタンス」や「EBS」などの管理を自動化します。 ・CloudFormation:「JSON」や「YAML」でAWSリソースの設定を定義し、各AWSサービスの構築や設定を行います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

何となくわかった気になる週刊AWS - 2022/1/17週

はじめに こんにちは、なじむです。 オミクロンが猛威をふるっていますね…こんな時こそ外出を自粛して、家でコツコツとアップデートを確認するいい機会です。 というわけで今週も張り切ってやっていきましょう!AWS Japan さんがまとめている週刊AWSで確認した内容の自分用メモ。 今回は1/17週のアップデートです。 1/17(月) 1/17(月) は米国の祝日(キング牧師の誕生日)のためアップデートがありませんでした。 キング牧師の本名は "マーティン・ルーサー・キング・ジュニア" で、アフリカ系アメリカ人公民権運動の指導者として活動しました。I Have a Dream ! の名言を残しています(Wikipedia より) 1/18(火) Amazon Corretto 1 月の四半期更新情報 Corretto は Amazon が提供している無料の OpenJDK ディストリビューションです。現在、LTS (Long-Term Supported) として 8, 11, 17 がありますが、四半期に一度行われるマイナーアップデートが各バージョンに対して行われました。 脆弱性への対応と各種 Issue への対応でした。詳細は各バージョンの Change Log を参照ください。 Version Change Log 8.322 Change Log for Amazon Corretto 8 11.0.14 Change Log for Amazon Corretto 11 17.0.2 Change Log for Amazon Corretto 17 Correto は github からダウンロードできます。 (参考) corretto 日本リージョン対応状況 ※OSS のため対応リージョン記載なし 東京:- 大阪:- PartiQL API コールが消費するスループット容量を DynamoDB が返し、クエリとスループットコストの最適化を支援 DynamoDB は NoSQL データベースのマネージドサービスです。DynamoDB では、SQL互換の PartiQL を使用することで、SQL ライクに DynamoDB のデータを Select したり Update したりできます。 DynamoDB の読み込み、書き込みにはキャパシティユニットが必要になり、DynamoDB の料金はキャパシティユニットの消費量が大きな要因となります。PartiQL は気軽にクエリができる分、想定外にキャパシティユニットを消費して料金が高額になってしまったり、キャパシティユニットを枯渇させて読み込み/書き込みができなくなってしまう可能性があります。 本アップデートでは、PartiQL API を実行する際に ReturnConsumedCapacity オプションを使用することで、以下の情報を返すことができるようになりました。 消費される読み取り/書き込みキャパシティユニットの合計容量 インデックスの統計 これらの情報により、クエリとスループットコストを最適化しやすくなりました。 実際の動作は以下です。 以下のように aws dynamodb execute-statement を実行する際に return-consumed-capacity オプションを使用することで、PartiQL を実行する際に消費されるキャパシティユニットを表示してくれます(CloudShell より実行) $ aws dynamodb execute-statement --statement \ > "SELECT * FROM \"nagym-dynamodb\" WHERE \"PartitionKey\" = 'Hokkaido'" \ > --return-consumed-capacity TOTAL { "Items": [ ★ここは DynamoDB のデータ { "PartitionKey": { "S": "Hokkaido" } } ], "ConsumedCapacity": { ★ここが見えるようになった "TableName": "nagym-dynamodb", "CapacityUnits": 0.5 } } $ 今回のテーブルは非常に小さいデータだったため消費されるキャパシティユニットも少なかったですが、大きなテーブルをクエリする際にはもっと重宝するかもしれません。ReturnConsumedCapacity の詳細は以下を参照ください。 (参考) ExecuteStatement 日本リージョン対応状況 東京:対応 大阪:対応 AWS Elastic Disaster Recovery がフェイルバックオートメーションのサポートを開始 Elastic Disaster Recovery は DR 対策のためのサービスです。オンプレやパブリッククラウドに構築した仮想マシンや DB、 SAP 等のアプリケーションを AWS にバックアップ、AWS 上でのリカバリを行うことが可能です。 (出典) Network diagrams 今回のアップデートでは、DR サイトからオンプレミスの vCenter サーバへのフェイルバックを自動化する機能が追加されました。最新の DRS Mass Failback Automation クライアント (DRSFA クライアント) を利用することで、大規模なフェイルバックを自動化することが可能になります。 利用開始までの大まかな流れは以下です。 Elastic Disaster Recovery をセットアップする オンプレミスの vCenter サーバに Ubuntu Server 20.04 LTS (以下 Ubuntu Server) を構築する 構築した Ubuntu Server に、DRSFA クライアントをインストールする 適切な権限を持った IAM ユーザと IAM アクセスキーを作成する Ubuntu Server で、DRSFA クライアントを起動、設定する(設定時にアクセスキーが必要) $ python3 drs_failback_automation_init.pyc を実行して Failback 時の動作を設定する 上述の流れは以下を参照したものです。キャプチャ付きで分かりやすかったのでぜひご覧ください。 (参考) Performing a failback with the DRS Mass Failback Automation client vCenter Server とかないので実機検証はしていません… 日本リージョン対応状況 東京:対応 大阪:未対応 ※Elastic Disaster Recovery 自体に未対応 1/19(水) Amazon FSx for NetApp ONTAP が Amazon CloudWatch でパフォーマンスと容量のメトリクスの提供を開始 FSx for NetApp ONTAP は NetApp ONTAP (ファイルストレージ) のマネージドサービスです。 (出典) 新サービス – Amazon FSx for NetApp ONTAP これまで FSx for NetApp ONTAP のモニタリングを行うためには、NetApp のモニタリングツール (NetApp Cloud Insights や Harvest with Grafana) を使用してモニタリングする必要がありました。本アップデートにより CloudWatch のメトリクスを利用可能になり、追加設定なしでボリュームのパフォーマンスとストレージ使用量のモニタリング、アラームの設定ができるようになりました。 取得できるメトリクスは以下です(各メトリクスの説明は Monitoring with Amazon CloudWatch を参照ください) メトリクス File system metrics Detailed file system metrics Volume metrics Detailed volume metrics DataReadBytes ○ ○ DataWriteBytes ○ ○ DataReadOperations ○ ○ DataWriteOperations ○ ○ MetadataOperations ○ ○ DataReadOperationTime ○ DataWriteOperationTime ○ MetadataOperationTime ○ StorageCapacity ○ ○ StorageUsed ○ ○ ○ ○ LogicalDataStored ○ FilesUsed ○ FilesCapacity ○ 実際の画面は以下です。 FSx for NetApp ONTAP の画面から見るとこんな感じです(起動した直後なので何もない…) Cloudwatch の画面から見るとこんな感じです(この下の詳細な項目は省きます) 日本リージョン対応状況 東京:対応 大阪:未対応 ※FSx for NetApp ONTAP に未対応 1/20(木) アジアパシフィック (大阪) における Amazon RDS スナップショットの S3 へのエクスポート機能のお知らせ RDS はリレーショナルデータベースのマネージドサービスです。 RDS には、スナップショットを Apache Parquet 形式で S3 にエクスポートする機能があります。Apache Parquet 形式はテキスト形式と比較して、エクスポートが速い、S3 でのストレージ使用量が少ないといった特徴があります。エクスポートしたデータは Athena や SageMaker、Apache Spark などを使用して分析することも可能です。本アップデートにより、この機能が大阪リージョンでも使用可能になりました。 (出典) Amazon S3 への Amazon RDS Snapshot Export によるデータレイクの構築とデータ保持ポリシーの実装 実際の画面は以下です。 エクスポートできるようになっています。 エクスポートした S3 を見たところ、RDS に DB を作成していないせいでデータが何もエクスポートされなかった(それはそう…)ため、実際の動作は以下を参照ください。 (参考) [新機能]RDSのスナップショットがS3にエクスポートできるようになりました。 なお、本機能を使用するためには RDS で使用するエンジンのバージョンに指定があったり、S3 は RDS と同じリージョンにないといけない等、いくつが注意が必要です。詳細はホワイトペーパーを参照ください。 (参考) Amazon S3 への DB スナップショットデータのエクスポート 日本リージョン対応状況 東京:対応 大阪:対応 Red Hat OpenShift Service on AWS (ROSA) がアジアパシフィック (大阪) リージョンで利用可能に Red Hat OpenShift Service on AWS (ROSA) は、Red Hat 社が提供している Kubernetes のプラットフォームである OpenShift を、AWS で動かすためのマネージドサービスです。OpenShift を使用することで、通常の Kubernetes には備わっていない機能を利用できたり、長期サポートを受けられたりします。 実際に構築できていないのですが、大阪リージョンで利用可能になっていました。 やってみた系のブログはクラメソさんのブログが参考になりますのでご覧ください。 (参考) Red Hat OpenShift Service on AWSがGAになったので触ってみた 日本リージョン対応状況 東京:対応 大阪:対応 Amazon EC2 のお客様は EC2 Instance Connect の認証で ED25519 キーが使用可能に EC2 は仮想マシンのサービスです。 EC2 に接続するためには以下のような方法があります。 ローカルマシンでターミナルソフトを起動し、SSH 接続する セッションマネージャから接続する EC2 Instance Connect から接続する EC2 シリアルコンソールから接続する これまで、CLI を使用して "EC2 Instance Connect"、"EC2 シリアルコンソール" の接続をする場合は RSA のキーペアしか使用できませんでした。本アップデートにより、それらのログインに CLI を使用した場合でも ED25519 のキーペアが使用可能になりました。 ED25519 は 2021/8/17 に EC2 へのログインに利用可能になり、従来の RSA のキーペアよりもセキュアとなっています。 (参考) Amazon EC2 のお客様は、インスタンス接続操作中の認証で ED25519 キーを使用できるようになりました 今回は EC2 Instance Connect を使用して実際の動作を確認していきます。 EC2 Instance Connect は、EC2 Instance Connect CLI (mssh) を使用する以外に、独自の SSH キーで接続することもできます。今回は ED25519 キーを新規作成して SSH 接続してみます。実施する前に AWS CLI を最新版にアップデートしてください。 早速ですが、EC2 Instance Connect で接続した結果は以下です(※必要に応じてマスクしています) $ ssh-keygen -t ed25519 -f nagym-keypair-ed25519 (省略) $ ls nagym-keypair-ed25519* nagym-keypair-ed25519 nagym-keypair-ed25519.pub $ aws --version aws-cli/2.4.13 Python/3.8.8 Linux/4.14.252-195.483.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off $ aws ec2-instance-connect send-ssh-public-key \ > --instance-id i-xxxxxxxxxx \ # マスク > --availability-zone ap-northeast-1d \ # 適切な AZ に > --instance-os-user ec2-user \ > --ssh-public-key file://nagym-keypair-ed25519.pub # 適切な keypair に { "RequestId": "12345678-abcd-1122-aabb-1234abcd5678", "Success": true } $ ssh -o "IdentitiesOnly=yes" -i nagym-keypair-ed25519 ec2-user@ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com Last login: Tue Jan 25 11:34:25 2022 from ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ 11 package(s) needed for security, out of 17 available Run "sudo yum update" to apply all updates. $ ちなみに、AWS CLI が古いと以下のように失敗します。ED25519 に対応していないと公開鍵長が 256 未満は対応していないようです。 $ aws --version aws-cli/2.4.6 Python/3.8.8 Linux/4.14.252-195.483.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off $ aws ec2-instance-connect send-ssh-public-key \ > --instance-id i-xxxxxxxxxx \ # マスク > --availability-zone ap-northeast-1d \ # 適切な AZ に > --instance-os-user ec2-user \ > --ssh-public-key file://nagym-keypair-ed25519.pub # 適切な keypair に Parameter validation failed: Invalid length for parameter SSHPublicKey, value: 145, valid min length: 256 $ 今回は EC2 Instance Connect で確認しましたが、EC2 シリアルコンソール接続の場合も aws ec2-instance-connect コマンドを使用しているため同様のアップデートが適用されています。それぞれの接続方法の詳細は以下を参照ください。 (参考) EC2 Instance Connect を使用した Linux インスタンスへの接続 (参考) EC2 Serial Console for Linux instances 日本リージョン対応状況 東京:対応 大阪:未対応 ※EC2 Instance Connect に未対応(と思われる) Amazon GuardDuty で、別の AWS アカウントから使用された EC2 インスタンスの認証情報の検出が可能に GuardDuty は AWS アカウントや AWS に構築した環境に対する脅威検知のためのマネージドサービスです。CloudTrail や VPC Flow Logs、DNS Logs をデータソースとして悪意のあるアクティビティを検知します。 (出典) Amazon GuardDuty これまで、漏洩した IAM ロールの認証情報が AWS の外で使用される場合は検知ができました。本アップデートにより、漏洩した IAM ロールの認証情報が他の AWS で使用された場合でも検知がで切るようになりました。 以下の操作を実行して検証します。 AWS Account A(攻撃される側):認証情報を確認 メタデータにアクセスすることで、IAM ロールの認証情報を取得します。 $ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>/ { "Code" : "Success", "LastUpdated" : "yyyy-MM-ddThh:mm:ssZ", "Type" : "AWS-HMAC", "AccessKeyId" : "xxxxxxxxxxxx", "SecretAccessKey" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Token" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Expiration" : "yyyy-MM-ddThh:mm:ssZ" } $ AWS Account B(攻撃する側):認証情報を用いて S3 に対するコマンドを実行 $ export AWS_ACCESS_KEY_ID="上述の出力結果の該当箇所を貼り付け" $ export AWS_SECRET_ACCESS_KEY="上述の出力結果の該当箇所を貼り付け" $ export AWS_SESSION_TOKEN="上述の出力結果の該当箇所を貼り付け" $ aws sts get-caller-identity (AWS Account A の認証情報であることが分かります) $ aws ec2 describe-instances (オブジェクトの一覧が表示されます) 実際の GuardDuty の検知画面は以下です。 UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS が検知されています。 イベントをクリックすると詳細が表示されますが、その内容は公式ブログを参照ください。 (参考) Amazon GuardDuty で EC2 インスタンス認証情報漏洩の検出を強化 日本リージョン対応状況 東京:対応 大阪:対応(おそらく対応していると思います) Amazon EMR が Apache Spark SQL のサポートを開始し、Lake Formation の統合が有効になっている場合に Glue Data Catalog テーブルへのデータ挿入や更新が可能に EMR はビッグデータを分析するためのプラットフォームです。Apache Hadoop や Apache Spark 等を使用して、データ分析を行うことができます。 (出典) Amazon EMR 2020/10/9 に EMR 5.31 以降で EMR と Lake Formation の統合が GA となりました。この時は Spark SQL を 用いた参照系の処理(SHOW DATABASES, DESCRIBE TABLE 等)の操作が可能でした。 (参考) Amazon EMR と AWS Lake Formation の統合が一般提供開始 本アップデートでは EMR と Lake Formation の統合に機能を追加し、Spark SQL を用いた更新系の処理(INSERT INTO, INSERT OVERWRITE, ALTER TABLE)が Glue Data Catalog テーブルに対して実行可能になりました。 実機での動作は確認できていませんが、EMR と Lake Formation の統合は以下が参考になると思いますのでご覧ください。 (参考) Lake Formation を使用した Amazon EMR クラスターを起動する なお、本機能は EMR 5.34 以降でのみ利用可能であり、EMR 6.x.x では利用不可のためご注意ください。 日本リージョン対応状況 東京:対応 大阪:未対応 AWS Lambda がイベントソースとして Amazon MSK、Apache Kafka、Amazon MQ for Apache Active MQ、RabbitMQ の Max Batching Window をサポート Lambda はサーバレスでコードを実行できるマネージドサービスです。 Lambda では、実行するためのトリガーとして様々なサービスが選択できます。本アップデートでは、以下のメッセージキューイングサービスをトリガーにした場合、一定の間隔(例えば 300 秒)で Lambda を実行するバッチウィンドウを設定できるようになりました。 Apache Kafka Amazon MSK RabbitMQ Amazon MQ for Apache Active MQ これにより、一回の実行で Lambda に渡されるレコードの平均数を増やすことができ、呼び出し回数を減らし、コストを削減することが可能です。 その他には、次の条件のいずれかが満たされると、関数が呼び出されます。 ペイロードサイズが 6 MB に達する バッチサイズが最大値に達する Max Batching Window が最大値に達する <- New 実際の画面は以下です(例としてMSKを確認します) バッチウィンドウが設定できるようになっています。 日本リージョン対応状況 東京:対応 大阪:対応 1/21(金) Amazon EMR がデータレイク向けの高パフォーマンス、並列処理、ACID に準拠しているテーブルフォーマットの Apache Iceberg のサポートを開始 EMR はビッグデータを分析するためのプラットフォームです。Apache Hadoop や Apache Spark 等を使用して、データ分析を行うことができます。 (出典) Amazon EMR 本アップデートでは、EMR 6.5.0 を使用している場合に Apache Iceberg 0.12 が利用可能になりました。Apache Iceberg はテーブルフォーマット形式(テーブルを構成するファイルをどのように管理、整理、追跡するか)の一つです。Iceberg を用いることにより、データレイク(例えば S3)に保存されたデータに対して Spark、Hive、Presto から 更新処理を行うことができるようになります。 Apache Iceberg に関しては、2021/11/29 に Athena が Iceberg に対応した時の以下ブログが非常に参考になりましたのでご覧ください。 (参考) Amazon Athena の Apache Iceberg 対応 previewを試す EMR で Iceberg を使用するには、クラスター(6.5.0)作成時の詳細設定で classification=iceberg-defaults,properties=[iceberg.enabled=true] の設定を入れてあげれば良いようです。 東京リージョンでも設定自体はできたのですが、アップデートのページには東京/大阪リージョンには対応していないと書いてあったので実際に動作はしないのかもしれません。 日本リージョン対応状況 東京:未対応 ※Iceberg 0.12 に未対応? 大阪:未対応 ※Iceberg 0.12 に未対応? 感想 投稿が遅くなってしまいました… 時間が取れず実機確認ができないものが多かったので、来週分はしっかり確認していこうと思います。。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS-CLIでELB+Cognitoを使ったBasic認証実装

背景 単発的なものだったらコンソールでここが○○であっちが△△でと思い出しながら調べながらでも別によいかなと思っていたのですが、散発的にELBとCognitoを使用したBasic認証を使うことがあり、またCognitoコンソールは新旧でUIがガラッと違っていて、これを期にコンソールに縛られないcliベースでの実装を整理しておこうというのと、cliベースで書かれたのものが見当たらなかったというのが主な背景になります。 ネタとしての真新しさは薄いのであしからず。 Cognito ユーザープール作成 前提 ユーザ及びパスワードは管理者が管理するケースを想定 パスワードポリシーは以下の通り パスワードの最小文字数 12 文字 少なくとも 1 つの数字を含む 少なくとも 1 つの特殊文字 (^ $ * . [ ] { } ( ) ? - " ! @ # % & / \ , > < ' : ; | _ ~ ` + =) を含む 少なくとも 1 つの大文字を含む 少なくとも 1 つの小文字を含む 一時パスワード有効期限:7日 ## 変数定義 PROFILE= ENV= PREFIX= POOL_NAME=${PREFIX}_${ENV}_basicauth_pool ## user_pool作成 USER_POOL=$(aws cognito-idp create-user-pool \ --profile $PROFILE \ --pool-name $POOL_NAME \ --alias-attributes preferred_username \ --username-configuration CaseSensitive=true \ --admin-create-user-config AllowAdminCreateUserOnly=true \ --account-recovery-setting 'RecoveryMechanisms=[{Priority=1,Name=admin_only}]' \ --policies 'PasswordPolicy={MinimumLength=12,RequireUppercase=true,RequireLowercase=true,RequireNumbers=true,RequireSymbols=true,TemporaryPasswordValidityDays=7}') ## user_pool_id取得 USER_POOL_ID=$(echo ${USER_POOL} | jq -r .UserPool.Id) ユーザプールクライアント作成 CALL_BACK_DOAMINはRoute53でELBと紐付けているレコードを指定 ## 変数定義 CLIENT_NAME=${PREFIX}_${ENV}_basicauth_client CALL_BACK_DOAMIN= ## client作成 USER_POOL_CLIENT=$(aws cognito-idp create-user-pool-client \ --profile $PROFILE \ --user-pool-id $USER_POOL_ID \ --client-name $CLIENT_NAME \ --generate-secret \ --explicit-auth-flows ALLOW_USER_PASSWORD_AUTH ALLOW_USER_SRP_AUTH ALLOW_REFRESH_TOKEN_AUTH \ --supported-identity-providers COGNITO \ --callback-urls https://$CALL_BACK_DOAMIN/oauth2/idpresponse \ --allowed-o-auth-flows code \ --allowed-o-auth-scopes openid \ --allowed-o-auth-flows-user-pool-client) ## client_id取得 CLIENT_ID=$(echo ${USER_POOL_CLIENT} | jq -r .UserPoolClient.ClientId) ユーザープールドメイン作成 ## 変数定義 DOMAIN=${PREFIX}-${ENV}-elbbasic ## user_pool_domain作成 aws cognito-idp create-user-pool-domain \ --profile $PROFILE \ --domain $DOMAIN \ --user-pool-id $USER_POOL_ID ユーザ作成 ## 変数定義 USER_NAME= PASSWORD= ## user作成 aws cognito-idp admin-create-user \ --profile $PROFILE \ --user-pool-id $USER_POOL_ID \ --username $USER_NAME \ --temporary-password $PASSWORD ## パスワードステータス変更 aws cognito-idp admin-set-user-password \ --profile $PROFILE \ --user-pool-id $USER_POOL_ID \ --username $USER_NAME \ --password $PASSWORD \ --permanent ELB ListenerRule変更 前提 Priorityが1(not default)の既存のListenerRuleを変更する場合を想定 認証後に任意のTargetGroupに転送する場合を想定 リクエスト条件は既存のまま ※ListenerRuleの前提がPJによってだいぶ違うのでここは手でやった方が正直よさそう。。 ## 変数定義 AWS_ACCOUNT_ID=$(aws sts get-caller-identity --profile ${PROFILE} | jq -r '.Account') USER_POOL_ARN=arn:aws:cognito-idp:ap-northeast-1:${AWS_ACCOUNT_ID}:userpool/${USER_POOL_ID} LISTENER_ARN= TARGETGROUP_ARN= ## 対象Rulearn取得 RULE_ARN=$(aws elbv2 describe-rules \ --profile $PROFILE \ --listener-arn $LISTENER_ARN \ | jq '[.Rules[]]' | jq 'map(select(.Priority=="1"))' | jq -r '.[].RuleArn') ## Rule変更 aws elbv2 modify-rule \ --rule-arn $RULE_ARN \ --actions Type=authenticate-cognito,AuthenticateCognitoConfig={"UserPoolArn=$USER_POOL_ARN, UserPoolClientId=$CLIENT_ID,UserPoolDomain=$DOMAIN"},Order=1 \ Type=forward,ForwardConfig={"TargetGroups={"TargetGroupArn=$TARGETGROUP_ARN"}"},Order=2 まとめ cliでリソース定義を細かく指定して作成する場合は動作確認で時間を取られガチですが、一度コマンド出来上がってしまえばUIの刷新に左右されず同じ結果を得られるなどの利点があるため、何度か繰り返しそうなタスクでは積極的に活用していきたいところ。 今回のケースでは叩くコマンドや変数の定義、必要なARNを事前に引っ張ったりと手数が多くなってしまったので、まだ改善の余地はありそうですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CLIの振り返り ~Route53入門編~

本記事の目的 JAWS-UG CLI オンラインハンズオンの復習として、ハンズオンで取り上げられたAWSサービスに関する用語と、使用したAWS CLI コマンドを箇条書きでまとめる。 今回はRoute 53入門編を取り上げる。 主なAWSサービス用語 委任セット 同一のAWSアカウントで作成される、4つの権威DNSサーバのセット。 複数のホストゾーンで再利用する事ができる。 Whois IPアドレスやドメイン名の登録情報を、インターネットユーザーが参照できるサービス。 ホストゾーン ドメイン及びサブドメインのトラフィックのルーティング方法についての情報を保持するコンテナ。 リソースレコード DNSにおける、ホスト名やドメイン名の設定が定義されているデータ。 JSON形式のリソースレコード設定ファイルをホストゾーンに対して適用する事で、リソースレコードを作成・更新・削除できる。 Aレコード IPv4でホスト名とIPアドレスの関連づけを定義するリソースレコードの一種。 CNAMEレコード 正規ホスト名に対する別名を定義するリソースレコードの一種。 MXレコード 対象ドメイン宛のメールサーバのホスト名を定義するリソースレコードの一種。 NSレコード ゾーン情報を管理するネームサーバーのホスト名を定義するリソースレコードの一種。 TTL DNSにおいて、リソースレコードをキャッシュに保持してもよい時間(秒数単位)。 主なAWS CLI コマンド一覧 Route53委任セットの作成 $ create-reusable-delegation-set --caller-reference <委任セット識別子> Route53委任セットの一覧表示 $ aws route53 list-reusable-delegation-sets Route53委任セットの削除 $ aws route53 delete-reusable-delegation-set --id <委任セット識別子> Route53ホストゾーンの作成 $ aws route53 create-hosted-zone --name <ホストゾーン名> --caller-reference <ホストゾーン識別子> [--hosted-zone-config <ホストゾーン設定>] [--delegation-set-id <委任セット識別子>] ※--hosted-zone-configオプションの引数としてComment="<コメント内容>"を指定する事で、ホストゾーンに特定のコメントを付与できる。 Route53ホストゾーンの一覧表示 $ aws route53 list-hosted-zones Route53ホストゾーンの削除 $ aws route53 delete-hosted-zone --id <ホストゾーンID> Route53リソースレコードセットの変更 $ aws route53 change-resource-record-sets --hosted-zone-id <ホストゾーンID> --change-batch file://<リソースレコードセット設定ファイルパス> Route53リソースレコードセットの変更状況取得 aws route53 get-change --id <リソースレコードセット変更ID> Route53リソースレコードセットの一覧表示 aws route53 list-resource-record-sets --hosted-zone-id <ホストゾーンID> 参考文献 AWSCLIコマンドリファレンス:Route53 JAWS-UG CLI専門支部:ハンズオン(簡易版): Route53入門
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift×AWS】iOSアプリにAPI Gatewayを導入してCognitoから指定のユーザーデータを消去する

前提 ユーザーの退会機能を作るべく、今までAmplifyを使用していたアプリにAPI Gatewayを追加したサーバレスアプリです。 Amplifyからユーザーの削除APIがあればよかったのですが見つからずで、Lambdaから実現することに。(もしAmplifyからのやり方を知っている人がいたら教えてください笑) 元々はLambdaが使えれば良く、どうやらLambdaを直叩きする方法もあるっぽいんですが、API Gatewayを触ったことがなかったのでそちらを使って実装してみることにしました。 また、今回初めてAPI Gatewayを触るので、とりあえずリクエストだけ実装してレスポンスはデフォルトです。 実装が甘いところ等もあると思いますがご容赦ください。 構成 構成はこんな感じ。これをAlamofireを使って叩いていきます。 実際の設計にはユーザーの他のデータも消すため、Lambdaの先にDynamo DBなりS3なりがくっついているのですが、今回はCognitoのユーザーを消すことが目的なので割愛。 気が向いたらそちらも記事にします。 以下、各所説明。 ◆API Gateway 今回の主役です。APIがユーザー側から叩かれたらIDトークンを検証して、トークンの中にあるsub値をLambdaに渡します。そしてそれに応じてレスポンスをユーザー側に返していきます。 ◆AWS Lambda API Gatewayから呼ばれたら、送られてきたsub値を元に該当するcognitoユーザーを消去します。 実装方法 ◆Lambda API Gateway実装時に、Lambda関数を指定するため、先に該当するLambda関数を作成しておく。 ①Lambda関数を作成する。今回はNode.jsを使用して実装しますが、お好きなのを選択してください。 関数名は今回は"delete_user"とします。 ②関数を作成したら、Lambda関数がcognitoにアクセスできるようにロールにポリシーを振る。 設定タブにあるロールをクリック。 ③「ポリシーをアタッチします」をクリックし、「AmazonCognitoPowerUser」をアタッチ。 ④コードを実装する。私は以下のコードで実装しました。 let aws = require("aws-sdk"); exports.handler = async (event) => { // eventから削除するCognitoユーザーのユーザー名を格納 let userName = event.context.sub; // Cognitoユーザーの無効化メソッドをコール await disalbeCognito(userName); const response = { statusCode: 200, }; return response; }; // Cognito情報を無効化し、ログインできないようにする async function disalbeCognito(username){ // Cognitoを使う準備 aws.config.update({ region: 'ap-northeast-1', }); const cognito = new aws.CognitoIdentityServiceProvider({ apiVersion: '2016-04-18' }); // 対象のCognitoユーザープールID const user_pool_id = "ap-northeast-1_xxxxxxxx"; // ユーザー削除 try { await cognito.adminDeleteUser({ UserPoolId: user_pool_id, Username: username }).promise(); console.log("Success! userName : " + username); } catch (err) { console.log("Failed! userName : " + username); if (err.code == 'UserNotFoundException') { // ユーザープールにユーザーが存在していない場合 console.log('UserNotFoundException'); } else { // その他のエラー console.log(err, err.stack); } throw err; } } 使用するならコピペで大丈夫ですが、一箇所注意点があるのでお伝えしておきます。 let userName = event.context.sub; 4行目のこちらですが、これはAPI Gatewayの中にあるJSONの影響によってこうなっています。JSONの形式はAPI Gatewayの方で載せてある、そちらを確認してみてください。 こちらでデプロイしてLambdaは完了です。 ◆API Gateway ①AWSコンソール画面からAPI Gatewayを開き、REST APIの構築を選択。 ②プロトコル-REST、新しいAPIの作成を選択、API名(わかりやすい名前)を入力し、APIの作成をクリック。 ③アクションをクリックしメソッドの作成を選択。 ④作成されたメソッドを選択し、該当するものを選択。今回はユーザーを削除したいため「DELETE」を選択。その後、チェックマークをクリック。 ⑤作成されたメソッドのセットアップ。ここで先ほど作成したLambdaを指定し、保存をクリック。 ⑥"オーソライザー"タブを選択し、「新しいオーソライザーの作成」を選択し、作成。 ※ここで、消去したいユーザーが存在するユーザープールを選択。 ※また、トークンのソースは"Authorization"を入力したが、値はお好きなもので。 ⑦リソース→作成したメソッド→メソッドリクエストをクリックし、"認可"の右側の鉛筆マークから⑥で作成したおーそライザーを選択し、チェック。 ⑧統合リクエスト内下部のマッピングテンプレートから、「マッピングテンプレートの追加」を選択、Content-typeに"application/json"と入力しチェック。 ⑨テンプレートに以下のコードを入力し保存。 { "context" : { "sub" : "$context.authorizer.claims.sub" } } 上記により、IDトークン内のsubの値を取り出してLambdaに渡すことができます。 ここのJSONの形がcontext : { sub : {} } なので、Lambdaのeventの後にcontext.subと記述しています。 ⑩アクション→APIのデプロイを選択し、新しくステージを作成してデプロイすれば、完了です。 ※この手順で作るURLの形は決まっていて、以下のようになっています。 https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}/ そのため、stage名もある程度わかりやすいor命名規則を設けた方が良いでしょう。 ◆Swift Swift側の実装はメインではないので、さっくりコードだけ載せようと思います。 public func deleteAPI( completion: (()->())?=nil) { let urlString = "https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}/" let defaultHeader = ["Authorization" : "Bearer \(cognito.idToken)"] as HTTPHeaders Alamofire.request(urlString, method: .delete, headers: defaultHeader) .responseJSON() { (response) in switch response.result { case .success: print("success") break case .failure: print("failure") break } } } 以上で、実装終了です。 感想 駆け足でしたが、いかがだったでしょうか。 分かりくいところもあったと思いますが、筆者もそこまで深く理解できているわけではないのでご容赦ください。 何かありましたら、コメントで教えてくださると助かります。 API Gatewayは初めて触ってみたのですが、使いやすくて良いですね。何より便利です。 サーバレスってことでAPI Gatewayが使えてくると元々使えているAmplifyも使ってバックエンド側もガンガン構築できそうです。 それでは。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SageMakerへのscikit-learnモデルのデプロイメント

scikit-learn model deployment on SageMaker | Databricks on AWS [2021/3/22時点]の翻訳です。 本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。 このノートブックではscikit-learnモデルのトレーニング、scikit-learnフォーマットでの保存で説明されている糖尿病データセットでトレーニングしたElasticNetモデルを使用します。このノートブックでは以下を説明しています。 MLflowエクスペリメントUIを用いてデプロイするモデルを選択。 MLflow APIを用いてSageMakerにモデルをデプロイ。 sagemaker-runtime APIを用いてデプロイされたモデルを検索。 別のモデルに対してデプロイ、クエリープロセスの繰り返し。 MLflow APIを用いてデプロイメントを削除。 DatabricksからAWS SageMakerにMLflowモデルをデプロイできるように、どのようにAWSの認証設定を行うのかについては、機械学習モデルをSageMakerにデプロイするのためのAWS認証設定のセットアップをご覧ください。 SageMakerエンドポイントへのデプロイがわかりにくいので補足します。 MLflow SageMaker APIを用いてモデルをSageMakerエンドポイントにデプロイする際、AmazonのElastic Container Registry (ECR)のDockerイメージを指定します。SageMakerはモデルをサービングする際にこのイメージを使用します。 ローカルマシンでMLflow CLI:mlflow sagemaker build-and-push-containerを実行し、mlflow-pyfuncイメージをビルドし、イメージをECRのリポジトリにアップロードします。ECRリポジトリにmlflow-pyfuncイメージが作成されます。アップロード完了後、DockerイメージのURLを取得することができます。 ローカルマシンでAWS CLIのインストール、設定aws configureを行います。 インストールされていない場合、PyPIでmlflow、 boto3をインストールしておきます。 ローカルマシンでmlflow sagemaker build-and-push-containerを実行すると、Dockerイメージの作成およびECRへのアップロードが行われます。 Python # 以下でECR DockerイメージのURLを指定します。 # ECR URLは以下のフォーマットである必要があります: {account_id}.dkr.ecr.{region}.amazonaws.com/{repo_name}:{tag} image_ecr_url = "<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/mlflow-pyfunc:1.23.1" 上のURLを指定して、エンドポイントへのモデルデプロイを行います。 Python import mlflow.sagemaker as mfs app_name = "diabetes-class-v1" mfs.deploy(app_name=app_name, model_uri=model_uri, image_url=image_ecr_url, region_name=region, mode="create") しばらくすると、エンドポイントがInServiceになるので、この後は予測結果を得るために モデルに対してクエリーを実行することができます。 MLflow scikit-learnモデルトレーニングのノートブック Databricks 無料トライアル Databricks 無料トライアル
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

機械学習モデルをSageMakerにデプロイするのためのAWS認証設定のセットアップ

Set up AWS authentication for SageMaker deployment | Databricks on AWS [2021/3/17時点]の翻訳です。 本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。 本書では、MLflowモデルをAWS SageMakerにデプロイするために、どのようにインスタンスプロファイルをセットアップするのかを説明します。ここで用いるIAMロールと同様のアクセス権をAWSユーザーのアクセスキーで設定することは可能ですが、SageMakerにデプロイするクラスターにアクセス権を設定する際にはインスタンスプロファイルを使用することをお勧めします。 ステップ1: AWS IAMロールを作成し、SageMakerのアクセス権ポリシーにアタッチする AWSコンソールでIAMサービスに移動します。 サイドバーのロールをクリックします。 ロールの作成をクリックします。 信頼エンティティのタイプの選択でAWSサービスを選択します。 このロールを使用するサービスの選択でEC2サービスを選択します。 次へ:アクセス権をクリックします。 アクセス権ポリシーのアタッチ画面で、AmazonSageMakerFullAccessを選択します。 次へ:レビューをクリックします。 ロール名にロール名を入力します。 ロールの作成をクリックします。 ロール一覧でロール名をクリックします。 arn:aws:iam::<account-id>:role/<role-name>のフォーマットのロールのARNをメモしておきます。 ステップ2: SageMakerデプロイメントリソースにアクセスするためのインラインポリシーを追加する ロールにポリシーを追加します。 をクリックします。 以下のJSON定義を貼り付けます。 JSON { "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:PutObjectAcl", "s3:PutObjectTagging" ], "Resource": [ "arn:aws:s3:::mlflow-sagemaker-*-<account-id>", "arn:aws:s3:::mlflow-sagemaker-*-<account-id>/*" ], "Effect": "Allow" }, { "Action": [ "iam:GetRole" ], "Resource": [ "arn:aws:iam::<account-id>:role/<role-name>" ], "Effect": "Allow" }, { "Action": [ "ecr:DescribeRepositories" ], "Resource": [ "arn:aws:ecr:*:<account-id>:repository/*" ], "Effect": "Allow" } ] } これらのアクセス権により、Databricksクラスターに以下のことを許可します。 新規ロールのカノニカルARNの取得 SageMakerエンドポイントサーバーによって使用されるS3に対するアクセス権スコープオブジェクトのアップロード ロールのアクセス権は以下のようになります。 ステップ3: ロールの信頼ポリシーを更新する sagemaker.amazonaws.comへのiam:AssumeRoleを追加します。 Role Summary > Trust relationships > Edit trust relationshipに移動します。 以下のJSONを貼り付けて保存します。 JSON { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Effect": "Allow", "Principal": { "Service": "sagemaker.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } お使いのロールの信頼関係は以下のようになります。 ステップ4: お使いのDatabricksワークスペースのAWSロールが、ロールを引き渡せるように設定する DatabricksワークスペースのAWSロールに移動します。 をクリックします。 以下のJSON定義を貼り付けて保存します。 JSON { "Version": "2012-10-17", "Statement": [ { "Action": [ "iam:PassRole" ], "Resource": [ "arn:aws:iam::<account-id>:role/<role-name>" ], "Effect": "Allow" } ] } account-idはAWS SageMakerサービスを実行しているアカウントのIDであり、role-nameはステップ1で定義したロールとなります。 ステップ5: Databricksクラスターのインスタンスプロファイルを作成する DatabricksのAdminコンソールでInstance Profilesタブを開き、Add Instance Profileをクリックします。 作成したAWSロールと紐付けられているインスタンスプロファイルARNを貼り付けます。ARNはarn:aws:iam::<account-id>:instance-profile/<role-name>のフォーマットであり、AWSコンソールで取得できます。 Addボタンをクリックします。 詳細につていは、Databricksにおけるインスタンスプロファイルを用いたS3バケットへのセキュアなアクセスをご覧ください。 ステップ6: インスタンスプロファイルを設定したクラスターを起動する ステップ6 インスタンスプロファイルを指定してクラスターを起動するをご覧ください。 Databricks 無料トライアル Databricks 無料トライアル
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS WAFの公開設定を色々とためしてみた

AWS WAFの公開設定を色々とためしてみました 事前準備 Amazon CloudFrontとAmazon S3を組み合わせて公開 Amazon CloudFront #001 - Amazon S3と組み合わせて公開 Amazon CloudFrontと組み合わせた公開 AWS WAFとAmazon CloudFrontを組み合わせて公開する方法です。 AWSコンソール → WAF & Shieldをクリック。 「Create web ACL」をクリック。 任意名称を設定。リソースタイプにCloudFrontを選択。対象のCloudFrontディストリビューションを選択。その他は今回はデフォルトのまま設定。 内容を確認し「Create web ACL」をクリック。 作成されたWeb ACLをクリック。 Web ACLの詳細を確認できます。 指定IPのみ公開 AWS WAFで指定IPのみ公開する方法です。 事前準備として、Web ACLの設定。 「IP sets」をクリック。 「Create IP set」をクリック。 任意名称を設定。リージョンにCloudFrontを選択。IPv4を選択。対象のIPアドレスを設定。 → 「Create IP set」をクリック。 作成されたIP設定をクリック。 IP設定の詳細を確認できます。 「Web ACLs」をクリック → 対象のWeb ACLをクリック。 「Rules」をクリック → 「Add rules」をクリック → 「Add my own rules and rule groups」をクリック。 IP setを選択。任意名称を設定。IP setに設定したIP設定を選択。Source IP addressを選択。ActionはAllowを設定 → 「Add rule」をクリック。 「Save」をクリック。 Rulesに設定されたのを確認できます。次にデフォルトルールの「Edit」をクリック。 Default actionはBlockを選択。Response codeは403を設定 → 「Save」をクリック。 設定されてるかを確認します。 設定したIPからURLにアクセスするとWebSiteが表示されます。指定IP以外はWebSiteが表示されません。 Basic認証公開 AWS WAFでBasic認証で公開する方法です。 ↓ 参考にさせて頂きました。 AWS WAFだけで、Basic認証を設定してみた 事前準備として、Web ACLの設定。 「Web ACLs」をクリック → 対象のWeb ACLをクリック。 「Rules」をクリック → 「Add rules」をクリック → 「Add my own rules and rule groups」をクリック。 Rule builderを選択。任意名称を設定。タイプはRegular ruleを選択。Statementはキャプチャ内容で設定。String to matchにはユーザー名とパスワードをbase64で変換した値を格納。ActionはBlockを設定。Custom responseはキャプチャ内容で設定 → 「Add rule」をクリック。 「Save」をクリック。 作成されたルールをクリック。 ルールの詳細を確認できます。 URLにアクセスするとユーザーとパスワードの入力画面が表示されます。 設定したユーザーとパスワードを入力するとWebSiteが表示されます。 リクエスト制限 AWS WAFでリクエスト制限する方法です。 事前準備として、Web ACLの設定。 「Web ACLs」をクリック → 対象のWeb ACLをクリック。 「Rules」をクリック → 「Add rules」をクリック → 「Add my own rules and rule groups」をクリック。 Rule builderを選択。任意名称を設定。タイプはRate-based ruleを選択。Request rate detailsはRate limitを今回は100で設定。ActionはBlockを設定 → 「Add rule」をクリック。 「Save」をクリック。 作成されたルールをクリック。 ルールの詳細を確認できます。 5分以内に100回以上動的にアクセスしてみます。 5分間に指定回数以上アクセスがあるとブロックされます。指定回数以下になるとアクセスが可能になります。 AWS WAFを利用することで、Amazon CloudFrontと組み合わせた公開や、今回試したIP制限・Basic認証・リクエスト制限以外にもさまざまな設定が可能です 次回は、Amazon Route 53も組み合わせた方法も紹介できたらと思います。 AWS WAFとAmazon CloudFrontについて、他にも記事を書いています。よろしければぜひ tags - AWS WAF tags - Amazon CloudFront やってみたシリーズ tags - Try
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

面倒なEC2インスタンスssh接続を超速で行えるようにした

目的 ec2のインスタンスにログインする時に、特に久しぶりだとコマンドを忘れたり、覚えていてもパブリックDNS探すのが面倒だったり、そもそもこの長いコマンドを打つのが嫌だった。。。 $ ssh -i <key_name> ec2-user@<Public_DNS> まさかこれを簡単にする方法があるとは知らなかった。 前提 EC2インスタンスを起動済み ElasticIPをそのインスタンスにアタッチ済み 概要 .sshディレクトリ を作成し、権限を付与する $ mkdir ~/.ssh # 所有者に全ての権限を与える $ chmod 700 ~/.ssh key.pemを.sshディレクトリに移動し、権限を付与する EC2インスタンス起動時にダウンロードした自分のキーをkey.pemに置き換えること。 所有者にread権限のみ与える。 $ mv key.pem ~/.ssh $ chmod 400 ~/.ssh/key.pem configにSSH接続情報を登録しておく configファイルがsshディレクトリ以下になければ作成する $ touch ~/.ssh/config $ vi ~/.ssh/config ~/.ssh/config host ec2_login HostName <PublicDNS> Port 22 User ec2-user IdentityFile ~/.ssh/key.pem HostNameにはインスタンス詳細に記載の自分ものを。 Userはいつもsshする時に使うUser名。 IdentityFileは前述で移動したkeyを。 configファイルの権限 所有者のみread/write権限を与える $ chmod 600 ~/.ssh/config ssh接続してみる $ ssh ec2_ec2_user Last login: Sun Jan 30 21:56:11 2022 from softbank219059166010.bbtec.net __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ できた!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon Forecastを試してみる

Amazon Forecastとは Amazon Forecastは、機械学習を使用して精度の高い予測を行う完全マネージド型のサービス 検証データ内容 日別の予約数(っぽいもの)を記録したCSVを作成し、Forecastに読み込ませて予測を行ってみる 作成したCSVはS3においておく 項目は店舗ID、予約日付、予約数 2020/11/1から2020/1/31までの3ヶ月分のデータ(92行) 土日祝日は予約数多め、平日だと比較的火曜日が多い。予約数は増加傾向を示している。というデータとなっている このデータを使って2月の予約数の予測を算出してもらおう 検証データ項目 item_id Forecastで必須の項目 ディメンション(○○別に見るといった分析軸を示すもの 店舗IDを当てはめる timestamp Forecastで必須の項目 時間軸を示す yyyy-MM-dd(日単位) 予約日付を当てはめる target_value Forecastで必須の項目 予約数を当てはめる AWSマネジメントコンソールからForecastを試す 操作方法 Amazon Forecastを開く 「View dataset groups」ボタンをクリック 「Create dataset group」ボタンをクリック 以下項目を入力 Dataset group name 英数字&アンダースコアで適当に入力する(例:forecast_sample) Forecasting domain 予測する種類の設定 https://docs.aws.amazon.com/forecast/latest/dg/howitworks-domains-ds-types.html テンプレートが用意されている Custom Domainを選択する(RETAIL Domainでも良かったかもしれない) 「NEXT」ボタンをクリックする 以下項目を入力 Dataset name 英数字&アンダースコアで適当に入力する(例:forecast_sample_dataset) Frequency of your data 読み込ませるデータの日付の単位 分、時、日、週、月、年から選択 今回は日単位で作成 Schema Builder item_id timestamp yyyy-MM-dd HH:mm:ss / yyyy-MM-ddからフォーマットを選択(yyyy/MM/ddはないので、CSVの形式に注意) target_value ちなみに読み込ませられるデータ型(Attribute Type)は以下が用意されている string(文字列) float(浮動小数点) integer(整数) geolocation(地理データ。USとヨーロッパのみ) Dataset import name 英数字&アンダースコアで適当に入力する(例:forecast_sample_dataset_import) Select time zone timestampがUTC時刻だったら選択すると良いのかも(未検証) Do not use time zoneを選択 Data location CSVデータをおいたS3を選択 IAM role CSVを読み込めるIAMロールを選択。なかったらこの場で自動生成してもらえる 「Start Import」を選択 15分ほど待ち Dashboardが表示されたら、Predictor trainingの「Start」ボタンをクリックして学習の設定を行う 必要ならば、その前にItem metadata dataやRelated time series dataをインポートしておくこともできる(今回は何も入れてない) item metadata data item_idに指定した値の属性情報を読み込ませることができる item_idを店舗IDにするならば、店舗の規模とか、取り扱い商品とか? Related time series data 時系列の属性情報を読み込ませることができる 休日、特売日とか 以下項目を入力 Predictor name 英数字&アンダースコアで適当に入力する(例:forecast_sample_predictor) Forecast horizon 何行先まで予測するか 入力データの1/3まで選択可能(Max:500) 今回2月の予約数を予測したいので、28を設定 Forecast frequency 日単位なのでdayを選択 Algorithm selection 使用するアルゴリズムを選択する とりあえずAutomaticにすればおすすめで予測してもらえる Manualの場合は以下から選択 CNN-QR DeepAR+ Prophet NPTS ARIMA ETS Forecast dimensions 店舗別に予測を出したいならitem_idを選択する? Number of backtest windows、Backtest window offset 学習する際にテストデータを分割するかどうかみたいな よくわからんのでデフォルトのままで Forecast type よくわからないのでデフォで advanced configuration 高度な設定。無視で Weather AWSが持ってる天気情報(2週間分)を学習に含めるか geolocation型をデータに持っている場合に使用可能(つまりUSかヨーロッパ限定の機能) Holiday AWSが持ってる祝日情報を学習に含めるか 日本も選択できるのでOnにしてみる 「Train predictor」ボタンをクリックして学習開始 2時間くらい待つ Dashboardに戻って、Forecast generationの「Start」をクリックして予測の設定を行う 以下項目を入力 Forecast name 英数字&アンダースコアで適当に入力する(例:forecast_sample_forecast) Predictor 先程作成したPredictorを選択 Forecast types 空欄で 「Create new forecast」ボタンをクリックして予測開始 30分くらい待つ 「Lookup forecast」ボタンをクリックする 以下項目を入力 Forecast 先程作成したForecastを選択 Start date 結果グラフの開始日付 予測したデータ行分だけ過去日付を指定可能 今回は予測開始日付の2/1から28日前までを指定可能(つまり1月4日) End date 結果グラフの終了日付 2/28まで予測するのでこれを指定 Choose the keys you want to use to filter your forecasts 店舗別に予測するようにしたので、表示する店舗IDを入力 「Get Forecast」ボタンをクリックして結果を表示 どや 結果考察 土日の予約数が多いってのは反映されている 平日は火曜日が多いってのも反映されている だんだん予約数が増加傾向にあることもでている 祝日が多いってのは無視されている(2/11が少ない予測になっている) 所感 日時の単位が分、時、日、週単位なので、30分単位での予測とかは用意されていない 分単位を選択してがんばればできなかないが、それだと最大500行(8時間ちょい)までの予測しかできない 祝日多いのが反映できていないのはAWSが用意しているHolidayデータがおかしいのでは? 読み込ませているデータは↓みたい http://jollyday.sourceforge.net/data/jp.html 振替休日考慮されてないじゃん! 93行ぽっちのデータでもデータインポート>学習>予測で3時間くらいかかる。実データでやろうとするならば、読み込ませるデータ数でどれくらい時間がかかるか注意する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Organizations 内のアカウントリストを組織構造と一緒に csv 出力する

はじめに AWS Organizations でマルチアカウント管理していると、アカウントの一覧を定期的に取得したいときはありませんか? アカウント情報だけではなく、所属する OU の情報も一緒に出力する方法を紹介します。 実はコンソールから csv をダウンロードできる コンソール上でも通知が出ているように、最近組織内のアカウントリストを csv 出力することができるようになりました。アクションから「アカウントリストをエクスポート」でダウンロード可能です。 これはこれでとても便利なのですが、2022年1月時点では以下の問題があります。 コンソールからしかダウンロードできない AWS CLI や SDK 経由でダウンロードができないため、定期的に取得したいといったケースでは自動化が困難です。以下のドキュメントに記載があります。 The only way to export the .csv file with account details is by using the AWS Management Console. You can't export the account list .csv file using the AWS CLI. 取得できる情報が限られている csv には以下の情報が含まれますが、OU など組織構造の情報は取得できません。 Account ID ARN Email Name Status Joined method Joined timestamp そのため AWS Lambda で Organizations の API を叩いて、OU 情報を含むアカウントリストを出力できるようにしました。 EventBrdige & Lambda でアカウントリストを自動更新 そのアカウントが所属する OU ID と、親 OU を含む OU 名を出力します。例えば以下のような出力になります。 accounts.csv Id,Name,Email,Status,Joined Method,Joined Timestamp,OU Id,1st Level OU,2nd Level OU,3rd Level OU,4th Level OU,5th Level OU 000000000000,account-mgmt,account+mgmt@example.com,ACTIVE,INVITED,2022-01-31 07:19:57,r-xxxx 111111111111,account-0001,account+0001@example.com,ACTIVE,INVITED,2022-01-31 07:25:38,ou-xxxx-yyyyyyyy,Suspended 222222222222,account-0002,account+0002@example.com,ACTIVE,CREATED,2022-01-31 07:31:28,ou-xxxx-zzzzzzzz,Sample System,Additional,Workloads,Prod 333333333333,account-0003,account+0003@example.com,ACTIVE,CREATED,2022-01-31 08:15:49,ou-xxxx-zzzzzzzz,Sample System,Additional,Workloads,SDLC 444444444444,account-0004,account+0004@example.com,ACTIVE,CREATED,2022-01-31 09:18:50,ou-xxxx-zzzzzzzz,Sample System,Foundational,Security,Prod 555555555555,account-0005,account+0005@example.com,ACTIVE,CREATED,2022-01-31 10:21:30,ou-xxxx-zzzzzzzz,Sample System,Foundational,Infrastructure,Prod 666666666666,account-0006,account+0006@example.com,ACTIVE,CREATED,2022-01-31 11:21:05,ou-xxxx-zzzzzzzz,Sample System,Foundational,Infrastructure,SDLC EventBrdige には以下のルールを登録しておき、アカウント作成時に Lambda 関数が起動するようにします。 { "detail-type": ["AWS API Call via CloudTrail"], "source": ["aws.organizations"], "detail": { "eventSource": ["organizations.amazonaws.com"], "eventName": ["CreateAccount"] } } Lambda 関数のコードは以下です。 ListChildren API を再帰処理し、組織内の OU リストを作成 リスト内の各 OU に対し以下を実行 ListParents API を再起処理し、自 OU と上位 OU の名前を取得 ListAccountsForParent API で OU に所属するアカウントの情報を取得し、レコード追加 csv ファイルを書き出し、環境変数 BUCKET で指定した S3 バケットにアップロード というのがざっくりな処理の流れです。もう少し簡潔に書けそうな気がするのですが、かなり長くなってしまいました。 lambda_function.py """ AWS Organizations list accounts Environment variables: BUCKET: S3 Bucket Name """ from logging import getLogger, INFO import csv import operator import os from botocore.exceptions import ClientError import boto3 logger = getLogger() logger.setLevel(INFO) def upload_s3(output, key, bucket): """Upload csv to S3""" try: s3_resource = boto3.resource('s3') s3_bucket = s3_resource.Bucket(bucket) s3_bucket.upload_file(output, key, ExtraArgs={'ACL': 'bucket-owner-full-control'}) except ClientError as err: logger.error(err.response['Error']['Message']) raise def get_ou_ids(org, parent_id): """Recursively process list_children to create a list of OUs.""" ou_ids = [] try: paginator = org.get_paginator('list_children') iterator = paginator.paginate( ParentId=parent_id, ChildType='ORGANIZATIONAL_UNIT' ) for page in iterator: for ou in page['Children']: ou_ids.append(ou['Id']) ou_ids.extend(get_ou_ids(org, ou['Id'])) except ClientError as err: logger.error(err.response['Error']['Message']) raise else: return ou_ids def get_ou_name(org, ou_id): """Return OU name""" try: ou_info = org.describe_organizational_unit(OrganizationalUnitId=ou_id) except ClientError as err: logger.error(err.response['Error']['Message']) raise else: return ou_info['OrganizationalUnit']['Name'] def get_ou_structure(org, child_id): """Recursively process list_parents and return the OU structure.""" ou_structure = [] try: parent_ou = org.list_parents(ChildId=child_id)['Parents'][0] if parent_ou['Id'][:2] == 'ou': ou_structure.append(get_ou_name(org, parent_ou['Id'])) ou_structure.extend(get_ou_structure(org, parent_ou['Id'])) except ClientError as err: logger.error(err.response['Error']['Message']) raise else: return ou_structure def list_accounts(): """Create accounts list""" org = boto3.client('organizations') accounts = [] ou_structure = [] try: root_id = org.list_roots()['Roots'][0]['Id'] ou_id_list = [root_id] ou_id_list.extend(get_ou_ids(org, root_id)) for ou_id in ou_id_list: if ou_id[:2] == 'ou': ou_structure = get_ou_structure(org, ou_id) ou_structure.reverse() ou_structure.append(get_ou_name(org, ou_id)) paginator = org.get_paginator('list_accounts_for_parent') page_iterator = paginator.paginate(ParentId=ou_id) for page in page_iterator: for account in page['Accounts']: item = [ account['Id'], account['Name'], account['Email'], account['Status'], account['JoinedMethod'], account['JoinedTimestamp'].strftime('%Y-%m-%d %H:%M:%S'), ou_id, ] accounts.append(item + ou_structure) except ClientError as err: logger.error(err.response['Error']['Message']) raise else: return sorted(accounts, key=operator.itemgetter(5)) def lambda_handler(event, context): """Lambda function to output the list of accounts in AWS organization in CSV format.""" key = 'accounts.csv' output_file = '/tmp/accounts.csv' bucket = os.environ['BUCKET'] header = [[ 'Account Id', 'Account Name', 'Account Email', 'Account Status', 'Joined Method', 'Joined Timestamp', 'OU Id', '1st Level OU', '2nd Level OU', '3rd Level OU', '4th Level OU', '5th Level OU' ]] account_list = list_accounts() with open(output_file, 'w', newline='', encoding='utf-8') as output: writer = csv.writer(output) writer.writerows(header) writer.writerows(account_list) upload_s3(output_file, key, bucket) IAM ロールには以下のようなポリシーをアタッチします。 iam_policy.json { "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:PutObject" ], "Resource": [ "arn:aws:s3:::<your_bucket_name>/*" ], "Effect": "Allow" }, { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "organizations:DescribeOrganizationalUnit", "organizations:ListAccountsForParent", "organizations:ListChildren", "organizations:ListParents", "organizations:ListRoots" ], "Resource": "*", "Effect": "Allow" } ] } 以上です。 参考になれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む