Amazon Auroraの自動停止をAmazon EventBridge + AWS Lambdaでコントロールする


きっかけ

個人のAWSアカウント上でハンズオンのために基本的なAWSリソースが使用できるようにしていて、Amazon Auroraもその対象に含めているのですが、テスト用でr5.largeの最低限の構成でAuroraクラスターを起動しているだけでもそれなりのコストがかかってしまうのに加えて、Amazon RDSにしてもAmazon Auroraにしてもそうなのですが、手動で停止しても7日間経過すると自動的に起動するという謎仕様になっているので、コスト削減のためにも、必要な時だけ起動して、それ以外は定期的に起動状態をチェックして、もしも起動していたら止める、という仕組みを作れないかなと考えていました。

で、ふと気が付いたのですが、そういえば前回Amazon EC2インスタンスの起動停止をAmazon EventBridge + AWS Lambdaでコントロールする仕組みを既に導入していたので、これをそのまま応用すればいいじゃない、ということで、サクッと実装してしまおうということになったのでした。

Lambda関数作成時にまずは実行ロールの設定を

例によってLambda関数を作成していくのですが、今回は気をつけなければいけない点がひとつ。Lambda関数からAuroraに対する実行ロールを作成しなければいけません。一旦デフォルトの設定で実行ロールを作成した場合は、作成されたロールに対してIAMポリシーを追加してあげる必要があります。でないと、Lambda関数を実行した時点でアクセス権限エラーが出力されます。

今回はひとまず、Amazon Auroraがプライベートサブネット上に構成されていることと、インターネット側からLambda関数が実行されることがないので、取り急ぎAWS管理ポリシーであるAmazonRDSFullAccessをつけてしまいます。ただし、これはあくまでもとり急ぎなので、最小権限の原則に基づいて後々必要な権限のみをアタッチするカスタマー管理ポリシーを実装することにしましょう。

Lambda関数の実装

基本的にやっていることは、EC2インスタンスの自動的な起動停止と一緒で、Auroraクラスターに付与したタグを持ってきて、タグに合致するAuroraクラスターを丸ごと停止させてしまいましょう、という内容です。コードはこちら。

import boto3
import logging
import traceback

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):

    region = event['Region']
    client = boto3.client('rds', region)

    rds_clusters = client.describe_db_clusters().get('DBClusters', [])

    print ("Found " + str(len(rds_clusters)) + " Aurora Clusters")

    for rds_clusters in rds_clusters:

        try:
            cluster_status = rds_clusters['Status']
            cluster_ids = rds_clusters['DBClusterIdentifier']
            cluster_arn = rds_clusters['DBClusterArn']

            print ("DBClusterIdentifier is %s and Status is %s" % (cluster_ids, cluster_status))

            tags = client.list_tags_for_resource(ResourceName=cluster_arn).get('TagList', [])

            print ("Tags is %s" % tags)

            for tags in tags:
                if tags['Key'] == 'AutoStop':
                    print ("Current instance_state of %s is %s" % (cluster_ids, cluster_status))

                    if cluster_status == 'available':
                        client.stop_db_cluster(DBClusterIdentifier=cluster_ids)
                        print ("Aurora Cluster %s comes to stop" % cluster_ids)
                    else:
                        print ("Instance %s status is not right to start or stop" % cluster_ids)
            return {
                "statusCode": 200,
                "message": 'Started automatic stop Aurora clusters process. [Region: {}]'.format(event['Region'])
            }

        except Exception as e:
            logger.error(e)
            print(traceback.format_exc())
            return {
                "statusCode": 500,
                "message": 'An error occured at automatic stop Aurora clusters process.'
            }

ここで躓いたポイントとしては、Auroraクラスターに設定したタグの情報を取得してくること。EC2インスタンスの時は、

responce = client.describe_instances(Filters=[{'Name': 'tag:AutoStartStop', 'Values': ['1']}])

でいけたのですが、同じ要領でコードを書いても、テスト実行時にどうもうまくいかなかったので、一旦起動しているAuroraクラスターの一覧を取得して、各クラスターごとに、arnを取得してそこに紐づいているタグを取得してくる方式に実装方法を変更しました。さらに、EC2インスタンスの時はタグのvalueの値によって制御していましたが、今回はタグのkeyが存在するかどうかで判定する方式に変更。

あとはEventBridgeをトリガーとしてcron式とlambda_handlerに送り込むイベント引数を追加して設定し、実行に失敗した時だけ自分の携帯電話にSMSを送信するAmazon SNSトピックを設定して終了です。

この方法、今回はAuroraクラスターに対して実行しているため、stop_db_clusterメソッドを実行することでクラスターに紐づいているrdsインスタンスを一気に落としていますが、Amazon RDSを使用している場合でも、ここのメソッドを書き換えてあげるだけで各々のrdsインスタンスを自動停止したいときに適用できるので使い回しが効くと思います。

