こつつみ

コツコツ積み上げる

2022年のOKR

OKR

今年も去年に引き続きOKRで目標を立てていきたいと思います。

2021年のOKR (俺の今年の理想) - こつつみ

O:Objectives

  • 定性的な目標
  • チームを鼓舞するようなチャレンジングなもの
  • シンプルで覚えやすいもの
  • 1カ月~四半期(3カ月)で達成できる目標
  • 定量的な指標(数字など)を入れない
  • 最大でも3〜4個

KR:Key Results

  • 定量的な指標で、数値で測れる
  • 数は3つくらい(2~5個程度)
  • ストレッチゴール(ストレッチ目標)
  • 60~70%の達成度で成功とみなす
  • 自信度10分の5の難易度
  • OKRのKRとはKey Results(主要な結果)であり、Objectiveへの進捗を図るための具体的な指標を意味する

以下、2022年の自分のOKRです。

O1. 自分の意見をもつ

KR1-1. 毎週このブログを更新する

去年に引き続き、自分で考える習慣を持つため、に読んだ本で感じたことを言語化したものであったりを毎週ブログ更新を目指していきたいと思います。

KR1-2. 技術書以外の本を30冊読む

著者の考えや思考を吸収するために、技術以外の本を多く読んでいきたいと思います。

O2. エンジニア技術の向上

KR2-1. 技術書を10冊読む

去年は20冊という目標を立てましたが、今年は10冊を深く理解できるまで読み込みたいと思います。

KR2-2. 技術記事を15個書く

去年は技術記事10記事だったところ目標達成できたので、今年は増やして人に伝えられる技術記事を書いていきたいと思います。

KR2-3. TOEIC800点以上とる

目的は技術リファレンスを読むことができるレベル、また、YouTubeで英語の聞き取りができるレベルになりたいと思っています。 定量的にするためにTOEICを基準に考えていきます。 ちなみに、現在のTOEICの最高点は3年前に580点です。そこから勉強をしていないです...

O3. 生活の充実

KR3-1. ルーティンの確立

去年はカレンダーに行なったことを入力する習慣はついたので、今年は毎日カレンダーで予定を立てるところをしていきたいです。 そうすることで、毎日、毎週、毎月の振り返りを行えるようにしていきます。

KR3-2. 自己投資を50万円以上つかう

去年と以下のようにこじつけで43万を使いました。

趣味の金は入れないようにして、50万円以上使っていきたいです。

KR3-3. 週3日筋トレを15分以上行う

筋トレが毎日継続できなかったので、今年は少なくとも週3回できるようにしていきます。

最後に

他にもルームシェアが今年の2月末に終わったり、チームでの受託開発が始まったりするので気を引き締めてやっていきたいです。

2021年の振り返り

こんにちは、ueshoです。

本当は振り返り記事と抱負の記事を別々に書こうと思っていましたが、もう2021年が終わり2022年になってしまいました。 2021年は色んなことがたくさんありました。良い転換期の年でした。

OKR振り返り

くそ恥ずかしいタイトルになっているが、今年の頭にOKRを策定していたので、まずはそれに沿って振り返りたいと思います。

kotsutsumi.hatenablog.com

以下、2021年OKR(Objectives and Key Results)です。

##  O1. 自分の意見をもつ

* KR1-1. 毎週このブログを更新する
* KR1-2. 毎日取ったメモをまとめる

## O2. エンジニアリングの追求

* KR2-1. 本業で 1 レベルの上の評価を得る
* KR2-2. 技術書を20冊読む
* KR2-3. 技術記事を10個書く

## O3. 生活の充実

* KR3-1. ルーティンの確立 (ToDoリストを作らずに全てカレンダーで管理する)
* KR3-2. 自己投資を惜しまない
* KR3-3. 同居人とランニングを続ける
* KR3-4. 毎日筋トレを10分する

OKRに合わせて以下の視点で一年間の目標を作成しました。 

  • 学習時間週21時間する(3時間/日)
  • メモを週21個とる(3個/日)
  • 読書を週1冊する完読する
  • ブログを週1個投稿する
  • 自己投資を年50万円する

