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

【YouTube配信】「30分でわかる AWS UPDATE!」第13回を配信しました!

$
0
0

こんにちは、技術1課の山中です。
1週間で発表されたAWS UPDATEの中から、サーバーワークスのエンジニアが気になったトピックをピックアップして解説する「30分でわかる AWS UPDATE!」

今回もフルリモートで、教育事業を担っている加藤、小倉、山中に加えゲストの渡辺も加えて配信を行いました。

そんな第13回の模様はこちら。

今回ご紹介したアップデートは以下です!

他の動画も見てみたい!

こちらのプレイリストからAWS UPDATEをまとめてチェックできます!
30分でわかる AWS UPDATE! | プレイリスト
「なぜ」「誰が」この放送を始めたのか、というお話を別記事にてまとめております。あわせてご覧ください。
【YouTube配信】「30分でわかる AWS UPDATE!」の配信を開始!

今後の配信

次回配信は 6/10(水) 12:00〜となります。

次回もフルリモートでの配信となります。
またこれからは、アップデート内容によってどんどん社内エンジニアにも出演いただき、熱量高く語ってもらうかと思っていますので、ぜひぜひご覧ください!

チャンネル登録もよろしくお願いします!

週中だし、お昼。
見たいけど見落としちゃいそう…というそこのあなた!
こちらから、ぜひチャンネル登録・通知設定をどうぞ!
サーバーワークスチャンネル


【入門編】ネットワーク障害時の問題の切り分けについて

$
0
0

CI5課の山﨑です。今回は入門編としてネットワーク障害の一次切り分けについて簡単にまとめていきたいと思います。

構成図

今回は上記構成図のオンプレミスとAWSのホスト間で通信が不可になった際にどのようにして問題を切り分けていくのか簡単にまとめていきたいと思います。

問題が発生しているレイヤーの特定

pingによる疎通確認が初めの一歩

まずはpingで疎通確認をします。pingでICMPパケットを送信して疎通確認を取ることができれば、原因はLayer4以上のいずれかにあることが分かります。反対にpingで疎通確認を取ることができなければ、原因はLayer3以下のいずれかにあることが分かります。

pingによる疎通確認が取れた場合

AWS側ではホストに関連付けているセキュリティグループの設定で適切なポートならびにSourceからのInboundトラフィックを許可しているかどうかを確認します。合わせてOutboundトラフィックが許可されているかどうかも確認します。 オンプレミス側ではファイアウォールの設定でトラフィックが許可されているか等を確認します。それぞれ正しく設定されていれば、問題はさらに上位のLayerに存在するはずだと考えて上位Layerに向かって原因を調査していきます。

pingによる疎通確認が取れなかった場合

AWS側ではサブネットに関連付けをしているルートテーブルのルートが正しく設定されているか、ネットワークACLで適切なルールを設定しているかを確認します。これらに問題がなければオンプレミス側のホストからtraceroute(tracert)コマンドをAWSのホストのIPアドレスに対して実行し、通信が遮断されているのかルーターを特定します。コマンドを実行する際はAWS側のホストから実行するのか、オンプレミス側のホストから実行するのかは状況に応じて判断していきます。 通信が遮断されているルーターを特定することができたら当該ルーターのルートテーブルを確認して、オンプレミス – AWS間の通信を制御しているルート設定がないかを確認して設定を修正します。それでも問題が解決しない場合はさらに下位のLayerに向かって原因を調査していきます。

まとめ

ネットワーク障害時のトラブルシューティングには様々な方法があり、発生しているトラブルによってどのような方法を選択するかが変わってくると思いますが、問題を大きく切り分ける第一歩としてpingによる疎通確認をする。そして状況に応じて上位Layer、下位Layerに向かって1つずつ問題の所在を明らかにしていくというプロセスを踏むことは大切なことではないかと思います。

AD Connector利用でWorkSpacesを使う時に必要なActive Directoryの通信要件

$
0
0

鎌田です。
昨今の事情もあり、在宅ワークのために急いでWorkSpacesをご用意されている方も多いのではないでしょうか。

WorkSpacesを既存のActive Directoryドメインで運用される際、AD Connectorを使った構成をされるかと思うのですが、Active Directory側で許可しておく必要があるポートについて、少々分かりづらいのでこちらのブログでご案内します。

AD Connectorの通信要件

AWSドキュメントでは、こちらのページに記載があります。
整理しますと、次の通りとなります。
Active Directory側で、AD Connectorからの通信で、TCP/UDPすべて合わせて6つの通信の許可が必要です。

プロトコル ポート番号 タイプ
TCP 53 DNS
UDP 53 DNS
TCP 88 Kerberos
UDP 88 Kerberos
TCP 389 LDAP
UDP 389 LDAP

AD Connectorがきちんと構成できていれば、WorkSpacesのディレクトリの画面で、ステータスがActiveになっていると思います。

ここまで出来たらあとはWorkSpacesを作れば・・・と思いたいのですが、この状況でWorkSpacesを作っても、WorkSpacesがドメインに参加できないというエラーになってしまいます。
エラーメッセージとして、以下のようなメッセージが表示されます。

There was an issue joining the WorkSpace to your domain.
Verify that your service account is allowed to complete domain join operations.
If you continue to see an issue, contact AWS Support.

なぜなのでしょうか。

WorkSpacesの通信要件

WorkSpacesのドキュメントの記載を見ると、AD Connectorで指定されているよりも多いポートが、Active Directory側で許可する必要があります。
整理しますと、次の通りとなります。

プロトコル ポート番号 タイプ
TCP 53 DNS
UDP 53 DNS
TCP 88 Kerberos
UDP 88 Kerberos
UDP 123 NTP
TCP 135 RPC
UDP 137-138 Netlogon
TCP 139 Netlogon
TCP 389 LDAP
UDP 389 LDAP
TCP 445 SMB
UDP 445 SMB
TCP 1024-65535 Dynamic ports for RPC

ユーザー情報の参照や、ドメインの情報を探すのみであれば、DNSやKerberos、LDAPといったポートだけで事足りるのですが、
ドメイン参加となった場合、NTPによる時刻同期が行われるなど、認証以外のポートも使うため、許可が必要なポートが増えてきます。

ルールが多くなりますが、忘れずに許可するようにしてください。

まとめ

  • AD ConnectorでWorkSpacesを利用するケースでは、WorkSpacesのドキュメントに記載のあるポートを、Active Directory側で許可が必要
  • これを実施しておかないと、WorkSpacesがドメイン参加できずにエラーになってしまうので注意

少々分かりづらい点なので、ブログでご紹介させていただきました。
どなたかの助けになれば幸いです。

【入門】Savings Plansを購入してみた

$
0
0

室内の酸素濃度が低下気味にあるCI部の柿﨑です。
エアコンをつけっぱなしにするだけではなく、部屋の換気も忘れずにした方が良いことを最近学びました。
参考情報

弊社では社員一人ひとりに検証用のAWSアカウントが割り当てられていますが、今回は個人的に所有しているAWSアカウントにて、Savings Plans(以下、SP)を購入したため、シンプルに一連の流れをブログ化します。

Savings Plansの詳細な説明については、以下の記事に詳しく記載されておりますので、是非ご確認ください。

Savings Plans はどのように適用されるのか?

Savings Plansを購入

私のAWSアカウントでは以下のように「t3.small」のwebサーバーが1台稼働しております。
今のところ稼働率は100%となっており、コスト削減とサービスを1年継続させることを目標としてSavings Plans(以下、SP)を購入することとしました。
上記の状態でEC2にかかっているコストは、0.65 USD/日です。
2020/06/04時点でドル円が109円のため、0.65 USD * 109 円 * 365 日 = 約 25,860 円/年の費用がかかる見込みです。
SPにはrecommend機能があり、そこで購入量を確認できます。
しかし、今回はサーバーを構築してあまり日数が経過していないため、recommend機能が使えません。
そのため、AWSの新しいCalculatorを使ってSPの購入量を確認します。
※SPが各インスタンスタイプに対してどのように割引きされるのかを確認するだけであれば、料金ページが早いです。

まずはAWSコンソール上で確認した現在のコストが正しいのかどうか、念のために確認してみます。
稼働率100%の「t3.small」のオンデマンドが1台のため、以下のようになります。


1時間あたりの料金がでましたので、0.0272 USD * 24 時間 = 0.6528 USDとなりましたのでAWSコンソール上の料金と合致していますね。

続いて、SPの料金を確認してみます。
今回は、割引き率の高いEC2 Instance Savings Plansを1年間の全額前払いで購入します。
理由はEC2インスタンスを東京リージョン且つt3ファミリー固定で問題ないこと、提供するサービスを3年続けるかまでは怪しいため今回は1年として、割引き率の高い全額前払いとしました。

上記の計算の結果、SPの1時間あたりの料金が以下のように確認できます。

SPでは1時間あたりの使用料をコミットすることでAWS利用料が割引きされるのですが、このコミットする金額はSPによって割引きされた後の金額となります。
今回の例であれば「0.016 USD」をコミットすれば、対象となるEC2インスタンスの利用料金を割引きすることができます。
1年間の利用料は140.16 USDとなりますので、日本円に換算すると140.16 USD * 109 円 = 約15,277 円/年になることが分かります。
オンデマンドの料金が約 25,860 円/年でしたので、約10,583 円/年お得ですね♪

SPの購入量が判明しましたので、SPを購入します。
まずはCost Explorerへ移動します。
SPの購入を押下。
以下のように購入内容を選択します。
「時間単位のコミットメント」が先ほど試算したSPの1時間あたりの料金となります。
前払いコストが事前に試算した額と一致していることを確認して、カートに追加を押下します。
カートの中身に間違いがないことを確認して、注文書の送信を押下します。
※基本的にはここで注文が確定されるため、注意して操作してください。
正常に処理が完了されると以下の画面が表示されます。
※場合によってはお支払いが完了せず、追加アクションが発生するようです。(今回はなし)
購入したSPを確認してみます。
インベントリを押下。
すると以下のように購入済みのSPを確認できます。
Savings Plan IDを押下することで、以下の画面も確認できます。
SPの利用状況がAWSコンソールに反映されるまでに少し時間がかかります。
後日確認したところ、SPを購入した6/1を境にEC2インスタンスの料金が0.00 USD /日となっていました。
これだけではコミットした金額が実際の利用料金に対してオーバーしている可能性もありますので、SPの使用状況も確認します。
Cost Explorerから使用状況レポートを押下。
以下のとおり、使用率が100%となっていますのでSPでコミットした金額を余りなく適用できているようです。

さいごに

今回は個人的にSPを購入しましたが、t3規模のインスタンスであれば2万円も出せば1年間はお得に利用できることが分かりました。
EC2 1台分(稼働率100%)の購入だけでも年間で1万円ほどお得になりましたので、個人的にEC2を稼働させている方はぜひSPの購入も視野に入れてみてはどうでしょうか。

AWS Direct Connectでフェイルオーバーテストできるようになりました

$
0
0

2020年6月3日のアップデートでDirect Connectのフェイルオーバーテストが可能になりました。
AWSとオンプレミスの接続をする時にはDirect Connectが用いられますが、障害対策として、2本の接続を利用することもよくあります。
1本で障害が起きても、もう1本あるから大丈夫。。。大丈夫なはず。。。テストしたい。。。
それが実現できるようになりました。

やってみた

たまたま手元にDirect Connectの冗長構成があったので、やってみました。

準備

効果測定のためにEC2インスタンスから、Direct Connect経由のサーバに対し、pingを打ち続けます。

ubuntu@ip-10-0-0-10:~$ ping -s 1472 172.16.0.10
PING 172.16.0.10 (172.16.0.10) 1472(1500) bytes of data.
1480 bytes from 172.16.0.10: icmp_seq=1 ttl=58 time=78.3 ms
1480 bytes from 172.16.0.10: icmp_seq=2 ttl=58 time=78.2 ms
1480 bytes from 172.16.0.10: icmp_seq=3 ttl=58 time=78.2 ms

そして、CloudWatchメトリクスでVIFのトラフィックを確認します。
2つのVIFのそれぞれにEgressとIngressがありますが、実際にトラフィックが流れているのは1つのVIFだけであることが確認できます。

フェイルオーバーテストの実行

VIF1つ目をDownさせてみる

VIFを一つ選択し、アクション > フェイルオーバーテスト > BGPを停止させる をクリックします。

テストでダウンさせる時間を1分〜180分の間で指定します。
今回は10分にしてみました。
確認するをクリックするとテストが開始されます。

VIFの状態がtestingになります。

テスト開始後もしばらくはBGPステータスがupになります。

しばらくすると、BGPステータスがdownになり、VIFのステータスもdownになります。