自動化する方法は意外とハードルが低いかも

もちろん適切なマネージドサービスがあればそれを使うに越したことはないのですが、コードの実装に対する気分的なハードルを下げることと、Lambda関数の仕組みの理解のためにも、せっせとPythonを書いてこのような形で自動化できそうな仕組みは可能な限り自動化していこうと思います。

まぁエレガントではない泥臭い方法なのかも知れませんが、このようなアプローチでいけば、さまざまな処理を自動化していく方法は意外とハードルが低いのかもしれませんね。

カテゴリー: AWS | タグ: , , , | コメントする

今更ながらApple Magic MouseとMagic Keyboardを仕事用に導入


はじめに

コロナ禍で在宅勤務制度が本格的に始まってからかれこれ1年8ヶ月が経過しました。当初は会社から貸与されたPCで仕事をしていたのですが、まぁこれがなんとも使いにくかったのと、PCの管理が結構大変なので、自宅で眠っていたMacBook Air(Retina, 13-inch, 2018)を引っ張り出し、VMware Holizon Clientを使用してオフィスに置いてあるPCにリモート接続するように運用を変更しました。ついでにひょんなきっかけで絶妙なタイミングでHP M22f FHDディスプレイが手に入ったので、個人的には在宅勤務環境はほぼほぼ出揃った感じになりました。

なんで今更マウスとキーボードを?

そんな感じで環境はだいぶ整ってきたのですが、MacBook Air(Retina, 13-inch, 2018)で仕事している上での欠点って、やっぱりバタフライキーボードなんですよね。普段使いしている程度であれば慣れるのですが、これを仕事で1日中使い続けているとキーストロークの浅さがなかなか辛い。そして辛いので肩が凝ってくるという。

とはいえWindowsの環境に合ったキーボードを探してみたところ、どうも一長一短でなかなかこれというものがない。まぁキーマッピングはうまく変換すればいいので、できるだけ使い慣れたものをということで結果的に購入したのが、Apple謹製のMagic MouseMagic Keyboard。Magic Keyboardは既にTouch ID対応のものが出ていますが、仕事用に使用しているのはIntelなので、まぁコストパフォーマンスを考えても普通のものでもいいでしょって感じで。

あとは、Windows環境上で仕事をするのにマウスって必須ですねぇ。もちろん、Macのトラックパッドはいろいろな意味で優秀なので、違和感ない操作感はあるのですが、それでも台画面上で操作しようとするとそれなりにストレスがかかるもので。

そういったストレスを少しでも軽減するためにも、マウスは必要な感じですね。

だいぶ楽になった

ここまで一通り取り揃えたことで、在宅勤務もだいぶ楽になってきました。何が楽になったかって、狭いデスクの上にモニターとMacBook Air2台という細々した状況がだいぶすっきりしたこと。MacBook Air (M1, 2020)の方は音声用に使用しているので、1台は置いてあるのですが、MacBook Air(Retina, 13-inch, 2018)の方はクラムシェルモードにしてデスクとは別の場所に置いているので、スペースがすっきりした分、執務スペースが増えて結構仕事の効率が上がってきました。

やっぱりデスク上を効率的に使用できるのって、在宅勤務を進めていく上では大事ですね。

これからも在宅勤務は続くので、改善できるところを少しずつ改善していって、快適に生産性が上がるように工夫していきたいと思います。

カテゴリー: Work | タグ: , , | コメントする

WordPressをさくらインターネットからAmazon Lightsailに移行した話


はじめに

このWebサイト、実は2010年からさくらインターネットの共用ホスティングサーバで長らく運用してきたのですが、最近色々あって復旧作業に手間取っているうちに、何を思ったのかWordPressの環境を吹っ飛ばしてしまったのです。お恥ずかしい限り。

パブリッククラウドに関わる仕事をしている割には、自分の環境は旧来のホスティングサーバということもあって、Amazon Web Servicesに移行しようかなと思いつつも、相応の構成でガッツリ組もうとするとそれなりにコストがかかるし、とはいえホスティングサービス使い続けるのもなぁということであれこれ考えていました。

Amazon Lightsailに関しては、AWSマネージメントコンソールのログイン画面で当たり前のように表示されるので名前は知っていました。ただその内容については全く知らず、というか要はちゃんと調べていなかったんですね。

で、実際にどういったサービスかを調べてみてびっくり。驚くほど低コストで、自分のような小規模なWebサイトの運用に使えるじゃん! ということで、さっさと乗り換えることにしたのでした。

移行は超簡単

簡単というか、ma-ya’s CREATE / WEB DESIGNさんの記事、”[Lightsail] さくらインターネットからAWS LightsailにWordPressを最速で移行する – スモールスタート編“と、Naoki Sekiguchiさんの記事、”さくらのVPSから Lightsail へ引っ越した | Like@Lunatic“に丁寧に解説されている通りのステップで、あっという間に移行が完了してしまいました。