f:id:ue-sho:20220101114506p:plain

以下が1日ごとに目標と比べて現在の達成度合いを表したグラフです。 夏あたりまで継続して頑張っていたが、10月あたりから遅れを取り返せなくなっていき、12月はかなり休んでいました。

春、夏前半は組み込みエンジニアとして新卒2年目の成果報告でプレゼンする機会があったり業務も忙しかったですが、社内の配属先を変えるためにAWS勉強したりしていたので、かなり頑張れてました。 夏後半は、無事配属先もAWSを使ったクラウドの部署に異動して残業も無く、割とやりたいことを出来ていました。 秋に入ってからは急に残業が増えました(月30時間程度)。このタイミングで小さいことからアウトプットをしていこうと思いTwitterで #uesho開発 のタグを使って毎日GitHubの草を生やそうという取り組みを行なったが、途中で折れてしまった。 12月頭の方で1年の振り返りを行ったところ、満足してかなり休んでしまったので目標と達成度の遅れがすごいことになってしまいました...

f:id:ue-sho:20220101163834p:plain

KeyResults振り返り

KR1-1. 毎週このブログを更新する

自分の考える習慣を持ちたくて、本読んだら自分の感じたことをブログにしようと思って始めました。 しかし、「とりあえず投稿!」って感じなので見せるの恥ずかしくて隠して投稿していたので、そこは反省点です。 もともと文章書くの下手で、レポートとか読書感想文とか書くの苦手だったが、思ったよりは継続できたので良かったです(年で52個記事にする予定が、現在44記事)。 ただ、このまま適当にやっても上手くならないと思うので、ちゃんと構造化を意識したりして来年は数もこなしつつ質も意識して継続していきたいです。

KR1-2. 毎日取ったメモをまとめる

これもメモを抽象化して考えて自分の意見を作れるようにと立てた目標です。 これは手段が目標みたいになってしまい、とりあえずTwitterや記事で「なるほど〜」と思ったところをNotionに投げるだけでになってしまい自分の意見をあんまり考えられなかったです。 後半はメモを取る回数が激減して、今は特にメモを取らなくなってしまいました。

f:id:ue-sho:20220101180921p:plain

KR2-1. 本業で 1 レベル上の評価を得る

これは来年にならないと分からないので割愛します。自分なりに今の等級にしてはやったとは思います。

KR2-2. 技術書を20冊読む

スプレッドシートのやつに落とし込まなかったので、目標を立てたことを忘れていました。 9冊くらいしか読んでいないです。 来年は積読されている技術書が大量にあるので、それらを消化したいですし、今まで読んだやつで振り返りたいやつもかなりあります。 技術書は何回も読んでアウトプットして自分の中に落とし込みたいので、2022年は8冊くらいを目標にしていきたいと思っています。

KR2-3. 技術記事を10個書く

この目標の存在もスプレッドシートに落とし込んでいないので忘れていました。 技術関連なら12記事くらい書いたが全て内容が浅いし、技術書読んだ振り返りとかになっている状況です。 2022年は、人に伝える記事を書いていきたいです。

KR3-1. ルーティンの確立 (ToDoリストを作らずに全てカレンダーで管理する)

毎日カレンダーに予定を入れて、それを実行するということを習慣化させることで自分の作業時間を増やそうとこの目標を立てました。 最初の頃は予定を決めてカレンダーに入れていたが、今は記録することだけが習慣になっています。

2021年後半は漫画を読む時間がとても増えてしまった。

f:id:ue-sho:20220101215811p:plain

KR3-2. 自己投資を惜しまない

自分はラーメンのトッピングをケチるくらいには、ケチなので金を使うことに罪悪感を持たないように設定した目標。 計算したところ1年で50万は余裕で使えることが分かったので、スプレッドシートのやつに落とし込んみました。 自己投資(学習)だけで50万使おうと思っていましたが使いきれないので、バイク(通勤時間の短縮)や一眼レフカメラ(気分転換になる)とこじつけて割とお金を使えました。 ただし、お菓子を買う頻度も爆上がりしてしまったので、反省です。

