こんにちは。ギークフィードの飛信隊(社長室)所属、ippei(@ippei2480)です。
今、IaC(Infrastructure as Code)が盛り上がっていますね。
複雑化していくクラウド環境構築において、コードで設定値を管理し、安全に変更を行うことができること、コードを使い回す再現性があることが大きなメリットです。
今後デファクトスタンダードになっていくかもしれないですね。
ギークフィードでも多分に漏れずIaCブームが来ており、ツールとしてTerraformを採用しています。
私の所属する社長室では、社内システムをAWS上で構築、運用管理していますが、それらをTerraformで管理するために日々四苦八苦勉強しています笑。
今回はまずは簡単なところからやってみようということで、以前ブログで紹介した「ギークブログ更新通知botスクリプト」をTerraformを使って、サーバー上のcronで動かす構成から、EventBridge + Lambdaのサーバーレス構成に移行したいと思います。
目次
全体構成
EventBridgeのスケジュールイベントでLambdaを実行します。
LambdaはPythonプログラムを実行し、Beautiful Soupでギークブログのスクレイピングを行い、記事更新がある場合にはSlack通知を行います。
Terraformで管理するのはEventBridgeとLambdaがメインで、Lambda実行IAMロール等も含まれます。
ソースコード
Terraformのコード、Lambdaのコードいずれも上記のGitHubにて公開しているのでそちらを参照ください。
ソースディレクトリ構成
ディレクトリ構成はとてもシンプルです。
下記のLambdaコードを格納するディレクトリ以外は、Terraformコードをモノリスで配置しています。
- src/scraping_gf_blog
- requirements.txt
- scraping_gf_blog.py
ポイント解説
main.tf
実は何も書いていないです。
provider情報をbackend.tfに記述したからです。
tfstateのバックエンド情報をbackend.tfに、provider情報をmain.tfに記述するのがベストプラクティスなのかも・・・?
event_bridge.tf
EventBridgeのスケジュールイベントでは、
- EventBridgeのルール本体
- ルールとターゲットの紐付け
- EventBridgeからLambdaを実行する権限を付与する
の3つのリソースを定義する必要があります。オプションも少ないので簡単です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
resource "aws_cloudwatch_event_rule" "scraping_gf_blog_lambda_event_rule" { name = "scraping-gf-blog-lambda-event-rule" description = "毎時0分にscraping_gf_blog lambdaを実行" schedule_expression = "cron(0 * * * ? *)" } resource "aws_cloudwatch_event_target" "scraping_gf_blog_lambda_target" { arn = module.scraping_gf_blog_lambda.lambda_function_arn rule = aws_cloudwatch_event_rule.scraping_gf_blog_lambda_event_rule.name } resource "aws_lambda_permission" "allow_cloudwatch_to_call_rw_fallout_retry_step_deletion_lambda" { statement_id = "AllowExecutionFromCloudWatch" action = "lambda:InvokeFunction" function_name = module.scraping_gf_blog_lambda.lambda_function_name principal = "events.amazonaws.com" source_arn = aws_cloudwatch_event_rule.scraping_gf_blog_lambda_event_rule.arn } |
lambda.tf
AWS Lambda Terraform mooduleを使用しました。とても簡単にLambdaが作れてしまいます!
モジュールのReadmeを見て、必要なパラメーターのみ指定しています。
Lambdaの環境変数では通知先SlackチャンネルのWebHook URLを指定しています。
このモジュールのすごいところは、”soruce_path”で指定したLambdaディレクトリ内のソースコードを自動でS3へアップしてくれるところです。
ですので、terraform applyするだけでソースコードを含むインフラ構築ができてしまいます。
今回は基本的な実行権限を持つLambdaで良いので追加の権限設定を行っていませんが、実行IAMロールに追加がある場合はパラメーターで指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
module "scraping_gf_blog_lambda" { source = "terraform-aws-modules/lambda/aws" version = "3.2.0" # insert the 32 required variables here function_name = "scraping_gf_blog" description = "My awesome lambda function" handler = "scraping_gf_blog.lambda_handler" runtime = "python3.9" memory_size = 128 timeout = 10 architectures = ["arm64"] environment_variables = { WEBHOOK_URL = "SlackのWebHook URLを指定してください" } source_path = "./src/scraping_gf_blog" tags = { Name = "scraping_gf_blog" } } |
scraping_gf_blog.py
以前のブログとの違いは、「WebHook URLをLambdaの環境変数指定に変更」と「Lambdaのハンドラーを追加」のみです。
1 2 3 4 5 6 7 8 9 10 11 |
def main(): url = "https://www.geekfeed.co.jp/geekblog" articles = check_update(url) if len(articles) != 0: webhook_url = os.environ["WEBHOOK_URL"] send_to_slack(webhook_url, articles) def lambda_handler(event, context): print("start checking blog update...") main() |
おわりに
とてもシンプルな構成ですが初のTerraformプロジェクトをデプロイすることができました。
Terraformで驚いたことはデプロイの速度がとても早いことです。Cloudformation比較で数倍のスピードです。
ちょっとした変更をすぐに試して確認することができるため、開発をスムーズに進めることができます。
より複雑なアーキテクチャをデプロイしたらまたブログにしようと思います!
以上、ギークフィードの飛信隊(社長室)所属、ippei(@ippei2480)でした。
AWS、Terraformエンジニアを募集中!
ギークフィードではAWSエンジニアを募集しています。
AWS、IaCに興味がある方はぜひ一緒に働きましょう!
参考文献
TerraformでLambdaのScheduled Eventを使う
EventBridge Lambda & Scheduled Events Example
- 組織内のIPv4アドレス(EIP)を自動通知してコスト削減する - 2024-12-03
- 組織内のAWSコスト最適化のためにやっている7つのこと - 2024-12-01
- Amazon Connect Contact Lens + iPaaSで生成AI活用&他サービス連携を簡単に実現!– Amazon Connect アドベントカレンダー 2024 - 2024-12-01
- AWS Step Functionsの基本を再学習しました - 2024-09-23
- Amazon SESでバウンスメールを管理する - 2024-07-07