上記2つの記事には本当に感謝しています。ありがとうございます!

つまずいたポイントがあったとすれば、AWSのお約束で、Lightsail側のUIが変わったせいなのか、ドメインのDNSの向き先変更を行うときに、Aレコードの追加の仕方がよくわからなくてネームサーバーの設定だけを先にさくらインターネット側にしてしまったことで、名前解決ができなくなり、Lightsail側の設定をよくよく見てみたら、しれっと[レコードの追加ボタン]が存在していることに気付いたので、慌ててAレコードを追加してあげてWordPressがインストールされているインスタンスの再起動をしたら、きちんと名前解決できるようになったといったくらいでしょうか。

どうもDNS周りのことはなかなか覚えられないだけに、ここはもうちょっと勉強しなきゃなぁとか思いました。

そこを乗り越えればサクサクで移行作業はおおむね60分程度で完了。無事にお引越しが完了しました。後はさくらインターネット側のお掃除をしてあげれば終了です。

使用していたWordPressのプラグインのうちの一部がどうもうまく動かないなぁという課題が残っていますが、それは後々調整していく感じで。

個人で使用するには十分なスペック

使用しているインスタンスは1GB RAM、1vCPUなので、EC2インスタンスで初年度無料枠で使用できるt2.microのインスタンスタイプと同等ですし、現時点では片方のAvailability Zoneにしか配置していないので、仕事柄若干不安はあるのですが、大規模なAZ障害でも起きない限り、個人利用するという前提で考えれば十分なスペックと環境なのではないかと思います。

後この先できることとすれば、ドメインも移管して、Amazon Route 53に移そうかどうしようかというところですかね。これができれば個人で利用している学習用のAWSアカウント上のリソースと連携して色々と実験することができるし。ここはこの先かかってくるコストとのご相談というところで。

終わりに

パブリッククラウドの環境を使ってみたいなぁと思いつつも、コストを考えて躊躇していて、なおかつAWSに関して少しでも知識を持っている人にとっては、Amazon Lightsailを使用するという選択肢は十分にあり得るのではないでしょうか。もちろん環境を維持していくことに関しては責任共有モデルが(多分)適用されるので、それなりに必要なことがあるかなと思いますが、まずはお手軽にAWSの環境を体験してみたいという人にとって絶好の選択肢なのではないかと考えています。

カテゴリー: AWS, Private | タグ: , , | コメントする

仕事で心がけていることと知識や経験の共有手段


はじめに

先日、勤務先の事業部が月に1回発行している社内報に、インタビュー記事を寄稿する機会があったのですが、あまりにも文字数が多過ぎたらしく、一部割愛されてしまったので、この機会なので自分の仕事に対するスタンスというか、心がけていることをアウトプットする意味でも、ここに書き留めておこうと思います。

心がけていること

  1. 基本的に新しいもの好きであること
  2. どんな役割の人の経験や話も自分の勉強になると思って傾聴すること
  3. 自分が得た経験や知識をできるだけ共有すること

1に関しては、まぁそうですよね。ITの世界はとにかく移り変わりが激しいし、トレンドが大きく変わってくるわけで。特にプラットフォームの世界ではオンプレミスな環境からのクラウドシフトが急速に進んでいっていて、たまたま私の場合はAmazon Web Servicesに関わることでそのシフトの波に乗っているのですが、それでも日々発表される新しいサービスやアップデートに対して追いついていくのに必死なわけで。

それでも新しいものに興味を持って、それが何ものであるのかを理解しておくというのはとても大事なことなんじゃないかと思っています。

2についてもそれに関連することなのですが、年齢や経験年数、職位に関わらずその人の経験やそこから学んだことに関しては、真摯に傾聴することが大事なんじゃないかと思っています。この辺り、座学の世界ではなかなか得られるものではないし、他の人の経験を糧にすることで自分の知見も自ずからアップデートされていくので、経験に基づく学びというものを傾聴して理解することは大事なんじゃないかと。決して基礎的なことだからと鼻で笑うというのはNG。

3が一番大事なことなんじゃないかなと思っています。いわゆる集合知の世界ですよね。もちろん万能な人がこの世の中にいればそりゃすごいなと思うんですけれども、そういう人がたくさんいるわけではないし。けれども各々の人がそれぞれに得意分野を持っていて、いわばネタを持ち寄るような形で共有し合うことが、結果としてチームのボトムアップにつながっていくんじゃないかなと思っています。

そのためにも、まずは自分が得た知識や経験を、手段はどんな方法でも構わないので共有していくこと。自らがナレッジを共有していくために動いていくこと、それがとても大事なことなのではないかなと思っています。

経験や知識を共有するための手段