KR3-3. 同居人とランニングを続ける

自分は現在大学の研究室の人たちとルームシェアを行なっている。その同居人が誘ってくれるので、ランニング大会(6月)までは継続できました。 しかし、そこからモチベーションが無くなり、ほぼ走ることがなくなってしまいました。 ランニングをしていた頃の方が、気分転換になっていたのか?集中力や作業始めるまでのモチベーションがあった気がします。

KR3-4. 毎日筋トレを10分する

夏ぐらいまでは10分とか意識していませんでしたが、割と筋トレしていました。しかし、これも途中で全くしなくなってしまいました。 来年は、引っ越しがあるので近くにジムがあったら通いたいと思っています。


OKR以外の振り返り

部署異動のこと

自分の新卒で配属された部署が特殊で2年目で異動が行われるところでした。元々組み込みエンジニアとしてやっていたので、AWS SAAの資格をとって今の部署であるクラウドチームに来ることができました。 今後しばらくはクラウド/バックエンドをやっていくので、人生の大きな転換期でした。

設計のこと

今年に入って全然わかっていなかった設計についてかなり勉強してきました。技術書で言うと以下を読みました。

全然実践経験がないので、絶賛今設計について(実務でも自己啓発でも)自分に任せてもらえているので、段々と何をすると嬉しいのかが分かってきました。 しかし、まだまだ上記の本を読んだとしても身についていないので、繰り返し読んで自分の中に落とし込んでいきたいです。

プログラミング言語

元々は組み込み開発をしていたので、C言語を実務でやっていました。また、去年は競技プログラミンングをやっていたのでC++も使っていました。

クラウドチームに配属されてからは、Pythonをメインに使っています。しっかり勉強したことはなかったですが、酒井潤さんのUdemy が素晴らしく良く、体系的に学ぶことができました。 今では、チームの中でもかなりPythonについて知っているレベルになりました。

関係ないですが、一般社団法人Pythonエンジニア育成推進協会からイベントでPythonマグカップをいただきました。f:id:ue-sho:20220101223547j:plain

クラウドについて

AWS SAAの資格を取ったときは手を動かす回数がすくなったかったので、単語だけ覚えている状態でしたが実践経験を積みながら段々と分かってきました。 来年は、もっとインフラ周りの知識をつけていきたいと思います。

総評

組み込みエンジニアからバックエンドエンジニアになり人生の転換期でした。 そして、2021年はAWS、設計、Python、Web技術など自分の知らないことについて色々と学んだ年でした。インプットが多めでしたので、2022年はアウトプットを意識していきたいと思います。

f:id:ue-sho:20220101224218p:plain

ここまで読んでいただき、ありがとうございます。良ければ Twitterのフォローも待っています。

twitter.com

「Team Geek」を読んだ

本の基本情報

本の基本情報について紹介する。

  • 著者名:Brian W. Fitzpatrick, Ben Collins-Sussman
  • 翻訳者: 及川 卓也 (解説), 角 征典 (翻訳)
  • 書籍名:Team GeekGoogleギークたちはいかにしてチームを作るのか
  • 出版社:オライリージャパン
  • 発売日:2013/7/20
  • 頁 数:228ページ

Team Geek ―Googleのギークたちはいかにしてチームを作るのか | Brian W. Fitzpatrick, Ben Collins-Sussman, 及川 卓也, 角 征典 |本 | 通販 | Amazon

書評

絵も多く文章も堅苦しくなく読みやすかった。共感する部分が多くタメになった。 この書評では自分が心に残ったことを書いていく。

隠したらダメになる

完成してないものを見られたら、何か言われるんじゃないかと本当に不安だ。細かいところまで見られて、馬鹿だと思われないだろうか

