弊社ECサイト用APIサーバのCI/CD環境今昔

弊社ECサイト用APIサーバのCI/CD環境今昔:

ハンズラボ Advent Calendar 2018 16日目の記事です。

ECサイト担当になって早3年を過ぎ、その間にCI/CD環境を継続して改善し続けてきました。

この度ようやくParavirtualなインスタンスで動作していたJenkinsサーバを停止し、一段落したこともあり、来し方を振り返ってみます。


APIサーバのCI/CD環境今昔


チーム参加時点(2015/09)

Gitリポジトリ: Atlassian Stash 
    - 今はBitbucketに吸収されてしまいました 
  CI: Jenkins 
    - Antから以下を実行 
        - PHP Lint(php -l) 
        - PHP Mess Detector 
        - PHP Code Sniffer 
        - PHPUnit 
  CD: Jenkins 
    - eb deployコマンドをbashスクリプトで実行 


当時を振り返って

  • Atlassian Stashにログインできるメンバーが社内に数名しかいなかった・・・
  • AntジョブがXMLで書いてありメンテナンスできない


Gitリポジトリ移行(2015/12)

+ Gitリポジトリ: Backlog 


当時を振り返って

  • BacklogのGitリポジトリでプルリクエスト機能が追加されたこともありBacklogへ移行

    • Githubも社内で利用開始していたが、Backlogは当時からエンタープライズプランで追加費用がなかった


決済APIサーバ分離(2016/02)

+ CI: Jenkins 
+    - Antをやめて、composerスクリプトでの実行に修正 
+ CD: Jenkins 
+    - bashスクリプトで待機系を判定し、待機系へ`eb deploy` 


当時を振り返って

  • ステージング環境と本番環境のAWSアカウントの分離にチャレンジした

    • ステージング環境にdeployしたCommitと本番環境に差異を発生させたくなかったため、ステージング環境deploy時に本番環境の待機系へもdeploy
    • 本番環境のCNAMEから待機系を判断
  • Jenkinsユーザが実行するジョブをvisudoで追加するのを忘れていて動かない


決済APIサーバのCI/CD環境移行(2018/06)

+ Gitリポジトリ: CodeCommit 
+ CI: CodePipeline + CodeBuild 
+   - PHP Parallel Lint に変更 
+   - CodeBuildのDockerイメージでhttpdを起動してAPIのテストを実行 
+ CD: CodeBuild 
+   - CodeBuildからeb deployコマンドをbashスクリプトで実行 


当時を振り返って

  • Meltdown/Spectre以降、Paravirtualインスタンスへのメンテナンス頻度が上がり、Jenkins廃止の機運が高まった
  • CodePipelineはBacklogのGitリポジトリからhookできない・・・

    • CodeCommitの使い心地を試してみる
  • CodeBuildでのCIでハマる

    • 今はローカル実行できていいですよね・・・
  • CodePipelineからElastic BeanstalkへdeployしたいがAWSアカウントをまたいでのdeployは素直には無理

    • 仕方なくCodeBuildからeb deployする


APIサーバのCI/CD環境移行(2018/11)

+ Gitリポジトリ: Github 
+ CD: CodePipeline + Lambda 
+   - CodePipelineからElastic Beanstalkの待機系へdeploy 
+   - 手動承認したらLambdaでswap 
+   - swap完了後に未deploy側へdeploy 
+   - deploy完了したら再swap 


当時を振り返って

  • CodeCommit辛い

    • プルリクエストしたらAWSのマネジメントコンソール開くの???
    • httpsにしてもsshにしても辛い
    • 諦めてGithubに移行
  • CodeBuildでのPHPMD/PHPCSで落ちる

    • Jenkinsサーバでは通るが、新環境では落ちる・・・
    • 仕方なく、通るまでチェックルールからルールを一つずつ削除する。辛い。
  • ステージング環境と本番環境のAWSアカウントを分離

    • featureブランチからdevelopブランチにマージ→ステージング環境にdeploy
    • developブランチからmasterブランチにマージ→本番環境にdeploy
  • CodePipelineからのLambda呼び出しでハマる

    • LambdaからCodePipelineへ「ジョブが完了した」と通知する必要がありました
import boto3 
import logging 
 
logger = logging.getLogger() 
logger.setLevel(logging.INFO) 
 
SOURCE_EB = os.environ['source_eb'] 
DEST_EB = os.environ['dist_eb'] 
 
def lambda_handler(event, context): 
    logger.info(event) 
 
    try: 
        beanstalk = boto3.client('elasticbeanstalk') 
        response = beanstalk.swap_environment_cnames( 
            SourceEnvironmentName = SOURCE_EB, 
            DestinationEnvironmentName = DEST_EB, 
        ) 
 
        logger.info(response) 
 
    except Exception as e: 
        logger.error(e) 
        raise e 
 
    try: 
        codepipeline = boto3.client('codepipeline') 
        jobid = event['CodePipeline.job']['id'] 
        response = codepipeline.put_job_success_result( 
            jobId=jobid, 
        ) 
 
        logger.info(response) 
 
    except Exception as e: 
        logger.error(e) 
        raise e 


今後

Elastic BeanstalkへのAmazon Linux2の公式対応待ちです。

その際には決済APIサーバのCI/CD方式をAPIサーバに合わせる予定です。

ECS + Fargate環境にも挑戦したいです。

今後も改善は続きます。


参考資料

ハンズラボ Advent Calendar 2018 明日17日目は@sr-mtmtです!

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)