手段としてはストックとフローはとても意識しています。タイムリーな情報をフローとしてタイムリーに共有するのであれば、Slackなどのビジネスチャットを使って自分の理解を交えながらささっと共有、もしも自分の得た知識や経験を、プロジェクトの先々に対して何かしらの形でストックとして記録に残しておくのであれば、Confluenceに書き留めておくようにします。情報を共有するためのリポジトリを作るということですね。

Confluenceはアジャイル型の開発を進めていく上では非常に有用なツールなのですが、そういう手法でなくても、文章として散らばってしまいがちな情報をWikiのようにリポジトリ管理するにはものすごく便利な手段だと思っています。誰かが書き記した情報をアップレートしたいと思えば誰でもアップデートすることができるし、コメントを書いていくことでFBにもつながる。プロジェクトをボジティブに進めていく上ではとても使いやすいんじゃないかなと思います。

Confluenceはお仕事で使っているので残念ながら実例をお見せすることができないのですが。

その代わりに、個人的にはそのネタを仕込むための手段として、Day OneというmacOS向けのアプリケーションを使っています。元々はライフログをローカルで書き留めておくためのアプリケーションなのですが、マークダウン形式で整理しながら書き留めていくことができるし、時系列やタグで管理できるので、これなんだっけ? と振り返って情報共有のネタにするときにとても重宝しています。このBlogのネタも、大抵はここから引っ張り出していることが多いです。

もちろんそれぞれにストックとして記録に残しておく手段があると思うので、そこはやりやすい形で全然問題がないと思うのですが、ちょっとだけご紹介ということで。

アウトプットに対するフィードバックを期待しすぎないこと

案外これ大事なんですけれども、自分がアウトプットしたことに対するフィードバックを過剰に期待しすぎないことも大事です。仮に自分が10個のアウトプットを出したとしても、それに対して10個のフィードバックが返ってくることは基本的にないです。せいぜい2個か3個くらいかなと思います。10個返ってくることを過剰に期待しすぎると、逆にそのことが重荷になったり、ネガティブな感情を抱いたりしてしまうことになるので、そこは程々に。

じゃあ結局は自己満足の世界なのかと言われてしまうとそのバランスを取ることがものすごく難しいのですが、けれどもこういった取り組みって誰かが始めないことには将来的に集合知として育たないことになってしまうので、自分はその種まきをしているんだっていうくらいに思っておけばいいんじゃないかと思います。

最後に

まずは自分の力でできることを種まきしていけばいいんだと思います。短期的にそれが育たなくても、少しずつ根を張って、結果として未来のどこかでそのナレッジが生かされるようになれば、目的は果たすことができると思うので。

カテゴリー: Work | タグ: | コメントする

Amazon DevOps Guru for RDSを試してみる


はじめに

2021年のAWS re:Inventでも魅力的な新しいサービスが発表されたり、サービスのアップデートが発表されたりと、日々興奮しつつ寝不足の日々を過ごしておりました。

数ある発表の中でも個人的に気になったのが、Amazon DevOps Guruが、Amazon DevOps Guru for RDSとして、Amazon Auroraに対応してくれたこと。ここのところお仕事で、WordPressをホストしているAmazon Auroraのパフォーマンス問題に悩まされており、それを一発で解決する手段として、これは使えるんじゃないかとピンときて、早速設定の仕方だけでもハンズオンしておこうとなったわけです。

Amazon DevOps Guru for RDSで何ができるのかを平たく書くと、機械学習(Machine Learning)を使用してAmazon Auroraクラスタを構成するrdsインスタンスに関する各種メトリクスを分析し、ホストリソースの過剰使用、データベースのボトルネック、SQL クエリの誤動作といった、パフォーマンスに関連するさまざまなデータベースの問題を自動的に特定して分析してくれること。

特にWordPressをAWS上でホストしている場合、コンテンツの生成はほとんどの場合SQLクエリによって動的に生成しているので自ずとAmazon Auroraに対するパフォーマンスをチューニングすることが不可欠になってきますし、単純にAmazon Auroraクラスタを構成するrdsインスタンスだけでなく、SQLクエリの改善も必要になってきます。そのためにも有効な手段なのではないかということで、ちょっと試してみようかということになりました。

設定方法

設定方法は至って簡単だったりします。ここではサンプルのAmazon Auroraを使用して設定方法をハンズオンしてみます。

分析対象のrdsインスタンスにタグをつける

ここではテスト用のAuroraクラスタと、シンプルなrdsインスタンスを作成していますが、本番のワークロードでもやることは同じです。

以下の通り、”key: Devops-Guru-*”, “value: True”というタグの設定を、分析したい対象となるrdsインスタンスにまずは仕込んであげます。なぜかというと、本番ワークロードでは多数のAWSリソースが動いているため、Amazon Auroraのみにスコープを絞り込んで分析を行いたいためです。

先に分析対象のリソースを絞り込んでおく