この気持ちは誰しもが抱く感情だと思う。自分もこのブログなど誰でも見れる状態にはあるが、Twitterでわざわざ発信はしていない。なぜなら、変な文章を書いていて恥ずかしいからだ。

この本では、これが間違いであることを説明している。いつも1人でやっていると、失敗のリスクは高くなる。そして、成長の可能性が低くなると言っている。 1人でやっていると、自分が正しいことに取り組んでいるのか、それがうまくできているのか、すでに完成していないかを確認する必要がある。早い段階で失敗する可能性は高い。しかし、その段階でフィードバックを求めれば、それだけリスクは下がる。検証を重視した「早い段階で、高速に、何度も失敗せよ」の精神を忘れないようにするべき。

失敗を恐れずアウトプットすることが大事。1人で仕事をする方がリスクが高い。間違ったことをして、時間を無駄にすることを不安に思うべきだ。

ソフトウェア開発はチームスポーツ

隠れ家に1人でいたら、才能が開花することもない。秘密の発明をこっそり準備していたら、世界を帰ることもできないし、数百万人のユーザーを喜ばせることもできない。誰かと一緒に仕事をしなければいけないんだ。ビジョンを共有しよう。仕事を分担しよう。他人から学ぼう。そして、素晴らしいチームを作るんだ。

これはアフリカのことわざである「早く行きたければ、ひとりで行け。遠くまで行きたければ、みんなで行け。」を表していると思う。 素晴らしいチームを作れば、1人でやるより大きいことを成し遂げられる可能性が高まる。

HRT

あらゆる人間関係の衝突は、謙虚・尊敬・信頼の欠如によるものだ。

  • 謙虚(Humility)
    • 世界の中心は君ではない。君は全知全能ではないし、絶対に正しいわけでもない。常に自分を改善していこう。
  • 尊敬(Respect)
    • 一緒に働く人のことを心から思いやろう。相手を1人の人間として扱い、その能力や功績を高く評価しよう。
  • 信頼(Trust)
    • 自分以外の人は有能であり、正しいことをすると信じよう。そうすれば、仕事を任せることができる。

QiitaのガイドラインにもHRTについて書かれているので、この本でも一番有名な部分であり、著者も「この原則は本当に重要なので、本書はこれを中心に構成している。」と言っている。

Qiitaに面白い記事があったので、共有 qiita.com

人は植物

エンジニアも植物みたいなものだ。日光を必要とする人もいれば、水を必要としている人もいる。リーダーとしての仕事は、どのエンジニアが何を必要としているかを把握して、それを与えることだ。

自分はまだリーダーのポジションにはいないが、リーダーでなくてもこれはできると思う。難しいことなので、リーダーになる前から意識していきたい。

安全なポジションまで昇進する

昇進すれば、自分の運命をコントロールできるようになる。いい心地のいいポジションの時に少し頑張る。昇進プロセスを調べる。

別の章では以下のような記述もあった。

君のやっていることだけでなく、君が「うまく」やっていることを上司やチームの外部にいる人たちに知らせる必要がある。

仕事をうまくやれば昇進できるとは限らない。言わずもがなだが、昇進したいなら色々と手を打つ必要がありそうだ。

さいごに

本書が読者に伝えたいのはソフトウェア開発に限った話ではなく、人間関係が発生する全てに適用できる。 今回取り上げたのはほんの一部なので、少しでも興味が沸いたら手に取って読んでみることをオススメする。

僕の知らないところで大きい金が動いている

最近知った事実。会社員じゃない人の金の動きは大きい。

大手企業に勤めている人は一月100万で人を雇うのは安いって言ってた。自分は給料30万も無いのに。

フリーランスの友達のお金周りを聞くと時給5000円やら、月50万は安すぎるなど自分の概念が壊された。 (もちろん退職金やら税金周りの処理やらがあるので、実質使えるお金はかなり減ることは知っている)

外注してシステムを作ってもらうのもめちゃくちゃ高い。 自分の会社では、一サービスのサーバー費だけでも年何百万もある。

知らないところで大きい金が動いている。