CloudWatchを見ると、トラフィックが流れるVIFが変わったことが確認できます。
なお、Ingressしかフェイルオーバーしなかったのですが、非対称ルートになっていたのが原因のようです。

指定した10分を経過すると復旧してきます。

VIF2つ目をDownさせてみる

2つのVIFのどちらで障害が起きてもトラフィックに問題ないかを確認したかったので、もう一つのVIFもDownさせてみます。

今回はテスト時間を20分にしてみました。

20分経過後にフェイルバック(経路の切り戻し)が自動的に行われました。
今回はきちんと調べてないですが、対向ルータの設定やBGPパラメータ等が原因なのだろうと思います。

ping結果

1480 bytes from 172.16.0.10: icmp_seq=7384 ttl=58 time=79.3 ms
1480 bytes from 172.16.0.10: icmp_seq=7385 ttl=58 time=78.2 ms
1480 bytes from 172.16.0.10: icmp_seq=7386 ttl=58 time=78.2 ms
1480 bytes from 172.16.0.10: icmp_seq=7387 ttl=58 time=78.2 ms
^C
--- 172.16.0.10 ping statistics ---
7387 packets transmitted, 7377 received, 0% packet loss, time 7396236ms
rtt min/avg/max/mdev = 61.058/79.008/101.443/1.734 ms

パケットロスは7387の中で10パケットだけロスしてますね。
(1%未満なので0% packet lossと表示)
明確にどのタイミングでロスが発生したかは確認しませんでしたが、本記事に書いたのも含め、フェイルオーバーテストを合計4回しているので、それでこれなら優秀なのではないでしょうか。
なんにしても、障害時の挙動を概ね把握でき、だいぶ安心できるようになりました。

テスト履歴

VIFの画面でフェイルオーバーテストの履歴が見れるようになっていました。

まとめ

Direct Connectの冗長構成で、片方のVIFのBGP停止させるテストが可能になりました。
それによって、片系障害時にどのようなトラフィックになるのかを確認できるようになりました。
また、障害復旧時にフェイルバックが起きるかどうかも確認ができました。

いろいろとテストができるようになったので、今後はDirect Connectの冗長化に関するテスト計画も作成すると良さそうと感じました。

[Docker入門]コンテナ同士の連携:ネットワークとボリューム

$
0
0

はじめに

こんにちは。孔子の80代目子孫兼技術5課の孔です。もう6月になりましたね。夏になってきて暑い日々が続いてるので、健康にも気をつけてくださいね。

前回のブログではDockerの使い方を簡単にみてみました。コマンドの仕組みのイメージがつかめたらいいかと思います。今回の話ではDockerのネットワークとボリュームについて解説します。ネットワークは、Dockerのコンテナ同士がどのようにやりとりをするのか、またホストIPをどのように経由して外部とつながるのかについて説明していきます。ボリュームは、Dockerのコンテナが共有する共通ボリュームについて説明します。

それでは、みてみましょう。Let’s check it out!

Dockerにおいてのネットワーク

Dockerのネットワーク機能は、コンテナのネットワークを構成、管理するものとなります。仮想ネットワークをDockerで作成し、それぞれのネットワークにコンテナを配置することによって簡単にネットワークを構成することが可能になります。

もう少し具体的な話をするために、まずDockerのネットワーク一覧をみてみましょう表示するコマンドはdocker network lsとなります。

kong@KongnoAir docker % docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
1c3d5534f8f6        bridge              bridge              local
3593069c284a        host                host                local
2d216a540abf        none                null                local

setn8dok5ho1以外のネットワークは全てデフォルトで入っているネットワークとなります。上記のシェルでNone, Host, Bridgeという単語がありますが、この三つはDockerをインストールした際にデフォルトでインストールされるネットワークとなります。それぞれのネットワーク上にコンテナを作成しながら特徴をみていきましょう。特定のネットワークにコンテナを作成するコマンドはdocker container run –net={ネットワーク名}となります。

Noneとは

Noneネットワークは、外部とも、そしてどのコンテナともつながらないネットワークを意味します。ローカル内で処理を完結したいコンテナはNoneネットワークに作成します。

kong@KongnoAir docker % docker run -it --net=none busybox sh
/ # ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

このように、Noneのネットワーク上に作成したコンテナはローカルネットワークしか存在してないことがわかります。他のコンテナとも、外部とも通信ができない状態です。

Hostとは

Hostネットワークは、ホストマシンとネットワークインターフェースを共有するネットワークとなります。コンテナのネットワークの設定をホストと一緒にしたい時に使います。ホストマシンのポートとコンテナのポートがマッピングされるため、コンテナでは80ポートをホストマシンの8080ポートをマッピングするようなことはできません。

Bridgeとは

Bridgeネットワークは、Dockerのコンテナ用の内部ネットワークを作成し、そのネットワークで仮想ネットワークインターフェースを作成してホストと通信のやりとりをするネットワークとなります。

bridge3

こちらの図をみていただくと、ホストマシンのネットワークインターフェースであるeth0と二つのBridgeがつながってます。それぞれのBridgeにコンテナは繋がり、このBridgeを経由してホストマシンとやりとりをします。Dockerをインストールし、ネットワークの接続状況を確認してみるとdocker0というアダプターができたのがわかります。

kong@KongnoAir docker % ifconfig docker0
docker0   Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:a2ff:fe10:ccf7/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:30 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:480 (480.0 B)  TX bytes:5025 (5.0 KB)

このアダプターを経由してDockerのBridgeネットワークとやりとりをしています。ちなみに、コンテナを作成する際にネットワークを指定しないとデフォルトのBridgeネットワークにアタッチされるような設定がされています。

補足:awsvpc

こちらはAWSのECSの話になりますので、興味がなければスキップで大丈夫です。ECSのタスクを定義する際にネットワークモード指定しますが、その中に上記の3つ意外にawsvpcというものが紛れ込んでます。

これはECS特有のもので、ECSクラスター上で作成される全てのタスクに固有のENIを付与するものとなります。ENIを一つ一つのタスクに付与することでSGをタスクごとに割り当てることができ、より細部までセキュリティ対策ができる仕組みになっています。より詳しい内容はドキュメントを参考にしてください。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-networking.html

Dokcerボリュームとは

Dockerボリュームは、コンテナ同士で同じマウントポイントを参照できる機能となります。コンテナが共通して使用するファイルがあればボリュームを作成し、コンテナがこちらのボリュームにマウントして使用することが可能になります。

イメージ、コンテナ、ストレージ・ドライバについて — Docker-docs-ja ...

例えば、DBMS(例えばMySQL)のコンテナを作成するとします。もしコンテナを作成し、そのコンテナの中にデータを保存していくと、コンテナに不具合が起きて新しいコンテナを作成しなければならない時にとても大変なことになります。せっかく簡単に環境を作成して消せるのがメリットであるDockerの良さをいかせてないですね。そのような時はデータベースが取り扱うデータをホストに保存し、コンテナで作成したDBMSはそこにマウントしておけば問題なく使えます。

さらに大事なことは、Dockerの思想に関することです。Dockerは思想として、コンテナはただのプロセスであるので一時的なものであり、その中身に差がないようなことが起きてはならないという考え方で作られました。まさにこのボリュームがその考え方を代弁するものとなりますね。

ボリュームを種類には2種類あり、Dockerデーモンがボリュームを作成してコンテナ同士で共有するスペースを作成するVolumesとホストのファイルシステム上にコンテナをマウントするBind Mountがあります。

volumes on the Docker host

それぞれ詳細をみてみましょう。

Volumes

Dockerデーモンがスペースを作成し、それをコンテナ同士で共有するやり方となります。作り方はdocker volume create {ボリューム名}で作成でき、こちらにコンテナをマウントする時はdocker container run -v {ボリューム名}/:{コンテナのパス}でマウントすることができます。

kong@KongnoAir docker % docker volume create test  // testという名のボリューム作成
test
kong@KongnoAir docker % docker volume ls
DRIVER              VOLUME NAME
local               test
kong@KongnoAir docker % docker container run -it -v test:/test busybox sh  // busyboxのshを起動します
/ # ls
bin   dev   etc   home  proc  root  sys   test  tmp   usr   var
/ # cd test
/test # ls  // 何もない状態
/test # echo "hello from volume!!" >> hello.txt
/test # ls
hello.txt
/test # cat hello.txt 
hello from volume!!
/test # exit
kong@KongnoAir docker % docker container run -it -v test:/test busybox sh  // 新しいコンテナを作成
/ # ls
bin   dev   etc   home  proc  root  sys   test  tmp   usr   var
/ # cd test/
/test # ls
hello.txt  // 先のコンテナで作成したファイルを確認できます
/test # cat hello.txt 
hello from volume!!

Bind mount

Bind mountは、ホストのファイルシステム上にコンテナをそのままマウントすることを指しています。別途ボリュームを用意する必要はなく、ホストマシンで修正した内容はそのままコンテナにも反映されます。こちらはコンテナを作成する際にdocker container run -v /{ホストのパス}:/{コンテナのパス}で指定可能です。ホストのパスを入力する際にスラッシュが入ってるのが違いですので、忘れずにつけましょう。

kong@KongnoAir ~ % pwd
/Users/kong
kong@KongnoAir ~ % echo "hello from host" >> hello.txt
kong@KongnoAir ~ % cat hello.txt
hello from host
kong@KongnoAir ~ % docker container run -v /Users/kong:/test -it busybox sh
/ # exit
kong@KongnoAir ~ % docker container run -v /Users/kong:/test -it --name bind_mount busybox sh  // bind_mountという名前のコンテナを作成
/ # ls
bin   dev   etc   home  proc  root  sys   test  tmp   usr   var
/ # cd test/
/test # ls
hello.txt  <私のホームディレクトリにある諸々のものは省略します…>
/test # cat hello.txt 
hello from host
/test # exit
kong@KongnoAir ~ % echo "hello from host again" >> hello.txt
kong@KongnoAir ~ % docker container start bind_mount                                                                                                         ~
bind_mount
kong@KongnoAir ~ % docker container exec -it bind_mount sh  // bind_mountという名前のコンテナのshを起動                                                                                                ~
/ # cat test/hello.txt 
hello from host
hello from host again

このように、ホストマシンで加えた修正がコンテナ上にも反映されていることがわかります。

最後に

今回はネットワークとボリュームについてみてみました。どちらもコンテナ同士で連携をする際に必ず必要な知識ですのでぜひ覚えておきましょう。次はオーケストレーションサービスであるswarmについてみてみたいと思います。それでは、お元気で!

【AWS Systems Manager】ランコマンドの実行タイムアウトについて

$
0
0

はじめに

AWS Systems Manager(SSM)の便利な機能にランコマンドがあります。
これはSystems Managerのマネージドインスタンス上でコマンドを実行できるサービスで、OS内に配置されたスクリプト等をAWS API経由で実行することにより運用作業を自動化・効率化できます。

このランコマンドにはタイムアウトの値を設定できますが、実は任意の値を設定出来ないケースがありますので、そのTipsをご紹介したいと思います。

実行タイムアウトについて

ランコマンドにはコマンドの実行タイムアウト(※)があり、指定した時間になってもコマンドの実行が完了しない場合には、コマンド実行が中断されます。

さて、AWSマネジメントコンソールでランコマンドを実行する場合は、コマンドの実行タイムアウトの値は、下記の画面で設定できます。

ただし、このタイムアウトの値はドキュメントにとってのデフォルトのタイムアウト値の位置づけとなっており、実際には適用されないケースがあります。

※ タイムアウトには実行タイムアウトの他に配信タイムアウトがあるのですが、本記事では実行タイムアウトのみを扱います。

コマンドの実行タイムアウト値を設定できるケース

例えば、Linux上で任意のコマンドを実行する AWS-RunShellScript ドキュメントの定義をみてみましょう。
その中の一部で、下記のように "timeoutSeconds": "{{ executionTimeout }}" と定義されています。
この {{ executionTimeout }} 部分でユーザーから入力されたタイムアウト値が代入され、設定されます。