次に、Amazon DevOps Guru上で、分析に必要なコストを圧縮するために、[設定]-[Analysed resource]で分析対象のリソースを絞り込みます。

  • Choose resources to analyzeから、[Tags]のラジオボタンを選択。
  • [Tag key]のプルダウンリストの中に、先ほど指定した”Devops-Guru-RDS”が選択できるようになっているため、これを選択。
  • Choose tag valuesから、[Choose specific tag values]のラジオボタンを選択。
  • [Select tag values]のリストの中から、先ほど指定した”true”のチェックボックスを選択。
  • [保存]ボタンをクリック

これで設定完了です。あとはダッシュボードから有効化するだけ。ちなみに、分析対象のリソースは、リソースが削除されるまで有効化されっぱなしになるので十分にご注意ください。

一応念のためコスト算出もしておく

それでもコストが気になるなっていう人は、コスト見積りツールからコストを算出しておきましょう。やり方はほとんど似ていて、

  • リソース分析の見積りカバレッジから、[Tags on AWS resources in the current Region]ラジオボタンを選択。
  • [Tag key]プルダウンリストの中に、先ほど指定した”Devops-Guru-RDS”が選択できるようになっているため、これを選択。
  • [Tag value]プルダウンリストの中に、先ほど指定した”true”が選択できるようになっているため、これを選択。
  • [月額コストの見積り]ボタンをクリック。

これでコストの算出が開始されます。

ここまでできたら、レポートが出力されるまで気長に待ちましょう。初回レポートの出力には、ワークロードにもよりますが数時間かかることがあります。

終わりに

今回はサンプルのAmazon Auroraで試してみたため、全然問題が発生しなかったのですが、ある程度のトランザクションのあるAmazon Auroraクラスタ上のrdsインスタンスでは、パフォーマンスに関するなんらかのレポートが出力されます。もちろん出力されたタイミングでSNSトピックによって通知を出力することも可能です。

お仕事で絶賛お試し中なところでもあるのですが、この存在が特にWordPressをAWSを用いて運用改善していく際の大きな助けになればいいなと思っています。

カテゴリー: AWS | タグ: , , | コメントする

MacBook Air (M1, 2020)に買い替えて約1年が経過


2021年の初めに、それまで使用していたMacBook Air (Retina, 13-inch, 2018)からMacBook (M1, 2020)に買い替えて約1年が経過しました。スペックは、

  • 8Core CPU
  • 16GB Memory
  • 512GB SSD

と、メモリをいつも通り2倍に増設しています。

まぁとにかく速い

ここ近年、CPUの性能が格段に向上したおかげで、体感的なパフォーマンスというのがそんなに気にならなくなってはきましたが、それでも特にマシン自体の起動時や、少し重めのアプリケーションを起動させる時など、速いなという印象は強く受けています。

最近は在宅勤務下で、一旦お蔵入りしていたMacBook Air (Retina, 13-inch, 2018)を併用しているのですが、同じMacBook Airなのにチップセットが違うだけでこんなにパフォーマンスが違うものなのか、ということを改めて痛感させられます。

キーボードが打ちやすい

先代のMacBook Airで採用されていたバタフライキーボードは、使えば慣れたもののなんだか打鍵感がパタパタしていて場合によってはキーを打ちにくいなぁという印象を感じていたのですが、MacBook Air (M1, 2020)ではシザーキーボードが復活したことで、打鍵感が確実に向上しました。いくらキーを打っていても疲れることがなくなりました。

それと、先代のバタフライキーボード、使い続けていくとだんだんキーコーティングが剥げてくるんですよね。自分のもまさにそうで、矢印キーなどはどっち向きの矢印なんだかよくわからない状態(なので買い替えの際に下取りに出すことを躊躇した)なんですけれども、現在は1年間使用していてもコーティングが剥げるような事態には、今のところなっていません。確実に使用する頻度は高いのですが。

何に使っているのか

日常の作業はほとんどこの1台で完結しています。Webの閲覧、ドキュメントやメールの作成などは当たり前として、Visual Studio Codeを使用して自前でちょこちょこ開発作業などもしているので、軽い作業からそれなりに重い作業までやっている感じです。それでもストレスを感じさせず、重量の軽さも相まってどこにでも持っていくことができる点で、確実に手が離せなくなっているのは確かですね。1日平均で10時間くらいは何かしらの用途に使っているかもしれません。

これからApple シリコンを搭載したMacもどんどん進化していくのは確実なんですが、この1年間使い倒している限りでは、少なくともApple Careの保証期限が切れるまではこれ1台で切り盛りできそうな感じです。下手すれば5年くらい使えるんじゃないかな。通常は3年周期で買い替えをおこなっているのですが、だいぶ手に馴染んできているのでこれからも丁寧に使っていくつもりです。

カテゴリー: Private | タグ: , , | コメントする

Amazon EC2インスタンスの起動停止をAmazon EventBridge + AWS Lambdaでコントロールする