日本の平均年収はどんどん下がってきているし、稼げない人が多くいる。しかし、お金大きな動きを知りトップの人が稼げる意味を知った。そんなことを考えていた日。

GitHub Actionsで「 CloudFormationで構築したLambdaにS3を介さずに自動でデプロイする」を作る

はじめに

以前の記事でLambda + CloudWatch Event でインフラをコード化した。

kotsutsumi.hatenablog.com

今回は、GitHubで管理しているLambdaに上げるコードをmasterブランチを更新するたびに、 AWS S3を介さずにデプロイする方法について書く。

CloudFormation

CloudFormationについては以前の記事でも記載したが、再度掲載する。

AWSTemplateFormatVersion: 2010-09-09

Description: Lambda for git commit count bot

Parameters:
  GitHubAccessToken:
    Type: String
  SlackApiToken:
    Type: String

Resources:
  GitCommitCountBotLambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: git-commit-count-bot
      Handler : lambda_function.lambda_handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Runtime: python3.9
      Timeout: 10
      Environment:
        Variables:
          GITHUB_ACCESS_TOKEN: !Ref GitHubAccessToken
          SLACK_API_TOKEN: !Ref SlackApiToken
      Code:
        ZipFile: |
          def lambda_handler(event, context):
              print('dummy')

  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: git-commit-count-bot-role
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource:
                  - '*'

  CloudWatchEventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: schedule-every-day-0am-event
      ScheduleExpression: cron(0 15 * * ? *) # 日本時間で 0:00
      State: ENABLED
      Targets:
        - Arn: !GetAtt GitCommitCountBotLambda.Arn
          Id: git-commit-count-bot-lambda

  LambdaEventPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref GitCommitCountBotLambda
      Principal: events.amazonaws.com
      SourceArn: !GetAtt CloudWatchEventRule.Arn

GitHub Actions

GitHub Actionsとは?

GitHub Actionsとは、GitHub上でプッシュ・Issue・リリースなどのイベントをトリガーに起動し、対応するアクションを組み合わせてワークフローの自動化が行える。 いわゆるCI/CDツールです。類似のものですと、CircleCIやJenkinsなどがある。

ドキュメントや公開されているActionが多数あるので、これらを活用することで簡単に自動化の実装ができる。また、Github ActionsはYamlファイルを書くだけで良いため1つサンプルを準備すると、 同様の設定をエンジニア以外でも作成することができる。公開されているActionを使うことで自分で作らなくても良いものもある。

CloudFormationで構築したLambdaにS3を介さずに自動でデプロイする

適宜ファイルにコメントをつけて説明する

name: deploy

on:
  push:
    branches:
      - master  # masterにイベントが発生した場合をトリガーに起動する