"runtimeConfig": {
    "aws:runShellScript": {
      "properties": [
        {
          "id": "0.aws:runShellScript",
          "runCommand": "{{ commands }}",
          "workingDirectory": "{{ workingDirectory }}",
          "timeoutSeconds": "{{ executionTimeout }}"

コマンドの実行タイムアウト値を設定できないケース

例えば、Windows UpdateをSSM経由で行う AWS-InstallWindowsUpdates ドキュメントの定義をみてみましょう。
その中の一部で、下記のように "timeoutSeconds": "14400", と定義されています。
14400秒すなわち4時間に固定で設定されており、この値が実際のコマンドの実行タイムアウト値として適用されます。

したがって、このSSMドキュメントを実行する場合は、実行時にタイムアウト値を設定したとしても、タイムアウト値は常に4時間ということになります。

"runtimeConfig": {
    "aws:runPowerShellScript": {
      "properties": [
        {
          "id": "0.aws:runPowerShellScript",
          "timeoutSeconds": "14400",

試してみた

実際に試してみました。

環境

  • Amazon Linux2
  • SSMドキュメント
    • AWS-RunShellScript
  • スクリプト
    • 1秒おきにファイルに書き込む。60秒実行する。

#!/bin/bash

for i in `seq 0 60`
do
  echo "i = $i" >> /home/ec2-user/echo.txt
  sleep 1
done

実行時に設定したタイムアウト値でタイムアウトすること

まずはコマンド実行時にタイムアウト値を「30秒」に設定して、上記コマンドをランコマンドで実行してみます。
そうすると、30秒経過した時点で、以下のようにエラーとなりました(画面が途中で切れていますが、 i = 29 で中断されています)。

ドキュメントを変更し、実行時に設定したタイムアウト値でタイムアウトしないこと

SSMドキュメントは自分で定義することもできるので、「AWS-RunShellScript」ドキュメントのタイムアウトの値だけ調整した独自のドキュメントを定義して実行してみます。
今度はドキュメントの中で固定した値を設定しておき、コマンド実行時に指定した値ではタイムアウトしないことを確認してみます。

独自ドキュメントの作成

あらかじめ、「AWS-RunShellScript」ドキュメントの定義JSONをコピーしておきます。

SSMの画面の「ドキュメント」から「Create Command or session」を選択します。

「ドキュメントの作成」画面で以下のように入力し、「コンテンツ」の部分に先程コピーした「AWS-RunShellScript」ドキュメントの定義をペーストします。

そして、”timeoutSeconds” の部分を120秒に設定してみましょう。
こうすることで、コマンド実行時のタイムアウト値の設定によらず、常に120秒がタイムアウト値となります。

本ドキュメントを用いて再度、コマンド実行時にタイムアウト値を30秒に設定して、実行してみます。
今度はコマンドが最後まで実行され、中断されないことが分かります。

おわりに

今回ランコマンドのタイムアウトについてTipsをご紹介しました。
知っていないと案外落とし穴になる部分なので、気をつけて設計したいところです。

AWS Config が新たに 9 つのマネージドルールをサポートしました

$
0
0

はじめに

こんにちは、技術1課の山中です。
もうすぐ梅雨というのもあるせいか、最近は雨の日が多いですね。
そんな日が続くと、たまに来る晴れの日には太陽のありがたさを感じることができます。

というのはさておき!
今回はこのアップデートについて見ていきます!

AWS Config が 9 つの新しいマネージド型ルールをサポート

AWS Config とは

AWS Config はフルマネージド型の構成管理サービスです。

AWS Config(リソースのインベントリと変更の追跡)| AWS

わずか数クリックで、AWS リソースの設定を評価、監査、審査することができるようになります。
AWS Config の概要と料金、セットアップ手順については以下動画にまとめておりますので是非ご覧ください。

AWS Config Rules

AWS Config では AWS のリソースが準拠すべきルールを事前に定義することで、ルールに沿った構成変更が行われているかを評価します。
ルールは AWS によって提供される マネージドルール とユーザが自分で作成 / 管理を行う カスタムルール の 2 つに分かれます。
今回のアップデートで新たに 9 つのマネージドルールが追加されました。

追加されたマネージドルール

今回のアップデートで追加されたルールは以下です。

名前 説明 検査タイミング パラメータ
SNS_ENCRYPTED_KMS SNS トピックを KMS で暗号化されているか 設定変更時 kmsKeyIds
SECURITYHUB_ENABLED Security Hubが有効化されているか 定期的
S3_DEFAULT_ENCRYPTION_KMS S3 バケットが KMS で暗号化されているか 設定変更時 kmsKeyArns
S3_BUCKET_DEFAULT_LOCK_ENABLED S3 バケットでオブジェクトロックがデフォルトで有効になっているか 設定変更時 mode
REDSHIFT_REQUIRE_TLS_SSL Redshift クラスターが SQL クライアントに接続するために TLS/SSL 暗号化を必要としているか 定期的
RDS_SNAPSHOT_ENCRYPTED RDS の DB スナップショットが暗号化されているか 設定変更時
EC2_EBS_ENCRYPTION_BY_DEFAULT EBS 暗号化がデフォルトで有効になっているか 定期的
DYNAMODB_TABLE_ENCRYPTED_KMS DynamoDB テーブルが KMS で暗号化されているか 設定変更時 kmsKeyArns
DYNAMODB_PITR_ENABLED DynamoDB テーブルに対してポイントインタイムリカバリが有効になっているか 設定変更時

おわりに

AWS Config のマネージドルールがこのようにどんどん増えていくと、ユーザとしても簡単に利用できるので、今後ももっと増えていってほしいですね!

また、この内容は 2020/6/10(水) 12:00 よりYouTube Liveで配信する「30分でわかる AWS UPDATE!」で取り上げますますので、是非ご覧ください!

参考


[Amazon Connect]Amazon Connect Streamsで例えばどんなことができるの?

$
0
0

CI部の村上です。思い返せば先週は2回しか外へ出ていない(うち1回はゴミ捨て)ことに気が付いたのですが、なんかもう平気になっている今日この頃です。

さて、以前に「履歴メトリクスでなにができるの?」というブログで、Amazon Connectで構築したコンタクトセンターでは、通話やエージェント(オペレータのこと)の行動が簡単に照会・分析できることを紹介しました。

ただし履歴メトリクスや問い合わせ検索が閲覧できるのは、デフォルトでは管理者などの特定のユーザーに限られています。

基本的にエージェントは、以下のようなソフトフォン(CCP)にアクセスして電話対応を行うのですが、Amazon Connect StreamsというAPIを使えば、CCPを自前のウェブアプリに組み込んでカスタマイズすることが可能です。

Amazon Connect Streamsの設定については、本記事とは別に名著がありますので、そちらをご覧ください。
Amazon Connect Streamsを使ってみよう

この記事は、「Amazon Connect Streamsを体験してみる」をテーマに書いていこうと思います。

まずは初期設定のおさらい

Amazon Connect StreamsはhtmlファイルからJSを読み込んで使用します。Amazon Connect Streamsを使ってみようのブログでも紹介されていますが、最初は下記のようなコードかと思います。

<!DOCTYPE html>
<meta charset="UTF-8">
<html>
    <head>
        <script type="text/javascript" src="amazon-connect-1.4.js"></script>
    </head>
    <!-- Add the call to init() as an onload so it will only run once the page is loaded -->
    <body onload="init()">
        <div id=containerDiv style="width: 400px;height: 800px;"></div>
        <script type="text/javascript">
            const instanceURL = "https://my-instance-domain.awsapps.com/connect/ccp-v2/";
 
            // initialise the streams api
            function init(){
                // initialize the ccp
                connect.core.initCCP(containerDiv, {
                    ccpUrl: instanceURL,            /*REQUIRED*/
                    loginPopup: true,           /*optional, default TRUE*/
                    region: "ap-northeast-1",           /*REQUIRED for chat, optional otherwise*/
                    softphone: {                /*optional*/
                        allowFramedSoftphone: true, /*optional*/
                        disableRingtone: false,     /*optional*/
                        ringtoneUrl: "./ringtone.mp3"   /*optional*/
                    }
                });
            }
        </script>
    </body>
</html>

Amazon Connect Streamsでは、GitHubに載っているAPIからエージェントやコールに関するイベントを取得して、各種メソッドを実行します。

ということで、さわってみる

「まずは簡単なものを実装しよう」と思いながらGitHubをみていると、エージェントイベントの中で、agent.onAfterCallWork()なるものを見つけました。

見てのとおり、エージェントが電話を切ったときに使えるAPIだと分かったので、これを使ってみることにします。

とりあえず、エージェントが電話を終えたら「お疲れ様」とメッセージを出す小粋な計らいをしてみたいと思い、やってみました。

connect.agent(function(agent) {    
    agent.onAfterCallWork(function(agent) { 
        alert("お疲れ様") 
    });
});

出来栄えはこんな感じです。

労われている感が皆無だったので、すぐに消しましたが、やりたかったことはできました。

このようにして、エージェントがお客様からの電話を切ったときに行いたい処理を記述すれば、他にもいろいろなことができそうですね。

着信履歴を表示してみる

つづいてContact APIにあるcontact.onConnected()(通話状態になったときに使うAPI)、contact.onMissed()(通話前に相手が電話を切ったときなどに使うAPI)の2つに注目しました。

というのも、デフォルトのままCCPを使っていると、通話中あるいはアフターコールワークの時にしかお客様の電話番号がCCPに表示されず、ちょっと不便かなと思ったからです。

まずは問い合わせフローの中で、「問い合わせ属性の設定」ブロックを使い、phonenumberというキーでお客様の電話番号を取得します。

次に、着信があった日時を表示するためにDateオブジェクトを書きます。

var now = new Date();
var Year = now.getFullYear();
var Month = now.getMonth()+1;
var Day = now.getDate();
var Hour = now.getHours();
var Min = now.getMinutes();

最後に、contact.onConnected()contact.onMissed()の処理を書きます。コンタクト属性の参照方法はAWSホームページにある「Amazon Connect スクリーンポップに発信者のコンタクト属性を表示するにはどうすればよいですか?」を参考にしました。htmlに<ul>タグを書いておいて、その中に着信履歴が表示されるようにしています。あと、着信履歴の表示にはBootstrapのボタンを使っています。

connect.contact(function(contact) {
    contact.onConnected(function() {
        var attributeMap = contact.getAttributes();
        var phonenumber = JSON.stringify(attributeMap["phonenumber"]["value"]);
        var button = document.createElement("button");
        button.className = "btn btn-primary btn-lg btn-block";
        button.textContent = Year + "年" + Month + "月" + Day + "日" + Hour + ":" + Min + "    通話:" + phonenumber;
        var ul = document.querySelector("ul");
        ul.appendChild(button);
    });

    contact.onMissed(function(contact) {
        var attributeMap = contact.getAttributes();
        var phonenumber = JSON.stringify(attributeMap["phonenumber"]["value"]);
        var button = document.createElement("button");
        button.className = "btn btn-danger btn-lg btn-block";
        button.textContent = Year + "年" + Month + "月" + Day + "日" + Hour + ":" + Min + "    不在着信:" + phonenumber;
        var ul = document.querySelector("ul");
        ul.appendChild(button);
    });
});

出来栄えはこんな感じです。

うまく表示されました。通話状態にすると、contact.onConnected()の処理が実行され青く表示、通話する前に電話を切るとcontact.onMissed()の処理が実行され赤く表示されています。

まとめ

今回はAmazon Connect Streamsを体験してみようをテーマに書いてみました。Amazon Connect Streamsには他にも様々なAPIがあり、「CCPでこんなことできないかな」と妄想しながら眺めてみると面白いと思いますので、ぜひ。

Swift の Lambda カスタムランタイムを使ってHello World してみる

$
0
0

こんにちは、技術1課の加藤です。

現在、iOS アプリケーションの言語といえば Swift なわけですが、この Swift を Lambda で動かすことができるカスタムランタイムが出ました。
というわけで早速触ってみます。

著者のレベル

という感じです。

特に Swift に関してはほぼ素人ですので、処理自体はとても簡単なものを使っています。
ご了承ください。

環境

今回は Swift の開発を行うため、以下を用意します。 

  • OS: macOS
  • 開発環境: Xcode

また本チュートリアルでは Docker を用いたビルドを行うため、Docker Desktop for mac についても導入しておいてください。

手順

以下手順で進めていきます。

  1. SwiftPM プロジェクトを作成
  2. プロジェクトに Swift AWS Lambda Runtime をインポート
  3. main.swift に Lambda の実行スクリプトを実装
  4. Docker を用いてスクリプトをビルド
  5. デプロイ
  6. 動作確認

1. SwiftPM プロジェクトを 作成

ではまずプロジェクトを作成していきます。
Swift Package Manager = SwiftPM というパッケージマネージャを用いて、プロジェクトの作成を行なっていきます。

ターミナルを開き、任意の場所で以下を実行しましょう。

$ mkdir HelloLambdabySwift
$ swift package init --type=executable
Creating executable package: HelloLambdabySwift
Creating Package.swift
Creating README.md
Creating Sources/
Creating Sources/HelloLambdabySwift/main.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/HelloLambdabySwiftTests/
Creating Tests/HelloLambdabySwiftTests/HelloLambdabySwiftTests.swift
Creating Tests/HelloLambdabySwiftTests/XCTestManifests.swift
$ open Package.swift

これで HelloLambdabySwift というプロジェクトの Package.swift ファイルが Xcode で開かれます。

2. プロジェクトに Swift AWS Lambda Runtime をインポート

必要なライブラリのインポート設定を書き込んでいきます。
Package.swfit を以下のように変更してください。

// swift-tools-version:5.2

import PackageDescription

let package = Package(
    name: "HelloLambdabySwift",
    platforms: [
        .macOS(.v10_13),
    ],
    products: [
        .executable(name: "HelloLambdabySwift", targets: ["HelloLambdabySwift"]),
    ],
    dependencies: [
        .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "0.1.0"),
    ],
    targets: [
        .target(
            name: "HelloLambdabySwift",
            dependencies: [
                .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
        ]),
    ]
)

これでインポート設定は完了です。

3. main.swift に Lambda の実行スクリプトを実装

では実際に処理を書いていきます。
[Sources] > [HelloLambdabySwift] > [main.swift]
を選択し、中身を以下のように変更します。

import AWSLambdaRuntime

Lambda.run { (_, _, callback) in
    callback(.success("Hello, Lambda. by Swift"))
}

今回はイベントからもコンテキストからも何も受け取らず、ただ文字列を返すだけの関数を作成したため、第1, 2引数を _ にして捨ててしまっています。

本来、クロージャの第1引数が Context、第2引数が Event、第3引数が callback 関数を受け取る形になっている様子。今回はcallback以外捨てちゃいましたが、必要に応じて利用してあげてください。

さてさて、作成した関数をテスト実行してみたいのですが、これだとまだテスト実行ができません。
ちょこっと改修を加えます。

import AWSLambdaRuntime

try Lambda.withLocalServer {
    Lambda.run { (_, _, callback) in
        callback(.success("Hello, Lambda. by Swift"))
    }
}

こうすることで、テスト実行時には Lambda.withLocalServer が実行され、関数が動いてくれます。

Xcode でコードをテスト実行してみます。
実行対象を MyMac に変更し、Xcode の実行ボタン (三角形の再生マーク) をクリックしてテスト実行をしてみましょう。
Build Succceeded の表示とともにコンソールのログが出ればOKです

実行が成功すると以下の内容のログが出力され、ローカルサーバーが待機状態になります。

  • 127.0.0.1:7000 を localLambdaServer で開いていること
  • /invoke に対して payloads を投げ込めば受け取ること

試しに以下の curl コマンドをターミナルで実行してみましょう。

$ curl -X POST --data 'test' http://127.0.0.1:7000/invoke
Hello, Lambda. by Swift

何がしかのデータを payloads として放り込むことで、callback 関数に指定した文字列が帰ってくることが確認できます。

ちなみに /invoke にGETをすると 404(Not Found)
データを渡さずに /invoke に POST をすると 400 (Bad Request) が帰ってきました。この辺は LocalServer の実装 みたいです。
(※2020/06/10現在、 SwiftAWSLambdaRuntime ver0.1.0 環境での結果)

Docker を用いてスクリプトをビルド

作成したコードをビルドしていきます。
ただ本番デプロイするコードに LocalServer はいらないためテスト実行時のみ利用するようコードを変更します。

Swift にはデバッグ時に実行するコードを判別する #if DEBUG という書き方があるのでこれを利用します。

import AWSLambdaRuntime

#if DEBUG
try Lambda.withLocalServer {
    Lambda.run { (_, _, callback) in
        callback(.success("Hello, Lambda. by Swift"))
    }
}
#else
Lambda.run { (_, _, callback) in
    callback(.success("Hello, Lambda. by Swift"))
}
#endif

これでデバッグ時のみ LocalServer で動くように修正できました。
(DRY ではなくもっといい書き方があるんじゃないかとは思うのですが、Swift 力が低く何も思いつかなかったので、ひとまずこれで進めます。)

Lambda にデプロイするためには、Amazon Linux 用にコンパイルしたコードを Zip にパッケージし、AWS へアップロードをする必要があります。

まずは Amazon Linux 用にコンパイルを行なっていきます。
これは Docker を用い専用のコンテナを使って実施します。
(なおビルド時に使うスクリプト類は swift-was-lambda-runtime のリポジトリにある、サンプル用のスクリプトを転用させていただいています。)

プロジェクトルート (Package.swift がある階層) に Dockerfile を作り、以下を書き込んでください。

FROM swiftlang/swift:nightly-master-amazonlinux2

RUN yum -y install zip

そして同じくプロジェクトルートで以下のコマンドを実行していきます。

$ docker build -t builder .
$ docker run --rm -v "$(pwd)":/workspace -w /workspace builder bash -cl "swift build --product HelloLambdabySwift -c release -Xswiftc -g"

これでコンパイルができました。

次にコードの Zip パッケージ化を行います。
プロジェクトルートに package.sh ファイルを作り、以下の内容を書き込んでください。

#!/bin/bash

set -eu

executable="HelloLambdabySwift"
target=.build/lambda/$executable

rm -rf "$target"
mkdir -p "$target"

cp ".build/release/$executable" "$target/"
cp -Pv /usr/lib/swift/linux/lib*so* "$target"
cd "$target"
ln -s "$executable" "bootstrap"
zip --symlinks lambda.zip *

そして以下コマンドを実行し、package.sh をコンテナ内で動かすことで Zip にパッケージします。

$ chmod +x package.sh
$ docker run --rm -v "$(pwd)":/workspace -w /workspace builder bash -cl "./package.sh"

.build/lambda/HelloLambdabySwift/lambda.zip が作成されていれば完了です。

5. デプロイ

作成したスクリプトを AWS 環境にデプロイをしましょう。
AWS マネージメントコンソールで AWS Lambda を開きます。

画面右にある [関数の作成] を押して関数の設定画面を開きます。

以下の画像の通り設定を入力し、右下の [関数の作成] を押してください。カスタムランタイムを使用した Lambda が作成されます。

さて 作成した Lambda の画面が開きましたら、[関数コード][アクション] から [.zip ファイルをアップロード] を選択します。

[アップロード]ボタンを押し、.build/lambda/HelloLambdabySwift の lambda.zip を選択、 [保存] を押します。

「関数 HelloLambdabySwift が正常に更新されました。」と表示が出ればアップロード完了です。

6. 動作確認

最後に、正しく動作するか確認します。画面右上の [テスト] ボタンを押しテストイベントを作成しましょう。
今回特に event に渡す値は必要ないので、{} を設定しておきます。

[作成] ボタンを押しイベントが作られたら、再度 [テスト] ボタンを押しテストを実行しましょう。
実行結果が 成功 になり"Hello Lambda. by Swift" という文字列が返ってきていれば成功です。

お疲れ様でした。

所感

iOS アプリケーションをメインで作っていらっしゃる方がバックエンドに Lambda を使おうと思ったら、Swift on Lambda を利用する、ということもあるのかもしれませんね。

とはいえそれなりに手順はかかりますし、Swift の学習コストやカスタムランタイムの運用コストもそれなりに高いので、
現時点では何か特別な理由がなければ標準でサポートされている言語を使った方がいいんじゃないかなというのが感想でした。

気になった方がいれば試してみてください。

参考

Amazon FSx for Windows File Serverのパフォーマンス特性、及び、監視運用について

$
0
0

こんにちは、CSM課の城です。

テレワークが続く中、あれやこれやと家電やらモニターやら机やらと買い揃え、ついに仕事部屋を確保することに成功しました。
歓喜に明け暮れております。
さておき、掲題のお話に入ります。

どんなシステムを利用する際もシステムのパフォーマンスの不足や障害検知のため、モニタリングや監視をするかと思います。
これはAWSのマネージドサービスを利用する際も同様です。
とあるシステムにてAmazon FSx for Windows File Serverを利用しているのですが、パフォーマンス特性やどのように監視運用をすべきか、検討した内容を共有したいと思います。

1. Amazon FSx for Windows File Serverのパフォーマンスについて

1.1 コンポーネントとパフォーマンス特性

まずはドキュメントに記載の下図をごらんください。

ファイルシステムへはENIを経由してアクセスします。
このENIの背後にはWindowsファイルサーバーがあり、ファイルサーバーにはインメモリキャッシュを備えています。
ファイルサーバーの背後にストレージボリューム、または、ディスクが配置されています。

上記のコンポーネントに対応するパフォーマンス特性、及び、それぞれの特性を決定する要素は下表となります。

パフォーマンス特性 説明 パフォーマンス特性を決定する要素
ネットワークパフォーマンス クライアントとファイルサーバー間のリクエストのスループット/ IOPS Throughput capacity
ファイルサーバーのインメモリキャッシュサイズ インメモリキャッシュサイズ Throughput capacity
ディスクI/Oパフォーマンス ファイルサーバーとストレージボリューム間のリクエストのスループット/ IOPS Throughput capacity
Storage capacity

1.2 ベースラインパフォーマンスとバーストパフォーマンス

Amazon FSx for Windows File Serverはバーストパフォーマンスを持っています。
これはベースラインレベルのパフォーマンスを提供しながら、そのベースラインレベルを超えてバーストする機能となります。
詳細は後述しますが、バーストパフォーマンスを持っているという点を考慮して設計を実施し運用することで、過剰な性能を避け、コストを最適化することが可能になります。

1.3 具体的なパフォーマンス特性を求める

ドキュメントに記載の下表のとおり、各パフォーマンス特性を求めることができます。

【Throughput capacityから求められるパフォーマンス特性】

【Storage capacityから求められるパフォーマンス特性】

ディスクI/Oパフォーマンスについては、上表で算出したどちらか低い方となるので、Storage capacityを少量に設定している場合などは注意が必要です。
ちなみにStorage capacityのSSDの性能については、ベースライン性能だそうです。

例えば、次の構成の場合を考えてみます。
ストレージタイプ: SSD
Throughput capacity: 16 MB/s
Storage capacity: 100 GiB

Throughput capacityから求められるパフォーマンス特性は下記となります。

  • ネットワークスループット(MB/s): ベースライン 16 , バースト 600
  • ネットワークIOPS: ベースライン 数千 , バースト 数万
  • インメモリキャッシュサイズ(GB): 1
  • ディスクスループット(MB/s): ベースライン 16 , バースト 260
  • ディスクIOPS: ベースライン 数百から数千 , バースト 数万

次にStorage capacityから求められるパフォーマンス特性は次のとおりです。

  • ベースラインディスクスループット(MB/s): 750 × 100GiB/1024GiB ≒ 73.24
  • ベースラインディスクIOPS: 3,000 × 100GiB/1024GiB ≒ 292

このようになるので、ディスクスループットについてはベースラインが16MB/s、ディスクIOPSについてはベースラインが292IOPSとなります。

また、バーストパフォーマンスについて、「ネットワークI/OとディスクI/O一定期間高速にバーストする機能」との記載がありますが、一定期間というのがどのくらいの期間なのかはドキュメントに記載されておらず、詳細は不明です。
ただ、2019年3月時点の資料と少し古いのですが、下記リンク先のBlack Beltセミナーの資料に「1日当たり30分のバーストクレジットが供給され、ベースラインパフォーマンスを下回っている期間は追加のバーストクレジットが供給される」とありましたので、参考にはなるかと思います。

2. 監視運用について

前項にてパフォーマンスについては確認しましたので、それをもとに監視運用を考えてみます。
ネットワークスループット単体がボトルネックとなるというのは考えづらいので、基本的には下記3項目を監視すればよいと考えます。

  • ディスクの空きストレージ容量
  • ディスクスループット
  • ディスクIOPS

こちらについて、CloudWatchで監視、SNSで通知するパターンを考えてみます。

2.1 対象メトリクスについて

では実際何を監視対象のメトリクスにするかですが、Amazon FSx for Windows File Serverのダッシュボードには予めこちらのメトリクスが用意されています。

マネジメントコンソールにてAmazon FSxのダッシュボードから[File systems]の画面に遷移し、[File system name]または[File system ID]をクリックします。

[Monitoring]をクリックすると、
Free storage capacity、Total throughput (bytes/sec)、Total IOPS (operations/sec)のグラフが表示されます。

ここからCloudWatch alarmを作っていくわけですが、お薦めは[Create CloudWatch alarm]をクリックするのではなく、次の方法で作成となります。
各グラフの右上にある…が縦に並んだマークをクリックし、[メトリクスで表示]をクリックします。

ここからはそれぞれのメトリクスについて説明していきます。

2.2 FreeStorageCapacity

FreeStorageCapacityについてはメトリクスそのものが取得できるので、メトリクスを選択肢、[統計]をプルダウンから最小に変更、[アラームの作成(ベルのマーク)]をクリックします。

アラーム条件について[以下 <=しきい値]([より低い]でもOK)を選択、しきい値を入力し、[次へ]をクリックします。

Bytesでの指定になるのですが、今回はざっくり5,000,000,000としています。
利用の特性やしきい値のアラート後にストレージ容量の拡張オペレーションをするのにどれくらい余裕が必要かといったことを加味して決めるのがいいでしょう。
その他の設定についてはアラームを実行するデータポイント(何回のデータポイントのうち、何回条件該当で発報)の設定や欠落データがあった際の処理の方法を設定できます。
こちらについては、今回はデフォルトのままとしています。

SNSトピックを設定します。
既存のものの利用、もしくは、[新しいトピックの作成]、[通知を受け取るEメールエンドポイント]にメールアドレスを入力し、[トピックの作成]をクリックします。

[次へ]をクリックします。

[アラーム名]を設定し、[次へ]をクリックします。

内容を確認し、[アラームの作成]をクリックします。

おっと、SNSのConfirmを忘れていました。

SubscriptionのConfirmを実施しないとSNSからの通知を受信することができません。
SNSトピックを作成すると、登録したメールアドレスに「AWS Notification – Subscription Confirmation」という件名でメールが届きます。
本文中のConfirm subscriptionをクリックします。

SubscriptionのConfirmができました。

CloudWatchの画面を更新すると、状態がOKとなりました。これで空き容量が約5GBを下回ると登録したメールアドレスに通知がきます。

2.3 Total throughput (bytes/sec)、Total IOPS (operations/sec)

Total throughput (bytes/sec)についてはこの方法でメトリクスを表示させると、Total throughput (bytes/sec)すなわち、DataReadBytes、DataWriteBytesの1分間の合計を60秒で割ったものがあるので、こちらを監視対象とします。
同様にTotal IOPS (operations/sec)についても、DataReadOperations、DataWriteOperations、MetadataOperationsの1分間の合計を60秒で割ったものとなります。
※ほぼ同じ内容となるのでTotal throughputのみ、画像を掲載します。

同様に[アラームの作成(ベルのマーク)]をクリックします。

ディスクスループット、IOPSの閾値については、システムのストレージの使い方により、設定の仕方が変わってきます。
今回私が運用するシステムとしては、読み取りはあまり発生しない、書き込みについてもスパイクが無く常に一定量を書き込み続けるような動作になるので、ベースラインスループット、IOPSを閾値とし、データポイント3回中3回超過したら、というような設定としました。
※こちらのサンプルFSxの設定とは異なりますが、1.3項の例と合わせてThroughput capacityが16MB/sを想定した設定となっています。

通知、アラーム名の設定をして、CloudWatch Alarmを作成します。(画像省略)

CloudWatch Alarm、及び、通知の設定をすることが出来ました。

さいごに

Amazon FSx for Windows File Serverについては先日のアップデートの前まではThroughput capacityやStorage capacityを変更することが出来なかったため、大きめに作ることが多かったと思いますが、変更することが出来るようになったため、パフォーマンス監視をきちんとすることで、過大な設定を避けコスト最適化することが出来ます。
より使いやすくなったAmazon FSx for Windows File Serverを利用してみてはいかがでしょうか。

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

【参考資料、画像引用元】
https://docs.aws.amazon.com/fsx/latest/WindowsGuide/performance.html
https://docs.aws.amazon.com/fsx/latest/WindowsGuide/monitoring-cloudwatch.html
https://docs.aws.amazon.com/fsx/latest/WindowsGuide/how_to_use_metrics.html

Amplify CLI を用いて定期実行の Lambda 関数をデプロイする

$
0
0

こんにちは、技術1課の加藤です。

今回は、AWS Amplify のお話。簡単にアプリケーションが構築できちゃう超便利サービスな Amplify なわけですが、一定の型から外れようとするとなかなか苦労する印象がありました。

しかし機能の拡充は進み、今となってはバッチ処理用の Lambda 関数を用意するのもお茶の子さいさいとのこと。

素敵な機能だと思ったので試してみました。

手順

  1. Amplify プロジェクトの作成
  2. Lambda 関数の追加
  3. デプロイ

以下のブログを参考にしています。
How to schedule recurring Lambda functions using the Amplify CLI

1. Amplify プロジェクトの作成

Amplify CLI のインストールや amplify configure の実行がまだの方はGet started – Installation – Amplify Docs に従い事前準備をお願いします。

上記が完了していましたら、ターミナルを開き、任意の場所で以下コマンドを実行します。エディタ設定は環境に合わせてお好きなものを選んでください。

$ mkdir amplify-lambda-sample
$ cd amplify-lambda-sample
$ amplify init
Scanning for plugins...
Plugin scan successful
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project amplifylambdasample
? Enter a name for the environment dev
? Choose your default editor: Vim (via Terminal, Mac OS only)
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using none
? Source Directory Path:  src
? Distribution Directory Path: dist
? Build Command:  npm run-script build
? Start Command: npm run-script start
Using default provider  awscloudformation

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html

? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default

2. Lambda 関数の追加

では今回の本題、Lambda 関数の追加を行なっていきます。

コマンドは以下。

$ amplify add function
Using service: Lambda, provided by: awscloudformation
? Provide a friendly name for your resource to be used as a label for this categ
ory in the project: amplifylambdasamplexxxxxx
? Provide the AWS Lambda function name: amplifylambdasamplexxxxxx
? Choose the function runtime that you want to use: NodeJS
? Choose the function template that you want to use: Hello World
? Do you want to access other resources created in this project from your Lambda
 function? No
? Do you want to invoke this function on a recurring schedule? Yes
? At which interval should the function be invoked: Minutes
? Enter the rate in minutes: 1
? Do you want to edit the local lambda function now? No

  • 定期実行 (毎分1回): 正しく実行されているか素早く確認するため
  • Node.js
  • HelloWorld テンプレートを使用

という設定を行いました。

関数のテンプレートとして、REST API や( ドキュメント見ると serverless-express ベースになってるみたい) 、DynamoDB Stream や Kinesis Stream に対応する Lambda Trigger が存在する様子。

また API に AppSync(GraphQL) を利用している場合、schema.json にて@function ディレクティブを使ってあげるとここで作った関数をデータソースとして利用することができるとのこと。
Amplify プロジェクトで使いたくなる Lambda の用途はだいたい網羅している感じがしますね。良き良き。

ひとまず今回はテストということで、通常の関数を作成するだけの HelloWorld テンプレートを選びました。
すると amplify-lambda-sample/amplify/backend/function/amplifylambdasamplexxxxxx/src 内にLambda のコードが用意されます。何気に event.json とかも用意されているのでローカルテストもできそうです。

3. デプロイ

ではデプロイしてみましょう。以下コマンドを実行します。

$ amplify push
✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category | Resource name               | Operation | Provider plugin   |
| -------- | --------------------------- | --------- | ----------------- |
| Function | amplifylambdasamplexxxxx | Create    | awscloudformation |
? Are you sure you want to continue? Yes

これでリソースが AWS に作られ、 1分毎に “HelloWorld” をリターンし続けるはずです。

AWS マネージメントコンソールで Lambda を開いてみると、きちんと想定通りの Lambda 関数が作成されていることが確認できます。

また少々時間をおいて [モニタリング]> [CloudWatch のログを表示] から実行ログを見てみましょう。1分おきに関数が実行されていることも確認できます。

環境の削除

環境を削除する際には以下のコマンドを実行します。

$ amplify delete 
? Are you sure you want to continue? (This would delete all the environments of the project from the cloud and wipe out all the local amplify resource files) Yes

まとめ

Amplify CLI を使って、 Lambda 関数のデプロイを行ってみました。

非常に簡単な手順で行えますし、これで Amplify プロジェクトないに閉じた形で関数を管理できるので非常に便利だと感じます。

ぜひ皆さんも使ってみてください。

Amplify 関連記事

【はじめてのAWS】Amazon GuardDuty を設定しよう

$
0
0

 

今回は、弊社のYoutubeチャンネル「サーバーワークス チャンネル」にて先日公開した以下動画についてblogでも内容を紹介いたします。

動画内では、実際にAWSマネジメントコンソールを操作しながら設定を行っていくデモがありますのでもし興味があれば是非、動画も参照頂ければと思います。

内容が良かった、為になったと感じたら是非Goodボタンやチャンネル登録頂けると嬉しいです。

対象者

・AWSをこれからはじめたい方
・AWSをもっと活用したい方
・Amazon GuardDuty の概要や設定イメージを把握したい方

Amazon GuardDutyとは

AWSのマネージド型の“脅威検出サービス”となります。
Amazon GuardDuty を有効にすると AWS CloudTrail や VPC フローログ や DNSログなどの様々なイベントログが自動的に分析されます。管理者視点だと、数クリックの設定を行うだけで、悪意のある操作や不正な動作を継続的にモニタリングする事が可能になります。

参照:Amazon GuardDuty
https://aws.amazon.com/jp/guardduty/

Amazon GuardDutyの料金

使った分だけの従量課金となっており、一定容量が増える毎にボリュームディスカウントも適用されます。
・AWS CloudTrailのイベントの回数
・VPCフローログやDNSログの容量

無料利用枠があり、利用開始後30日間は無料となっています。
無料で利用している期間中も日毎の平均利用料の推定を確認することが出来るので試用と同時に費用感を把握されるのが良いと思われす。詳細はAWS公式の以下情報を参照ください。

参照:Amazon GuardDuty の料金
https://aws.amazon.com/jp/guardduty/pricing/

Amazon GuardDuty の注意事項

注意点として以下3点を紹介します。

  1. 各種ログ出力設定は Amazon GuardDuty側で行われません
    Amazon GuardDutyで利用されるAWS CloudTrail、VPCフローログ、DNSログ等は、ユーザが独自に取得設定を行う内容とは別の独立したデータストリームから直接取得されます。従って仮にユーザ側でログを未取得でも Amazon GuardDuty側の設定をするだけで脅威検知は可能ですが、実際に検知されたログの詳細をユーザー側で確認する事はできませんので、Amazon GuardDutyの利用と同時に関連ログの取得設定を実施しておく事を推奨します。詳細は以下を参照ください。

    Amazon GuardDuty – よくある質問
    Q: Amazon GuardDuty の AWS CloudTrail、VPC フローログ、および DNS ログを有効にする必要はありますか?
    https://aws.amazon.com/jp/guardduty/faqs/

  2. 検出された脅威について管理者側で確認および対処する必要があります
    Amazon GuardDutyは、検知した脅威を3つの重大度(低、中、高)で評価し、管理者が脅威を把握しやすいよう継続的にモニタリングしてくれますが、検出された脅威に関する対応判断や実際の処置は当該AWSアカウント管理者側の責任で行う必要があります。
    その為、管理者視点だと脅威が検出された際の運用プロセスについてもあわせて検討しておくと良いでしょう。ただし、実際の検出内容を確認しないと然るべき運用も見えてこないとは思われますのでまずは無料利用枠を活用し、実際に利用してご検討頂くのが良いと思われます。
  3. Amazon GuardDutyはリージョン毎に設定が必要となります
     複数リージョンをご利用の場合は、複数リージョンでの設定および運用が必要となります。

Amazon GuardDutyのセットアップ実施のデモ(動画内 01:28〜)

Amazon GuadDutyを有効化の設定を行い費用感をどこで把握すれば良いかデモを動画内で紹介しています。
管理者視点で、ざっくりとAmazon GuardDutyの設定イメージを掴んで頂ける内容となっておりますので、もし興味があれば動画を参照ください。

まとめ

Amazon GuardDutyを有効活用する事で、社内セキュリティチーム等のリソースを割かずとも膨大な量のログから悪意のある操作や不正な動作を継続的にモニタリングし、脅威を把握する事が可能となります。

管理者としてAWSアカウントを作成した際には、無料利用枠もありますので、初期設定項目として実施を検討してみてください。

 

クライアント証明書のインポート(MacOS)

$
0
0

こんにちは。
梅雨に入って湿度が高くなってきましたね。
最近、エアコンのドライ機能の素晴らしさに気づいた設樂です。
ドライをつけっぱなしにしてたら部屋の湿度が40%台になってしまい、寝て起きたら軽く喉が荒れてました。
高温多湿環境だとトラックパッドの滑りも悪くなって効率が悪くなります。

さて、今回はmacOSにクライアント証明書をインポートする方法をご案内したいと思います。
WorkSpacesをデバイス認証したりするのに使えます。
WindowsのWorkSpacesクライアントでデバイス認証

アクセス確認(拒否されること)

クライアント証明書がない状態だとアクセス制御しているWorkSpacesに拒否されました。

クライアント証明書のインポート(ローカル端末)

お手元のクライアント証明書(client.p12)をローカル端末にて実行します。
※クライアント証明書の発行はこちらをご確認ください。

クライアント証明書のパスワードが求めらます。
こちらを入力します。

Keychain Accessに登録されます。

ルート証明書(PineApple-workspaces)を開きます。
このルート証明書は信頼されていないようです。

信頼してあげましょう。

信頼ができたら、ファイルを閉じます。

ローカル端末の認証が求められます。

アクセス確認

クライアント証明書がある状態で再チャレンジします。
Keychain Accessにローカル端末の管理者パスワードを求められました。

許可すると、今度はアクセスできました。

まとめ

割とポチポチする操作が多くて直感的に進められると思います。
直感的な操作って便利な半面、無意識に進んでしまうことがあってちょっとこわいです。。。
それでは。

CloudTrailの証跡ログをSSE-KMS暗号化に変更する

$
0
0

AWSにはSecurity Hubというコンプライアンスチェックをしてくれるサービスがあります。
「AWS基礎セキュリティのベストプラクティス」のチェック項目の1つに 「CloudTrailでは、保管時の暗号化を有効にします」というのがあります。
しかし、私のAWSアカウントでは失敗となっていました。

コンプライアンスチェックのスコアを上げたい、そんな気持ちから暗号化設定をしてみました。
また、その設定をする意味についても考えてみました、

1.CloudTrailのSSE-KMS暗号化設定をする

まずは現状把握

CloudTrailの証跡の設定を確認します。
確かに「ログファイルのSSE-KMS暗号化」が無効になってました。

あっさりとSSE-KMSに変更

後から暗号化設定の変更をできるんだろうか?と疑問に思いましたが、編集ボタンからあっさり変更できました。
今回はKMSキーを新規作成しました。

CloudTrailの設定をみると、ほんとにあっさり変更できてますね。

念のため、KMSの画面で確認すると、新しいCMK(カスタマー管理型のキー)ができていました。

ログも暗号化できたし、Security Hubのスコアも上がった

変更後に作成されたS3オブジェクトをみると、暗号化がAWS-KMSとなっています。
期待通りですね。

Security Hubのコンプライアンスチェックでも成功となりました。

2.CloudTrailはデフォルトで暗号化されている

CloudTrailの証跡を暗号化する設定をしてきましたが、実はデフォルトでも暗号化されてS3バケットに保存されます。

なんのこっちゃですね。
デフォルトではSSE-KMSではなく、SSE-S3という方式で暗号化されます。

SSE-KMSへの変更前に作成されたオブジェクトをみると、AES-256(SSE-S3のこと)という表記で暗号化されているのがわかります。

AWS CloudTrail を使用すると、AWS API 呼び出しや AWS アカウントの他のアクティビティを記録し、記録された情報を、選択した Amazon Simple Storage Service (Amazon S3) バケット内のログファイルに保存できます。デフォルトでは、CloudTrail によって S3 バケットに配信されるログファイルは、Amazon S3– で管理された暗号化キーによるサーバー側の暗号化 (SSE-S3) を使用して暗号化されます。ただし、AWS KMS– 管理キーによるサーバー側の暗号化 (SSE-KMS) の使用を選択することもできます。
AWS CloudTrail で AWS KMS を使用する方法

デフォルトでは、SSE-S3で暗号化されると書いてます。

機密性の高い CloudTrail ログファイルのセキュリティを強化するには、保管時の暗号化用の CloudTrail ログファイルに AWS KMS マネージドキー (SSE-KMS) を使用してサーバー側の暗号化を使用する必要があります。デフォルトでは、CloudTrail によってバケットに配信されるログファイルは、Amazon で Amazon S3 管理された暗号化キーによるサーバー側の暗号化 (SSE-S3) によって暗号化されます。
AWS の基本的なセキュリティのベストプラクティスコントロール

Security Hubの説明では、「デフォルトでSSE-S3だけど、SSE-KMSにしてね」的なことが書いてあります。

3.CloudTrailのSSE-KMS暗号化のメリット

デフォルトでも暗号化されているのに、わざわざSSE-KMSに変更した時の利点はなんでしょうか?

このアプローチには以下の利点があります。

・ CMK 暗号化キーを自分で作成して管理することができます。
・ 単一の CMK を使用して、すべてのリージョンの複数のアカウントのログファイルを暗号化および復号できます。
・ CloudTrail ログファイルを暗号化および復号するためにキーを使用できるユーザーを制御できます。要件に応じて、組織のユーザーにキーのアクセス権限を割り当てることができます。
・ セキュリティが強化されました。この機能では、ログファイルを読み取るために、次のアクセス許可が必要です。
・ ユーザーには、ログファイルを含むバケットに対する S3 の読み取り権限が必要です。
・ ユーザーには、CMK ポリシーによるアクセス許可の復号化を許可するポリシーまたは役割も適用する必要があります。
・ S3 では、CMK の使用を許可されたユーザーからの要求に対してログファイルが自動的に復号されるため、CloudTrail ログファイルの SSE-KMS 暗号化は、CloudTrail ログデータを読み取るアプリケーションとの下位互換性があります。
AWS KMS で管理されたキー (SSE-KMS) による CloudTrail ログファイルの暗号化

いくつかの利点が書いてありました。
これらに魅力を感じるのであれば、SSE-KMS暗号化するといいと思いますが、必ずしもすべてのAWSユーザーに必要ではない気もします。

CMK 暗号化キーを自分で作成して管理

自分で作成した鍵をインポートしたいとか、定期的に鍵をローテーションしたいといったことを含むのだと思います。
企業によっては、セキュリティ監査要件に記載があるかもしれません。

CloudTrail ログファイルを暗号化および復号するためにキーを使用できるユーザーを制御

SSE-S3のキーは、AWSアカウント内のどのユーザーからでもアクセスできるという決め打ちの設定になっています。
SSE-KMSのキーなら、キーポリシーでいろいろと権限制御が可能です。

マネージメントコンソールでCloudTrailの暗号化設定の際に作成されたCMKのキーポリシーは以下のようになっていました。

{
    "Version": "2012-10-17",
    "Id": "Key policy created by CloudTrail",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:sts::123456789012:assumed-role/Role1/User1",
                    "arn:aws:iam::123456789012:root"
                ]
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow CloudTrail to encrypt logs",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "kms:GenerateDataKey*",
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:123456789012:trail/*"
                }
            }
        },
        {
            "Sid": "Allow CloudTrail to describe key",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "kms:DescribeKey",
            "Resource": "*"
        },
        {
            "Sid": "Allow principals in the account to decrypt log files",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "kms:Decrypt",
                "kms:ReEncryptFrom"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "kms:CallerAccount": "123456789012"
                },
                "StringLike": {
                    "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:123456789012:trail/*"
                }
            }
        },
        {
            "Sid": "Allow alias creation during setup",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "kms:CreateAlias",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "kms:CallerAccount": "123456789012",
                    "kms:ViaService": "ec2.ap-northeast-1.amazonaws.com"
                }
            }
        },
        {
            "Sid": "Enable cross account log decryption",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "kms:Decrypt",
                "kms:ReEncryptFrom"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "kms:CallerAccount": "123456789012"
                },
                "StringLike": {
                    "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:123456789012:trail/*"
                }
            }
        }
    ]
}

このポリシーだと、SSE-S3と同様にアカウント内の誰でもキーにアクセスし、復号に用いることができます。
ある意味では、そのまま使えるので親切なポリシーとは思います。

ただし、特定のIAMユーザーにのみ復号化を許可する設定にしたい場合は、”kms:Decrypt”を許可するPrincipalを限定する必要があります。
例えば、Principalを”AWS”: “*”から、管理者のIAMユーザーに変更します。
そうすれば、その他のIAMユーザーでは復号化できなくなり(=S3オブジェクトををダウンロードできなくなり)、CloudTrailのログにアクセスできる人を限定できます。

{
            "Sid": "Allow principals in the account to decrypt log files",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/user1"
            },
            "Action": [
                "kms:Decrypt",
                "kms:ReEncryptFrom"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "kms:CallerAccount": "123456789012"
                },
                "StringLike": {
                    "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:123456789012:trail/*"
                }
            }
        }

4.CloudTrailのSSE-KMS暗号化のデメリット

明確なデメリットは1つで、コストが発生することです。

AWS KMS– 管理キー (SSE-KMS) によって CloudTrail ログファイルを暗号化すると、CloudTrail がログファイルを S3 バケットに置くたびに、AWS KMS API リクエストが生成されます。通常、CloudTrail は 5 分おきにログファイルを S3 バケットに置くため、リージョンおよび AWS アカウントあたり 1 日に約 288 の AWS KMS API リクエストが生成されます。
AWS CloudTrail で AWS KMS を使用する方法

まとめ

CloudTrailの証跡はデフォルトではSSE-S3で暗号化されますが、それをSSE-KMS暗号化に変更するのは簡単にできます。
しかし、必須というわけではありません。
メリット、デメリットを考えて決定していただければと思います。


AWS Transfer Family が認可の要素として接続元 IP を指定できるようになりました

$
0
0

はじめに

こんにちは、技術1課の山中です。
雨が多いと思ったらいつの間にか梅雨に入っていたみたいですね。
これからは晴れの日が貴重になってくるので、計画的に洗濯していこうと思っています。
というのはさておき!
今回はこのアップデートについて見ていきます!

AWS Transfer Family が認可の要素としてソース IP を有効に

AWS Transfer Family が認可の要素として接続元 IP を指定できるようになったとのことなので、試していこうと思います。

AWS Transfer Family とは

Amazon Transfer Family とは、以下サービスの集合的な名称でフルマネージド型のサービスです。

  • AWS Transfer for SFTP
  • AWS Transfer for FTPS
  • AWS Transfer for FTP

AWS Transfer Family | アマゾン ウェブ サービス

SFTP、FTPS、FTP 経由で Amazon S3 と直接ファイルのやり取りができます。

料金

AWS Transfer Family では、それぞれのエンドポイントが有効になっている時間及びデータアップロード/ダウンロード量に対する従量課金となっています。
各プロトコルのエンドポイントごとに料金が発生しますので、ご注意ください。
詳しくは以下を参照ください。
AWS Transfer Family の料金 | アマゾン ウェブ サービス

アップデート内容の確認

今回は接続元 IP が認可の要素として利用できるようになったということで、接続元 IP によってユーザに異なる権限を与えることを試していきます。

S3 バケットのセットアップ

まずは、 SFTP 経由で接続するための S3 バケットを作成します。
今回は、 20200615-demo-bucket というバケットを作成しました。

適当にファイルを作成し、配置しておきました。

IAM ロールのセットアップ

今回は以下のようなアクセスコントロールを行ってみたいと思います。

  • 特定 IP アドレスからのアクセス
    バケット内ファイルの参照及び操作が可能
  • 上記 IP アドレス以外からのアクセス
    バケット内ファイルの参照のみ可能

これを実現するために 2 つの IAM ロールを事前に作成します。

  • AllowAccessToS3

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::20200615-demo-bucket"]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": ["arn:aws:s3:::20200615-demo-bucket/*"]
    }
  ]
}

  • AllowReadOnlyAccessToS3

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::20200615-demo-bucket"]
    },
    {
      "Effect": "Allow",
      "Action": [
            "s3:GetObject"
        ],
      "Resource": ["arn:aws:s3:::20200615-demo-bucket/*"]
    }
  ]
}

上記 IAM ポリシーの信頼ポリシーは以下です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "transfer.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

CloudFormation で各リソースの作成

Working with identity providers – AWS Transfer Familyページの Basic stack template からテンプレートをダウンロードし、 AWS CloudFormation で新たにスタックを作成していきます。

SFTP サーバーは後ほど作成するので、 CreateServerfalse にします。
また、 UserPublicKey1 に公開鍵を指定し、 UserRoleArn には先ほど作成した IAM ロール (特定 IP からアクセスがあった際に利用する) の ARN を指定します。

Lambda 関数の修正

CloudFormation にて作成される Lambda 関数は以下です。

'use strict';

// GetUserConfig Lambda

exports.handler = (event, context, callback) => {
  console.log("Username:", event.username, "ServerId: ", event.serverId);

  var response;
  // Check if the username presented for authentication is correct. This doesn't check the value of the serverId, only that it is provided.
  if (event.serverId !== "" && event.username == 'myuser') {
    response = {
      Role: 'arn:aws:iam::000000000000:role/AllowAccessToS3', // The user will be authenticated if and only if the Role field is not blank
      Policy: '', // Optional JSON blob to further restrict this user's permissions
      HomeDirectory: '/' // Not required, defaults to '/'
    };

    // Check if password is provided
    if (event.password == "") {
      // If no password provided, return the user's SSH public key
      response['PublicKeys'] = [ "ssh-rsa AAAAB3NzaC1yc2EXXXXXXXXXXx" ];
    // Check if password is correct
    } else if (event.password !== 'MySuperSecretPassword') {
      // Return HTTP status 200 but with no role in the response to indicate authentication failure
      response = {};
    }
  } else {
    // Return HTTP status 200 but with no role in the response to indicate authentication failure
    response = {};
  }
  callback(null, response);
};

アクセス元 IP アドレスによって与える権限を変えたいので、該当箇所を以下のように変更します。
※ Lambda の環境変数 allowIp に接続元 IP アドレスを設定しています

if (event.serverId !== "" && event.username == 'myuser') {
    if (event.sourceIp == process.env.allowIp) {
      response = {
        Role: 'arn:aws:iam::000000000000:role/AllowAccessToS3', // sourceIp が指定した IP アドレスの場合
        Policy: '', // Optional JSON blob to further restrict this user's permissions
        HomeDirectory: '/' // Not required, defaults to '/'
      };
    } else {
      response = {
        Role: 'arn:aws:iam::000000000000:role/AllowReadOnlyAccessToS3', // sourceIp が指定した IP アドレスでない場合
        Policy: '', // Optional JSON blob to further restrict this user's permissions
        HomeDirectory: '/' // Not required, defaults to '/'
      };
    }

    // Check if password is provided
    if (event.password == "") {

API Gateway のセットアップ

続いて、 Lambda 関数のトリガとなっている API Gateway の該当 API を開き、 /servers/{serverId}/users/{username}/config – GET のメソッドリクエストを選択します。

まず、 リクエストの検証 から クエリ文字列パラメータおよびヘッダーの検証 を選択し、リクエスト時の検証を有効にします。

続いて URL クエリ文字列パラメータ を展開し sourceIp の必須にチェックを入れます。

これで API Gateway の設定は完了したので、 [アクション] – [API のデプロイ] をクリックし prod ステージにデプロイします。

Transfer Family のセットアップ

マネジメントコンソールから AWS Transfer Family にアクセスし、 Create server をクリックします。

今回は SFTP にてファイル転送を行うので、 SFTP を選択し Next ボタンをクリックします。

Identity provider type では Custom を選択します。
Custom provider には先ほどデプロイした API Gateway の URL、 Invocation role には CloudFormation で作成した [Stack 名]-TransferIdentityProviderRole-XXXXXXXX を指定します。

エンドポイントタイプは Publicly accessible を選びます。

あとの設定はデフォルトのまま進めて Create server をクリックし、作成してください。

しばらく経つとステータスが Online となるので、 [Actions] – [Test] をクリックしテストしてみます。

テスト

Lambda 関数のコードで指定したユーザ名とパスワード及び IP アドレスを入力しテストしてみます。

この場合はきちんと AllowAccessToS3 ロールが返ってきました。
次は、 IP アドレスを違うものに変更してテストしてみます。

接続元 IP が異なるので、今度はきちんと AllowReadOnlyAccessToS3 ロールが返ってきています。
テストはうまくいきましたね。

アクセスしてみる

実際に許可している IP アドレスから SFTP 接続してみます。

$ sftp -i ~/.ssh/private_key myuser@s-8c3b109e73f64257b.server.transfer.ap-northeast-1.amazonaws.com
Connected to s-8c3b109e73f64257b.server.transfer.ap-northeast-1.amazonaws.com.
sftp> cd /20200615-demo-bucket #該当バケットに移動
sftp> ls
samplefile01.txt  samplefile02.txt  samplefile03.txt
sftp> rm samplefile01.txt #ファイルを削除
Removing /20200615-demo-bucket/samplefile01.txt
sftp> ls
samplefile02.txt  samplefile03.txt
sftp>

想定通り、許可している IP アドレスではファイルの参照も削除も可能ということがわかりました。
続いて VPN を繋いで上記と異なる IP アドレスで SFTP 接続してみます。

$ sftp -i ~/.ssh/private_key  myuser@s-8c3b109e73f64257b.server.transfer.ap-northeast-1.amazonaws.com
Connected to s-8c3b109e73f64257b.server.transfer.ap-northeast-1.amazonaws.com.
sftp> cd /20200615-demo-bucket #該当バケットに移動
sftp> ls
samplefile02.txt  samplefile03.txt
sftp> rm samplefile02.txt #ファイルを削除
Removing /20200615-demo-bucket/samplefile02.txt
Couldn't delete file: Permission denied #削除に失敗
sftp> ls
samplefile02.txt  samplefile03.txt
sftp>

許可していない IP アドレスからアクセスがあった場合、オブジェクトの参照はできますが削除はできないことがわかりました。

おわりに

接続元 IP アドレスにて権限を制御できるようになったお陰で、社内にいるときはフルアクセス、社外のときは参照権限のみ、など柔軟にアクセスコントロールができるようになるのではないでしょうか。

また、この内容は 2020/6/17(水) 12:00 よりYouTube Liveで配信する「30分でわかる AWS UPDATE!」で取り上げますますので、是非ご覧ください!

参考

【Amplify】 Amplify CLI を使ってカスタムリソースをデプロイする

$
0
0

こんにちは、技術1課の加藤です。
今日も今日とて Amplify。

Amplify ではあらかじめ用意されているテンプレートから生成した CloudFormation スタック以外に、ユーザーが作成したテンプレートを流すことができる機能があります。

今回はこの機能を使ったチュートリアルということで、 Amplify を使って EC2 インスタンスを立ててみます。

手順

以下手順で行っていきます。

  1. Amplify プロジェクトを作成
  2. カスタムリソースを定義
  3. テンプレート内容を定義
  4. デプロイ

公式ドキュメントはこちら
Custom CloudFormation stacks

1. Amplify プロジェクトを作成

とりあえず Amplify のプロジェクトを作りましょう。
フロントも何もなく、ただ EC2 を立てるだけという Amplify を使う意味…? 状態で作成をしていきます。

$ mkdir amplify-custom-cfn
$ cd amplify-custom-cfn
$ amplify init

init 時の選択肢は全てデフォルトで Enter を押しました。

2. カスタムリソースを定義

まずカスタムリソースを定義していきます。
リソースの定義は amplify/backend/backend-config.json に記載されています。

デフォルトでは何も入っていない {} が書いてあるだけです。
ここに、EC2 インスタンスを立てるためのカスタムリソース instance を作りましょう。

{
  "instance": {
    "EC2": {
      "service": "EC2",
      "providerPlugin": "awscloudformation"
    }
  }
}

次に上記の定義に対応したテンプレートファイルを配置します。
配置場所は amplify/backend/instance/EC2/template.json になる様子。
またテンプレートに渡すパラメータは template.json と同じディレクトリ に parameters.json として保存します。

$ mkdir -p amplify/backend/instance/EC2
$ touch amplify/backend/instance/EC2/{template,parameters}.json

この状態ではまだ Amplify CLI はカスタムリソースの存在を認識していません。 amplify statusをしても何も出てこないことが確認できます。

$ amplify status

Current Environment: dev

| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | --------------- |

カスタムリソースを Amplify CLI に認識してもらうには、以下のように checkout をしてあげる必要があります。

$ amplify env checkout dev
✔ Initialized provider successfully.
Initialized your environment successfully.
$ amplify status

Current Environment: dev

| Category | Resource name | Operation | Provider plugin   |
| -------- | ------------- | --------- | ----------------- |
| Instance | EC2           | Create    | awscloudformation |

これで Amplify CLI にカスタムリソースの存在を知らせることができました。

3. テンプレート内容を定義

とはいえまだ template.json の中身は空っぽです。
今回は EC2 と SecurityGroup をデフォルト VPC に作成していきます。以下を template.json に書き込んでください。
(※ 値については適宜自分の指定したい値に書き換えてご利用ください)

{
    "Parameters": {
    "env": {
      "Type": "String"
    },
    "KeyName": {
      "Type": "AWS::EC2::KeyPair::KeyName"
    }
  },
  "Resources": {
    "Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "InstanceType": "t3.micro",
        "ImageId": "ami-0a1c2ec61571737db",
        "KeyName": {
          "Ref": "KeyName"
        },
        "BlockDeviceMappings": [{
          "DeviceName": "/dev/xvda",
          "Ebs": {
            "VolumeType": "gp2",
            "VolumeSize": 8
          }
        }],
        "SecurityGroupIds": [{
          "Ref": "SecurityGroup"
        }],
        "Tags": [{
          "Key": "Name",
          "Value": "AmplifyCustomCfnTest"
        }]
      }
    },
    "SecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "AmplifyCustomCfnTest",
        "GroupDescription": "for AmplifyCustomCfnTest",
        "SecurityGroupIngress": [{
          "CidrIp": "0.0.0.0/0",
          "FromPort": 22,
          "ToPort": 22,
          "IpProtocol": "tcp",
          "Description": "SSH Access from Anywhere"
        }]
      }
    }
  }
}

また parameters.json にキーペアの情報を入力しておきます。自分の利用しているキーペアの名前を入れてあげてください。

{
  "KeyName": "<KeyPairName>"
}

ちなみにパラメータのうち env はResourcesで特に利用していないのですが、この指定をせずにデプロイすると以下のエラーが発生しました。

Parameters: [env] do not exist in the template

パラメータを利用する場合、 env はテンプレート内での使用有無に関わらず用意してあげる必要があるみたいです。

4. デプロイ

ではデプロイをしてみましょう。

$ amplify push

これで環境が立ち上がります。
EC2 が一台立ち上がっていれば成功です。

5. 環境削除

以下コマンドで環境を削除します。

$ amplify delete

この時、 amplify ディレクトリ ごとガサっと消えちゃうようです。
作成したコードも一緒に消えちゃうみたいなので、手がいたテンプレートの管理はお気をつけて。

まとめ

独自に作成した CFn をAmplifyを使って流してみました。
今回はとりあえず作ってみよう、ということで EC2 を立ててみましたが、かなり汎用的にAmplifyを利用することができそうです。

Amplify が提供している機能を使ってベースの実装はショートカットしつつ、バッチ処理などで必要なリソースは今回使ったカスタムCFnで作成していく、なんてことがやりやすくなっていきますね。

今後も Amplifyの記事継続的にアップしていきます。

AWS BackupでAmazon Auroraのスナップショットがとれるようになりました!

$
0
0

こんにちは、技術1課の小倉です。
2020/6/10にアップデートがあり、AWS BackupでAmazon Auroraのスナップショットがとれるようになりました!

Amazon Aurora スナップショットが AWS Backup 経由で管理可能に

今まではAmazon EC2、Amazon EBS、Amazon RDS、Amazon DynamoDB、Amazon EFS、AWS Storage Gatewayのバックアップが取得できていましたが、今回のアップデートでAmazon Auroraのバックアップが取得できるようになりました。対応するサービスが増えたことにより、よりバックアップの管理がしやすくなっています。

AWS Backupとは

AWSサービスのデータのバックアップを一元化と自動化を簡単に実行できる、マネージド型のバックアップサービスです。 AWS公式サイト : AWS Backup
2020/6/16現在、AWS Backupでできることと対応サービスを以下に記載します。

できること

  • リソースのバックアップ取得(スケジュール、オンデマンド)
  • バックアップアクティビティの監視
  • 取得したバックアップのリージョン間コピー
  • 取得したバックアップからの復元

対応サービス

  • Amazon EC2
  • Amazon EBS
  • Amazon RDS
  • Amazon DynamoDB
  • AWS Storage Gateway
  • Amazon EFS
  • Amazon Aurora

料金は保管、復元、転送にかかります。最新の料金は公式サイトでご確認ください。 AWS公式サイト : AWS Backup pricing

設定方法

サービスのオプトインでAuroraの有効化

いつからかわからないのですが、どのサービスのバックアップを取得するかを設定できるようになっていました。確認したらAuroraはデフォルトで無効になっていたので、有効に変更します。

マネジメントコンソールにログインして、AWS Backupのコンソール画面を表示します。
ナビゲーションペインの[設定]をクリックし、[リソースを設定]をクリックします。

リソースを設定の画面でAuroraを有効に変更して、[確認]をクリックします。

Auroraが有効になりました。

バックアッププランの作成

今回はAuroraのスナップショットをとるだけの目的ですので、細かい設定はせずにもともと用意されている設定を使用します。
ナビゲーションペインで [バックアッププラン]をクリックし、[バックアッププランを作成]をクリックします。

バックアッププランを作成の画面で以下を入力し、下にスクロールして [プランを作成]をクリックします。

  • 開始する方法を選択してください : [既存のプランから開始]を選択
  • プランを選択 : [Daily-35day-Retention]を選択
  • バックアッププラン名 : プラン名を入力(今回はAurora_snapshot)

バックアッププランが作成されました。
この状態だとどのリソースのバックアップを取得するかを指定していませんので、 [リソースを割り当てる]をクリックしてリソースを割り当てます。

リソースを割り当てるの画面で、以下を選択し、[リソースを割り当てる]をクリックします。

  • リソース割り当て名 : 割り当て名を入力(今回はAurora_snapshot)
  • 割り当て単位 : リソースIDを選択
  • リソースタイプ : Auroraを選択
  • クラスターID : 現在稼働しているAuroraを指定

これで設定は完了です。あとはバックアップが取得されるのを待ちます。
ナビゲーションペインの [ジョブ]をクリックするとバックアップジョブの確認ができます。

ジョブが動いたので、Auroraのスナップショットを確認します。
マネジメントコンソールでAuroraのコンソールを開き、ナビゲーションペインの [スナップショット]をクリックし、バックアップサービスのタブをクリックします。ここで、AWS Backupで取得したスナップショットを確認できます。

まとめ

AWS BackupでAmazon Auroraのスナップショットがとれるようになりました。AWS Backupで対応サービスが増えてきているので、よりバックアップの管理がしやすくなります。定期的に自動でバックアップ取得やリージョン間コピーができますので、バックアップに課題をお持ちの方は使ってみてはいかがでしょうか。

また、本ブログの内容は2020/6/17(水) 12:00よりYouTube Liveで配信される「30分でわかる AWS UPDATE!」でも取り上げる予定ですので、ぜひご覧ください!
もしリアルタイムで見逃しても、アーカイブ動画から内容を確認できます。

Amazon CloudSearchにSlackのメッセージを格納して検索してみた話

$
0
0

こんにちは!技術2課の濱岡です。
どうぶつの森でサメが釣れはじめてちょっと釣りが楽しくなっています。
背びれが見えている魚ばかり釣ってしまいますね。

さて、今回はAmazon CloudSearchにSlackのメッセージを格納してそれを検索してみようというのをやってみます。

こちらもよろしければどうぞ
Amazon CloudSearchとAmazon Elasticsearch Serviceを実際に触ってみた

目的

弊社Slackでは技術的な質問したり、ノウハウを共有するチャンネルがあります。
その情報を格納して検索できれば面白いかなと思いまして、今回はそのチャンネルの情報を取得してAmazon CloudSearchで検索してみるというのをやってみます。

Pythonを使ってSlackのメッセージを取得し、jsonでファイルに格納してそれをAmazon CloudSearchに入れて検索してみます。

今回は、Pythonは3.7.3とPythonのモジュールであるRequestsとSlackのAPIのconversations.historyを使用しました。

Slackのメッセージの取得

まずはSlack Appの作成

メッセージの取得をするためにまずはSlack Appを作成します。
ここにまずアクセスします。
そしてCreate New Appを押します。

Slack Appの名前とワークスペースを選択してCreate Appを選択します。

名前やアイコンなどはお好みで設定してください。

メッセージを取得するための権限をつけます。
OAuth&Permissionを押します。
そしてAdd an OAuth Scapeをクリックして以下を追加してください。

これでメッセージの取得ができるようになります。

そして上にスクロールするとInstall App to Workspacesがあるのでそれを押して自分のワークスペースにインストールします。

トークンが発行されたら準備完了です!

メッセージを取得してみる

今回、トークンやチャンネルIDなど必要な情報は環境変数から取得しています。
SlackのAPIのURLはこちらから確認してください。
SlackのチャンネルIDはブラウザ版のSlackから取得したいチャンネルを押してそのURLの末尾の英文字列になります。
とりあえず100個メッセージを取得してみました。

import json
import os
import requests

from dotenv import load_dotenv


#環境変数の取得
load_dotenv()
slack_channel_id = os.environ["SLACK_CHANNEL_ID"]
slack_api_url = os.environ["SLACK_API_URL"]
slack_api_token = os.environ["SLACK_API_TOKEN"]


def get_history():
    params = {
              "token":slack_api_token,
              "channel":slack_channel_id,
              "limit":100
              }
    data = requests.get(slack_api_url, params=params)
    json_data = data.json()

    return json_data

取得したメッセージからjsonのファイルを作成

このままだとAmazon CloudSearchには入れられないのでデータを綺麗にしていきます。
今回、検索用に使うのはSlackのメッセージのテキストだけにしたいのでそれだけをjsonファイルに格納していきます。

import json


def conversion_json(dict_data):
    respons_data = []
    index_number = 0

    for value in dict_data["messages"]:
        respons_data.append({"type":"add",
                              "id":str(index_number),
                              "fields":{
                              "message":value["text"]
                             }
                             })
        index_number+=1

    return respons_data


def create_json_file(data):
    with open("sample.json", "w") as file:
        file.write(json.dumps(data, indent=4, ensure_ascii=False))

作成したjsonファイルの中身はこんな感じです。

[
    {
        "type": "add",
        "id": "0",
        "fields": {
            "message": "Slackのテキスト"
        }
    },
    {
        "type": "add",
        "id": "1",
        "fields": {
            "message": "Slackのテキスト"
        }
    },
・
・
・
  {
        "type": "add",
        "id": "99",
        "fields": {
            "message": "Slackのテキスト"
        }
    }
]

Amazon CloudSearchに入れて検索してみる

ドメインの作成

まずは、ドメインを作成していきます。
Amazon CloudSearchのマネージメントコンソール上からCreate a new search domainを押します。

Search Domain Nameはお好きな名前で大丈夫です。
私はtestdomainにしました。
Desired Instance TypeとDesired Replication Countは今回はdefaultにしておきます。
設定できましたらContunueを押します。

次はindexを作成します。
上で作ったjsonファイルを読み込ませれば大丈夫です。
今回はローカルからファイルをアップロードするのでAnalyze sample file(s) from my local machineを選択してファイルをアップロードしてください。
選択できましたら、Continueを押します。

indexの確認画面がでますので問題なければContinueを押します。

次にポリシーを選択します。
Search and Suggester service: Allow all. Document Service: Account owner only.を押してポリシーが表示されましたらContinueを押します。

確認画面がでますので問題なければConfirmを押してください。

この画面がでましたらOKを押してください。

ドメインの作成まで10分ほどかかるので待ちます。

データのアップロード

いよいよデータのアップロードです。

Update Documentsを押します。

File(s) on my local diskを選択して作成したjsonファイルを選択してContinueを押します。

確認画面がでますので問題なければUpload Documentsを押します。

最後にFinishを押します。

これでデータのアップロードは完了です!

検索してみる

データをアップロードしたらRun a test searchというのが表示されていると思います。
そこにキーワードを入力してGoを押すと検索ができます。

こんな感じで検索ができます!

まとめ

今回はAmazon CloudSearchにSlackのメッセージを格納してそれを検索してみました。
ここから色々できそうなので試してみようかと思います。
また、何かできましたらブログに書くかもしれません。

以上、濱岡でした!

[Docker入門]Docker Composeの概要と使用法

$
0
0

はじめに

こんにちは。孔子の80代目子孫兼技術5課の孔です。暑い日々が続いております。サーバーワークスは4月から在宅勤務を続けておりますが、エアコンをどんどん回したら電気代が7,000円請求されました。これはあかんと思い、暑い時は冷たい水でシャワーを浴びることに最近切り替えました。すると水道代が7,000円請求されるという、四面楚歌の困窮に陥っている近況報告です。無一文の人間であっても快適な夏を過ごせる方法ご存知の方は、ぜひ共有してください。

そういうことで、今回はDocker入門シリーズ第5篇、Docker Composeとなります。Dockerではよりコンテナを快適に使うため、複数のツールを提供しています。その中の一つがDocker Composeとなります。Docker Composeは複数のコンテナをまとめて作成できるツールとなります。今まで紹介したブログ内容でコンテナを作成しようとすると、コンテナを一個ずつ作成し、それぞれのネットワークやボリューム、コマンドなどをそれぞれのコンテナを作成するたびに設定しないといけなかったですね。それをアプリで必要な複数のコンテナを同時に作成できるようにまとめて作成できるようなツールがDocker Composeとなります。ここまでが簡単な紹介で、もう少しDocker Composeを掘り下げてみましょう。Let’s get it!

Docker Composeとは?

Docker Composeをもう少し具体的にみてみましょう。先ほど説明しましたように、Docker Composeは複数のコンテナを同時に定義に、まとめて作成できる、Dockerが提供するツールとなります。設定ファイルはyaml形式で定義します。例えばこのような書き方になります。

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

具体的なイメージを掴むために、上記のyamlを簡単に解説します。

まず1行目のversionですが、Docker Composeには複数のバージョンがあります。バージョンによって書き方や機能が少し変わってきますので注意が必要です。具体的にどのような違いがあるかはこちらのドキュメントを参考にしてください。

2行目のservicesですが、ここからコンテナを定義していきます。Docker Composeでは一つ一つのコンテナをserviceで定義します。servicesのインデントが一つ下がったところに「web」と「redis」がありますが、こちらがそれぞれのコンテナとなるのでこのDocker Composeファイルは2つのコンテナをまとめて作成するものとなります。

それぞれのコンテナをみてみると、build、ports、imageという言葉が出てきます。buildは前回紹介したdocker image buildと同じく、カレントディレクトリにあるdockerfile(購読点がついてるとカレントディレクトリのdockerfileを指すことは紹介しましたね!)をビルドしてそのままコンテナにします。portsはdokcerfile同様、どのポートをどのホストのポートにマッピングするかを表してます。webサーバはカレントディレクトリにあるweb用のdockerfileをコンテナにし、5000ポートでリスニングしてますね。redisのところにあるimageはどのイメージを使ったコンテナなのかを定義するところとなります。特にdockerfileなどでカスタマイズせずそのまま公式を使ったり、既にビルド済みであるイメージを使うのであればこれで大丈夫です。

このように、Docker Composeはserviceという名前のコンテナをまとめて定義し、一貫した複数のコンテナ環境を作成できることがイメージできたのではないかと思います。Docker Composeのymlファイルで使えるコマンドはこちらにレファレンスがあるので、もっと知りたい方はぜひみてみてくださいね。それでは、実際どのように動くのかをみてみましょう。

使ってみよう!

Docker Composeにもいろいろなコマンドがあります。まずはDocker Composeを使うためには「docker-compose」というコマンドを使います。docker-compose.ymlに定義されたコンテナを作成するにはdocker-compose upを入力します。先ほどのdocker-compose.ymlファイルだとdockerfileが特にないので、以下のdockerfileをカレントディレクトリに追加してください。

FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

pythonが動作する環境を整えるdockerfileとなります。ADDとWORKDIRが出てきました。それぞれカレントディレクトリの内容をコンテナの「/code」パスに追加する、ビルドの際に「/code」ディレクトリでRUNとCMDを実行する、という意味となります。

もちろんapp.pyも、requirements.txtもないので追加しましょう。まずapp.pyです。

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    count = redis.incr('hits')
    return 'Hello World! I have been seen {} times.\n'.format(count)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

そしてrequirements.txtです。

flask
redis

以上のファイルを追加し、docker-compose upコマンドを入力すると、buildから始まってコンテナの作成が終了したら自動的にコンテナの内部が見れるようになります。

kong@KongnoAir docker % docker-compose upBuilding web
Step 1/5 : FROM python:3.4-alpine
 ---> c06adcf62f6e
Step 2/5 : ADD . /code
 ---> e20c96150279
Step 3/5 : WORKDIR /code
 ---> Running in 003e58261e54
Removing intermediate container 003e58261e54
 ---> 6686388484c1
Step 4/5 : RUN pip install -r requirements.txt
 ---> Running in 6df432d4855c
DEPRECATION: Python 3.4 support has been deprecated. pip 19.1 will be the last one supporting it. Please upgrade your Python as Python 3.4 won't be maintained after March 2019 (cf PEP 429).
<pythonのパッケージインストールログ>
Removing intermediate container 6df432d4855c
 ---> 493fd18cb862
Step 5/5 : CMD ["python", "app.py"]
 ---> Running in a10fac2d68ad
Removing intermediate container a10fac2d68ad
 ---> bfd47533d4f8
Successfully built bfd47533d4f8
<省略>
web_1    |  * Debugger PIN: 284-351-253

localhost:5000に入ってみると、redisに何回訪問したのかを数えた数字が格納され、更新するたびにカウントが上がることが確認できます。簡単にwebサーバとredisサーバをまとめて作成できますね!

また、createコマンドでサービス作成、psコマンドでプロセス検索、killコマンドでサービスのコンテナ起動中止、rmコマンドでサービスの削除が基本的な操作となります。より多くの操作コマンドを知りたい方はこちらのドキュメントをご参考ください。

最後に

今回はDocker Composeについてみてみました。コンテナを一個一個管理するのはとても大変なことですので、このツールを使うことでコンテナをより簡単に管理できることがわかりますね。今回使った資料は全部Dockerの公式ページにあるものですので、もっと詳細を知りたい方は是非公式ドキュメントもみてください。「使ってみよう!」のパートはこちらのページを参考に作成したものとなります。

次はDockerで提供するオーケストレーションツールであるswarmについてみてみましょう。暑い日が続いておりますが、ぜひ健康には気をつけてくださいね。それではお元気で!

Viewing all 1210 articles
Browse latest View live


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