きっかけ

仕事の中で複数持っている自分のタスクを効率よくこなしていくのとともに、散らばっている情報を一つに集約して常に整理していくのはとても重要なことだと思っています。前者に関して、自分のプロジェクト内のタスクコントロールはヌーラボさんのBacklogで完結していて、ものすごく重宝しているのですが、Backlogで管理している課題よりももっと細かい粒度のタスクを個人レベルで管理するにあたって、ガントチャートレベルで期限日を重要度を意識しながらコントロールしていくのがどうも苦手なので、とりあえずこの目的を達するために管理の手段としてredmine使おうと思い、どうせだったら個人で保有しているAWSアカウントの中に、redmineのAMIを使用したEC2インスタンスを立ててしまえばいいじゃん、となったわけです。

ところが自分のAWSアカウント、使い始めてかれこれ数年になるので、残念ながら無料枠は使えません。なので、コスト削減のために、自分が普段のルーチンとしてタスクの棚卸をする時間帯だけ起動させるようにしたい、と思ったのがそもそものきっかけです。

せっかくならAWS Lambdaを使いたい

ちょうど同時進行で、AWS Lambdaの勉強を掘り下げていたこともあったので、せっかくならば自分でコードを書いてLambda関数を作り、その機能でコントロールさせてあげればいいなと。AWS Lambdaの特徴としては、

  1. インフラストラクチャの運用管理が不要
  2. イベントドリブンであること
  3. コスト効率が高い

の3つが挙げられるのですが、何気に2番目って、自分の観測範囲ではなかなか使われていなかったので、この機会に使ってみようと思ったわけです。使いたい時間だけ使えるようにすればいいので、Amazon EventBridgeを使ってLambda関数と連携してあげればOK。

というわけでさっくりとLambda関数上でワークフローを組み上げました。そんなに難しいことはしていません。

とりあえず器として”EC2-Auto-Start-Stop”というLambda関数を作成し、トリガーとしてEC2インスタンスを起動するためのEventBridgeトリガーと、EC2インスタンスを停止するEventBridgeトリガーを追加。一応念のため、ちゃんとEC2インスタンスが起動停止したよということをSMSとして送信するためのAmazon SNSトピックも送信先として追加。

これだけなんですけれどもね。

Amazon EventBridge側の設定

まず最初に、それぞれのEventBridgeのトリガーとして、今回はスケジュールで実行するので、起動・停止したい時刻をcron式で定義してあげます。

次に、イベントを起動してあげたいLambda関数を指定します。この時、EC2インスタンスのタグを読み取ってイベントを起動する、というやり方もあるのですが、自分の場合は、Lambda関数のevent引数の中に、起動対象のEC2インスタンスが所属するリージョン情報と、起動したいのか、停止したいのかを示すフラグをjsonで渡してあげるようにしました。

Lambda関数にコードを書く

ここで、いよいよLambda関数のコードを書いていきます。今回はサクッと書きたいためにラインタイムは”Python3.9″を選択。せっかくなのでアーキテクチャは採用されたばかりの”arm64″を選択します。

で、デフォルトで作成される”lambda_function.py”に書いたコードは以下の通り。

import boto3
import logging
import traceback

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):

    try:
        region = event['Region']
        action = event['Action']
        client = boto3.client('ec2', region)
        responce = client.describe_instances(Filters=[{'Name': 'tag:AutoStartStop', 'Values': ['1']}])
        target_instance_ids = []

        for reservation in responce['Reservations']:
            for instance in reservation['Instances']:
                target_instance_ids.append(instance['InstanceId'])
        
        print(target_instance_ids)

        if not target_instance_ids:
            print('There are not instances subject to automatic start or stop.')
        else:
            if action == 'start':
                client.start_instances(InstanceIds=target_instance_ids)
                print('Started Instancess.')
            elif action == 'stop':
                client.stop_instances(InstanceIds=target_instance_ids)
            else:
                print('Invalid action.')

        return {
            "statusCode": 200,
            "message": 'Finished automatic start or stop EC2 instances process. [Region: {}, Action: {}]'.format(event['Region'], event['Action'])
        }

    except Exception as e:
        logger.error(e)
        print(traceback.format_exc())
        return {
            "statusCode": 500,
            "message": 'An error occured at automatic start or stop EC2 instances process.'
        }

ざっくり解説すると、EventBridgeの入力の設定で設定したリージョン情報と起動・停止のフラグを読み込んで、EC2インスタンスのタグで自動起動停止設定が”1″(true)になっているインスタンスIDを探し出し、順繰りに起動または停止してあげるだけというものすごく簡単なコードです。簡単すぎて申し訳ない。。。

まとめ

こんな感じで、意外にも簡単に、EC2インスタンスを決まった時間に自動的に起動停止する仕組みが出来上がりました。