jobs:
  lambda-cd:
    name: Zip the code to be deployed to AWS Lambda
    runs-on: ubuntu-latest
    env:
      ZIP_FILE_NAME: package.zip  # jobs全体に適用される環境変数を設定する
    steps:
      - name: Checkout
        uses: actions/checkout@v2  # 公式が提供しているGitHub Actions, イベントがあったブランチを仮想環境上に置く(チェックアウトする)

      - name: Setup Python
        uses: actions/setup-python@v2 # 公式が提供しているGitHub Actions, Python環境を準備する
        with:
          python-version: 3.9

      - name: Zip the code
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt -t ./   # Lambda上でpip installできないので、サードパーティーのライブラリのソースコードを置く 
          zip -r ${{ env.ZIP_FILE_NAME }} ./*  # サードパーティーのライブラリのソースコード と 自身のコードをZip化する
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1   # こちらもGitHub Actionsで公開されている, AWSの認証を行う
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: deploy to AWS Lambda
        env:
          TEMPLATE_FILE: cloudformation/git_commit_count_bot.yml   # CloudFormationのYamlファイルのパス
          STACK_NAME: git-commit-count-bot-cfn  
          LAMBDA_FUNCTION_NAME: git-commit-count-bot
        run: |
          aws cloudformation deploy \
            --template-file $TEMPLATE_FILE \
            --stack-name $STACK_NAME \
            --capabilities CAPABILITY_NAMED_IAM \
            --parameter-overrides \
            GitHubAccessToken=${{ secrets.ACCESS_TOKEN }} \
            SlackApiToken=${{ secrets.SLACK_API_TOKEN }}     # AWS上に環境を構築する
          aws lambda update-function-code \
            --function-name $LAMBDA_FUNCTION_NAME \   # CloudFormationのYamlファイルに変更がない限り変更コードが反映されない
            --zip-file fileb://${{ env.ZIP_FILE_NAME }} --publish   # そこで毎回Zipファイルを指定してLambdaのコードを更新する

このようにすれば、masterブランチを更新するたびに、AWS S3を介さずにデプロイできる。

最後に

今回はこのようにして行ったが、CloudFormationで AWS::Serverless::Function を用いれば簡単にできるかもしれないと後になって気づいた。 しかし、試していないので今度試してみて出来れば記事にしたいと思う。

docs.aws.amazon.com

Lambda + CloudWatch EventのインフラをCloudFormationでコード化する

はじめに

この記事は、以下の記事にて説明したSlack botのインフラをCloudFormationでコード化したものです。

kotsutsumi.hatenablog.com

Lambda + CloudWatch Event の CloudFormation

作成するリソースはこちらです。

今回のLambdaは、CloudWatch EventのルールによりLambdaを起動します。 Lambdaのコードは、GitHub ActionsでAWS CLIにより直接配置する予定なので、今回はダミーとして超簡単なコードを記載しています。

def lambda_handler(event, context):
    print('dummy')

今回Yamlファイルで書いていますが、Jsonでも書くことができます。 しかし、Json形式ですとコメントが書けないといったデメリットがあります。

自分の書いたCloudFormationに適宜コメントを入れて解説します。

AWSTemplateFormatVersion: 2010-09-09

Description: Lambda for git commit count bot # 書かなくても良い

Parameters:  # 指定する値が無ければ書かなくても良い
  GitHubAccessToken:  # Parametersで定義したものは、Resourcesで使えるようになる
    Type: String  # Parametersの値は、CLIで指定したり、Web上で入力も出来ます
  SlackApiToken:
    Type: String

Resources:
  GitCommitCountBotLambda:  # 任意の名前に変更する
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: git-commit-count-bot  # 任意の名前に変更する
      Handler : lambda_function.lambda_handler  # 自身のコードに合わせて変更する
      Role: !GetAtt LambdaExecutionRole.Arn
      Runtime: python3.9
      Timeout: 10  # デフォルトは3秒だが、今回10秒にしている
      Environment:
        Variables:
          GITHUB_ACCESS_TOKEN: !Ref GitHubAccessToken  # 環境変数を設定できる
          SLACK_API_TOKEN: !Ref SlackApiToken  # !RefでParametersでしたいした値を使用できる
      Code:
        ZipFile: |  # ここでコードを書かなくてもS3に配置するなどでも大丈夫
          def lambda_handler(event, context):
              print('dummy')

  LambdaExecutionRole:   # 任意の名前に変更する
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: git-commit-count-bot-role
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup  # ログを取れるように許可を与える
                  - logs:CreateLogStream  # ログがいらなければRoleがなくても良い
                  - logs:PutLogEvents
                Resource:
                  - '*'

  CloudWatchEventRule:  # 任意の名前に変更する
    Type: AWS::Events::Rule
    Properties:
      Name: schedule-every-day-0am-event  # 任意の名前に変更する
      ScheduleExpression: cron(0 15 * * ? *)  # 日本時間で 0:00
      State: ENABLED
      Targets:
        - Arn: !GetAtt GitCommitCountBotLambda.Arn
          Id: git-commit-count-bot-lambda

  LambdaEventPermission:  # 任意の名前に変更する
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref GitCommitCountBotLambda  # Type: AWS::Lambda::Functionで自身がつけた名に変更する
      Principal: events.amazonaws.com
      SourceArn: !GetAtt CloudWatchEventRule.Arn  # CloudWatch Eventと連携させる

番外編: デプロイ

今回AWSに適用する際にはAWS CLIで操作します。もちろんAWSのサイト上でファイルをしてCloudFormationのコードを適用することも出来ます。

自分が使用したコマンドは以下である。自分がハマったエラーとして --capabilities CAPABILITY_NAMED_IAM を指定しなかったことです。

CloudFormationがスタックを作成するために、特定の機能が含まれていることを明示的に示す必要があ理ます。

  • IAMリソースがある場合は、CAPABILITY_IAMかCAPABILITY_NAMED_IAMが必要になる
  • カスタム名のIAMリソースがある場合はCAPABILITY_NAMED_IAMを指定する
  • 指定がないとAWSCloudFormationはInsufficientCapabilitiesエラーを返す

今回、IAM Roleを作成しているので、--capabilitiesで指定する必要があります。 ${{ secrets.~~ }} はGitHub Actionsの指定です。実際には、そこに環境変数の値を入力します。

aws cloudformation deploy --template-file cloudformation/git_commit_count_bot.yml --stack-name git-commit-count-bot-cfn --capabilities CAPABILITY_NAMED_IAM --parameter-overrides GitHubAccessToken=${{ secrets.ACCESS_TOKEN }} SlackApiToken=${{ secrets.SLACK_API_TOKEN }}

ちなみにLambdaにCLIで直接デプロイする方法は以下です。

aws lambda update-function-code --function-name git-commit-count-bot --zip-file fileb://${{ env.ZIP_FILE_NAME }} --publish

自分は上記のことをGitHub Actionsで行っています。参考にコードを置いておきます。

github.com

最後に

今回CloudFormationでコード化に至ったのには、以下の理由からである。

  • AWS初学者を導く体系的な動画学習サービス AWS CloudTech で学んだ
  • 会社でCloudFormationを使うことになった
  • CI/CDを構築したい

自動テストは大体行える環境を作ってはいるが、自動デプロイに関しては無知だったので、とても良い経験になった。 今回CloudFormationを学んだことで、会社でもすんなり実装できて良かった。

CloudFomationは、AWS CloudTechで学んだ。とても分かりやすく初学者にとって有効だった。 自分は、AWS CloudTechに入ってAWS SAAの資格をとって、組み込みエンジニアからWebエンジニアに社内転職した人なので、おすすめします。

aws-cloud-tech.com

AWS Lambda + GraphQLでGitHubのコミット数を通知してくれるSlack botを作った

はじめに

2021年10月ごろより、出来るだけ毎日GitHubの草を生やそうと決めました。 また、Pythonのコードの書き方を身につけることも目的です。

そのために、Slackの自分のチャンネルに通知してくれるbotを作ろうと考えました。

機能

f:id:ue-sho:20211003152642p:plain

上記のように1日のコミット数をSlackに通知してくれる。

  • Lambdaと連携させたCloudWatch Eventを使って 0:00 にイベントを発火する
  • Slackの自分の #times_uesho に通知する
  • GitHubの GraphQL API を使ってコミット数を取得する
  • プライベートリポジトリのコミット数まで取得する
  • CloudFormationでインフラをコード化する ※別記事にて解説予定
  • GitHub Actions でmasterにpushしたら自動でデプロイする ※別記事にて解説予定

GitHubの GraphQL API

当初、コントリビューションからコミット数を取得していたが、どうもプライベートリポジトリの値は取れなかった。

        query (
            $name: String!,
            $from: DateTime!,
            $to: DateTime!
        ) {
            user(login: $name) {
                name
                contributionsCollection(from: $from, to: $to) {
                    totalRepositoryContributions
                    totalCommitContributions
                    commitContributionsByRepository {
                        repository {
                            nameWithOwner
                        }
                        contributions {
                            totalCount
                        }
                    }
                }
            }
        }

そこで、リポジトリごとにコミット数を調べる方法に変更した。(デフォルトブランチのコミット数しか取れなそう)

        query($date: GitTimestamp!) {
          viewer {
            repositories(last: 100) {
              nodes {
                nameWithOwner
                defaultBranchRef {
                  target {
                    ... on Commit {
                      history(since: $date) {
                          totalCount
                      }
                    }
                  }
                }
              }
            }
          }
        }

こうすることで以下のようなレスポンスが得られる。

{
        "data": {
            "viewer": {
                "repositories": {
                    "nodes": [
                        {
                            "nameWithOwner": "ue-sho/pycabook_rentomatic",
                            "defaultBranchRef": {
                                "target": {
                                    "history": {
                                        "totalCount": 0
                                    }
                                }
                            }
                        },
                        {
                            "nameWithOwner": "ue-sho/Calculator",
                            "defaultBranchRef": {
                                "target": {
                                    "history": {
                                        "totalCount": 0
                                    }
                                }
                            }
                        },
                        {
                            "nameWithOwner": "ue-sho/rent_price_forecast",
                            "defaultBranchRef": {
                                "target": {
                                    "history": {
                                        "totalCount": 0
                                    }
                                }
                            }
                        },
                        {
                            "nameWithOwner": "ue-sho/telescopic-sidebar",
                            "defaultBranchRef": {
                                "target": {
                                    "history": {
                                        "totalCount": 0
                                    }
                                }
                            }
                        },
                        {
                            "nameWithOwner": "ue-sho/git-commit-count-bot",
                            "defaultBranchRef": {
                                "target": {
                                    "history": {
                                        "totalCount": 5
                                    }
                                }
                            }
                        },
                        {
                            "nameWithOwner": "ue-sho/auto_testing",
                            "defaultBranchRef": {
                                "target": {
                                    "history": {
                                        "totalCount": 4
                                    }
                                }
                            }
                        }
                    ]
                }
            }
        }
    }

取得したレスポンスを整形し、SlackのAPIchat.postMessage を使用して自分のチャンネルに通知した。Slack Botの記事は多くあるので割愛します。

コード量はそんな多くないので、詳細をみたい人はリポジトリを見てください!Pythonです( ◠‿◠ )

github.com

AWS Lambda

構成はとても簡素です。なぜLambdaを使ったかと言うと、EC2などに上げるより簡単かつ時間のイベント発火も簡単にできるためです。しかも無料で使える!ところが決め手です。

AWS Lambda の無料利用枠には、1 か月ごとに 100 万件の無料リクエスト、および 40 万 GB-秒のコンピューティング時間が、それぞれ含まれます。 引用: 料金 - AWS Lambda |AWS

f:id:ue-sho:20211003153957p:plain

今回に必要な設定は以下です。

  • Lambda Functionの作成
  • CloudWatch Eventの定義
  • LambdaとCloudWatch Eventの連携

Lambda Functionの作成

コンソール上の「関数を作成」から作る。

  • 関数名をつける (今回は「git-commit-count-bot」(下の画像のサンプルは「test」)という名前をつけた)
  • ランタイムを選択 (今回はPython 3.9)
  • その他はデフォルトでOK

CloudWatch Eventの定義 & 連携

f:id:ue-sho:20211003161014p:plain

上記の画面のトリガーを追加からEventBridge(CloudWatch Event)を選択する。

「新規ルールの作成」を選択して今回は0時にイベントが発火するようにする。 自分はバッチ処理などでよく使われるcronコマンドの方式で設定しました。

UTC(協定世界時) になっており、日本の時刻から-9時間する必要があります。 つまり、cron(0 15 * * ? *) することで、毎日0時にイベントが発火します。

ルールのスケジュール式 - Amazon CloudWatch Events

これにて完成!

最後に

GitHubの草も9月くらいからよく生えるようになりました。

f:id:ue-sho:20211003161717p:plain

この記事はAWS初学者を導く体系的な動画学習サービス AWS CloudTech を参考に作成しました。(AWS関連)

aws-cloud-tech.com