実際にこうして簡単なコードを書いてみることで、Amazon EventBridgeからLambda関数がイベントドリブンでどのように連携されていくのかということをハンズオンレベルで理解ができるというのはいいですね。

またこういった問題って、AWS認定SysOps アドミニストレーター アソシエイト試験(AWS SOA)でも出てきたりするので侮れないです。

これからもこんな感じで楽しみながらコーディングしたり設計したりしつつ、AWSの持つ各サービスの仕組みを理解していきたいと思います。

カテゴリー: AWS | タグ: , , | コメントする

ANA MILEAGE CLUB Bronzeのステータスに到達


2021年もCOVID-19の影響で外出自粛が求められている中ではありましたが、感染状況を見極めていきながら、20年近く利用しているANAに搭乗する事で支援していきたい、ということで、ワーケーションや親戚に会いに、羽田 – 福岡間を往復していたところ、どういうわけかANAマイレージクラブのBronzeのステータスに到達してしまいました。

JetLoversのログを辿るとこんな感じです。

  • 2021/3/21 NH243 HND – FUK (JA609A / 2K)
  • 2021/3/22 NH258 FUK – HND (JA811A / 2A)
  • 2021/6/25 NH245 HND – FUK (JA804A / 30J)
  • 2021/6/27 NH262 FUK – HND (JA808A / 7H)
  • 2021/8/28 NH245 HND – FUK (JA821A / 2K)
  • 2021/8/29 NH256 FUK – HND (JA816A / 1A)
  • 2021/10/30 NH247 HND – FUK (JA815A / 6G)
  • 2021/10/31 NH256 FUK – HND (JA834A / 5K)

普段なら羽田 – 福岡間4往復では、プレミアムクラスを使ったとしてもBronze到達条件になる30,000プレミアムポイントまでは到達できないのですが、2021年は2回プレミアムポイント2倍キャンペーンがあったのがかなり大きかったですね。そういう意味ではかなりラッキーなBronze到達だったのかもしれません。

何故このご時世に飛行機で旅行なんて、と眉を顰める方もいるかもしれませんが、航空機そのものが衛生面ではかなり安全な乗り物であるということと、搭乗便と座席番号がきちんと乗客名簿に記録されるので、万が一の時があっても行動を追跡してもらえやすいというところは大きいですね。なので逆に不特定多数の人が利用する新幹線の方が万が一の時のリスクは大きいのではないかという。

もともと福岡は好きな街ですし、なんなら移住したいくらいのつもりでいるので、2022年もガッツリ登場して、Bronzeのステータスの恩恵をいただきたいと思っています。

ANAは日本の航空会社の中では一番好きなので、苦境の航空業界の中にあっても引き続き搭乗して支援していきたいと思っています。

カテゴリー: Private | タグ: | コメントする

レイヤーを含むLambda関数からAmazon S3バケットにアクセスしようとして難儀した話


つい最近Lambda関数の実装をしていまして、その中で困ったことと解決したことがあったので、自分への備忘も兼ねて共有します。

一応エチケットシートとして。この記事は投稿時点(2021/6/20時点)において検証した結果に基づいており、今後Amazon Web ServicesのBoto3ライブラリの仕様が変更された場合には、必ずしもこの検証通りの結果にならない可能性があることだけ、ご了承ください。

やろうとしていたこと

  • Amazon S3バケットからS3.PutObjectを行う処理のみを、Lambda関数のレイヤーとして切り出す
  • 上記で作成したレイヤーをimportしているビジネスロジックの部分をLambda関数上で実装する
  • レイヤー、Lambda関数ともにPython3.8で実装
  • Lambda関数を実行すると、S3バケットにファイルが格納される

ちなみにレイヤーのコードはざっくりこんな感じです。もうほとんどBoto3のドキュメントのお作法そのまんまです。

import boto3

def put_object(fileObject, bucketName, filePrefix, Key):

    if filePrefix != '':
        key = filePrefix + Key

    s3 = boto3.resource('s3')
    object = s3.Object(bucketName, Key)

    response = object.put(
        Body=fileObject,
        ContentEncoding='utf-8',
        ContentType='text/plain'
    )

困ったこと

このレイヤーを含むLambda関数をリリースして、同じAWSアカウント内にS3バケットを作成。ブロックパブリックアクセスは有効にしています。

ブロックパブリックアクセスを有効にしている場合でも、デフォルトでは特に作成したS3バケットへのファイルの格納は普通にできる、と思っていたのですが、いざLambda関数を実行してみると、ファイルが格納されないわけです。で、デバッグのためにCloudWatch Logsの該当ロググループを確認すると、

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

お決まりのAccess Deniedが出力されているわけで。

危ないと知りながらも、一旦S3バケットのブロックパブリックアクセスを無効にしてみたり、それでも解決しないので、再度ブロックパブリックアクセスを有効にして、Lambdaの実行ロールに対してPutObjectとPutObjectACLを有効にしてあげるバケットポリシーを書いてみたりしてもどうにも解決せず、途方に暮れていました。

解決方法

鍵はバケットポリシーの書き方に違いない! というところまではなんとなく勘がついていたので、試しに以下のようにバケットポリシーを書き換えてあげたら、普通に該当するS3バケットにファイルが格納されるようになったではないですか!

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:sts::(AWSアカウント):assumed-role/(レイヤー名)",
                    "arn:aws:iam::(AWSアカウント):role/(Lambda関数の実行ロール)",
                    "arn:aws:sts::(AWSアカウント):assumed-role/(Lambda関数の実行ロール)/(Lambda関数名)"
                ]
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::(S3バケット名)/*"
        }
    ]
}

どうも、同一アカウント内でS3バケットに対する操作を行う場合でも、Lambda関数とレイヤーからの操作を受け入れるためのassumed roleを明示的に書かないと、S3バケットに対する操作ができないようです。

今回の構成では、Amazon S3向けのVPC Endpointは実装していないので、Lambda関数からS3へのアクセスの通信が、一旦インターネットに出ていっているが故に、明示的にこういったポリシーの設定をしてあげないとダメなのかもしれません。まだVPC Endpointを設定していないので、断定的なことは言えないのですが。

まぁとにかくやりたいことは実現できたのですが、Amazon S3とLambda関数の関係は、まだまだ勉強しなければいけないですね。。。日々精進です。

カテゴリー: AWS | タグ: , , , | コメントする

AWS認定ソリューションアーキテクト プロフェッショナル(AWS SAP-C01)に合格しての感想


1回目の受験では684点のスコアで残念ながら不合格になってしまったのですが、そこから気を取り直して学習を続け、2回目で無事に、824点のスコアで合格することができました。いやぁ嬉しいです。なんとか登るべき山を一つ登り切ったというか。

どんな風に勉強したのか

どんな風に勉強したのかといっても、合格体験記は検索すればきっとたくさん出てくるのではないかと思うので、それらの勉強方法は一通りやったという感じです。もちろんAWS クラウドサービス活用資料集は片っ端から読みまくったし、参考書がなかなかない中でオンラインの問題集を、1日の中で時間を決めて順繰りに解いていったりということはやってきました。

強いて言えば、現在携わっているプロジェクトの中で、AWS Direct ConnectからDirect Connect Gatewayの移管に関わったり、IAM関連の設計や実装に関わったりすることで、座学だけでは得られない経験を得られたというのは大きかったと思います。そういう意味では、Amazon Web Servicesがこの試験の受験対象として記している「2年以上の実務経験」というのは本当に合っているのかもしれません。

とはいえ、個人で所有しているAWSアカウントでは、どうしてもコストの兼ね合い上無尽蔵にAWSリソースを作りまくるというのは現実的にはかなり厳しいので、座学中心の学習になってしまうことは仕方がないとも思います。個人でAWS Organizationsあたりを構築するのは容易ではないですしねぇ。

ここまでの所感

これまで、

  • 2019年6月: AWS認定クラウドプラクティショナー (AWS CLF-01)
  • 2020年3月: AWS認定ソリューションアーキテクト アソシエイト (AWS SAA-C01)
  • 2020年9月: AWS認定デベロッパー アソシエイト (AWS DVA-C01)

と、ひとつひとつ段階を追うようにAWS認定資格を取得してきましたが、やはりいきなり飛び級的にAWS SAAを取得しようとは思わずに、AWS CLFから取得してきたのは、知識の積み上げとしては良かったのかなぁと思っています。

そして、実はアソシエイトレベルの試験を突破するのが一番難しいんじゃないかなぁと思ったりもしています。AWS認定SysOpsアドミニストレーター アソシエイト(AWS SOA)も2021年7月下旬をもってバージョンが上がるのが確実になっていますし、難易度も確実に上がってくるんでしょうね。なので、もしも実務に関わっている人であれば、CLF → SAA → SOAを経由してSAPに挑んだ方がもしかしたらいいのかもしれません。あくまで個人的な感覚ですが。

次の目標

次の目標として確実にマイルストーンとなってくるのは、当然のことながらAWS SOA-C02に合格することになってきます。頭では分かっていても、それを実技として相応のスキルがあるということを証明できないと、AWS系のエンジニアとしてそれ相応のスキルを持っていますよということを認識してもらうことができるというのが難しいという風に感じるようになってきたので。そういう意味では自分の中では超難関ですね。

もちろん、試験に受かって認定資格を得ることが目的ではなくて、認定資格を取得しているだけの知見を持つことが目的であることには変わりないのですが、それを定量的に示す指標として、これからも変わらず、次の試験に挑むために知識と経験を積み重ねていきたいと思っています。

カテゴリー: AWS | タグ: | コメントする