使用Terraform在CircleCI上构建LocalStack

介绍的内容

    • circleciにlocalstackをterraformで構築します

terraformでlambdaを作ります
ユーザーが指定したディレクトリにpython packageをインストールします
インストールしたpackageをzipに固めます

circleciをlocalで動かしてますが、本物のcircleciでも動きます
circleciのdocker executorを使います

總的來說

    • localstackのdocker-entrypoint-initaws.dが使用できないから、

docker-entrypoint-initaws.dの作業内容をPrimaryコンテナに書きます、
localstack固有のもろもろ初期化が終わるタイミングを把握できません。愚直に初期化作業に掛かる時間を計測して、その時間分待つようにすることが最善です。

circleciをlocal環境でデバックする方法はこちらで確認できます

https://qiita.com/cheekykorkind/items/4efc89fd5271bec7ff50

localstackコンテナの環境変数HOSTNAME_EXTERNALをlocalhostにして、Primaryコンテナからのlocalstackアクセスできるようにします。

CircleCI的Docker执行器无法使用卷。

    • circleciのdocker executorはdocker composeのvolumesを使用できません。

これがlocalstack固有のもろもろ初期化が終わるタイミングを把握不可能する原因です。volumesが使えないから、docker-entrypoint-initaws.dに介入が不可能です

localstackのportが開くことを基準にするのは意味がありません。なぜなら、portを開けたままもろもろ初期化作業するからです

https://circleci.com/docs/2.0/executor-types/#docker-benefits-and-limitations
どうしてもdocker composeのvolumesを使う必要があったら、machine executorにしたら実装可能だと思います

CircleCI的Docker执行器的网络主机名被设置为localhost。

    • circleciのdocker executorは一つのネットワーク(common network)がありまして、host名はlocalhostです。Primaryコンテナ含むすべてのコンテナが属してます

docker executorはコンテナ同士volumnsでやりとりできないから、コンテナ各々違うport番号を貼ってやりとりさせることが無難かと思います。

common networkの原文:https://circleci.com/docs/2.0/executor-types/#using-multiple-docker-images

(参考)除了主要容器以外的容器功能受到限制,给人留下限制较多的印象。

    docker executorが使えるオプション:https://circleci.com/docs/2.0/configuration-reference/#docker

我要开始介绍了

介绍localstack

这是一个可以在不使用真正的AWS的情况下进行各种试验的工具。
从0.11.0版本开始有很大的变化。本文将使用0.11.0版本的localstack。
链接:https://github.com/localstack/localstack

介紹terraform

你可以使用代码来管理基础设施。
https://www.terraform.io/

CircleCI是一個CI/CD平台。

这是一个帮助实现代码持续集成和测试的工具。
https://circleci.com/

建立实验环境

Linux – Linux是一个开源的操作系统。

    CentOS Linux release 7.7.1908 (Core)

Docker Compose是一种容器编排工具。

    VERSION : 1.24.1

Docker是一种容器化平台。

    VERSION : 19.03.5

将 circleci 安装在本地

目录结构

你可以在 https://github.com/cheekykorkind/circleci-localstack 上查看所有源代码。

circleciD.png

这个项目是基于Docker Compose构建了Localstack,并使用Terraform创建了Lambda函数。在该项目的基础上,我们添加了CircleCI配置并进行了调整。关于如何使用Docker Compose创建Localstack的详细内容,请参考这篇文章:
https://qiita.com/cheekykorkind/items/02c896465ddea5c5186f

在CircleCI的config.yml中进行配置构建。

工作的名字是test。也可以设置为my-test等。

version: 2
jobs:
  test:
    docker:
      - image: circleci/python:3.7-buster-node
        environment:
          AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
          AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
          AWS_DEFAULT_REGION: us-east-1

          LAMBDA_ZIP_PATH: /home/circleci/lambda.zip
          HELLO_WORLD_PATH: /home/circleci/project/sam-lambda/hello_world
          TERRAFORM_PATH: /home/circleci/project/terraform

          COMMON_NETWORK: localhost

      - image: localstack/localstack:0.11.0
        environment:
          AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
          AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
          AWS_DEFAULT_REGION: us-east-1
          SERVICES: lambda,logs
          DEBUG: 1

          HOSTNAME_EXTERNAL: localhost

    steps:
      - checkout

      - run:
          name: Wait for localstack
          command: dockerize -wait tcp://localhost:4566 -timeout 2m

      - run:
          name: install pip packages at packages directory
          command: |
            pip -V
            cd $HELLO_WORLD_PATH
            pip install -t ./packages -r requirements.txt
            zip -r9 $LAMBDA_ZIP_PATH .

      - run:
          name: install terraform 0.12.6
          command: |
            cd ~
            sudo apt-get install unzip
            wget https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
            sudo unzip -o terraform_0.12.6_linux_amd64.zip
            sudo mv terraform /usr/local/bin/
            terraform --version

      - run:
          name: terraform apply
          command: |
            cd $TERRAFORM_PATH
            terraform init
            terraform apply -auto-approve -var="lambda_zip_path=$LAMBDA_ZIP_PATH" -var="endpoint_domain=$COMMON_NETWORK"

      - run:
          name: install aws cli
          command: |
            sudo apt install awscli

      - run:
          name: test lambda
          command: |
            aws lambda invoke --region us-east-1 \
              --endpoint-url http://localhost:4566 \
              --function-name hello_lambda \
              --payload '{ "name": "Bob" }' \
              response.json

设置容器的环境变量

circleci/python:3.7-buster-nodeコンテナ(Primaryコンテナ)

COMMON_NETWORK はterraformにcircleciのdocker executorのデフォルトhost名localhostを伝えるために作りました

AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_DEFAULT_REGION はaws cliを便利に使うために設定しました

LAMBDA_ZIP_PATH はlambda生成に使うzipファイルの位置を書きました。コンテナ2つが連携して作業するから管理しやすくするために設定しました

HELLO_WORLD_PATH は便利にSAMプロジェクトのpythonコードのzip圧縮をするために設定しました

TERRAFORM_PATH はterraformファイルのパスです。terraformコマンド実行するためにterraformファイルがいるところに移動する必要があります。便利な移動のために事前に指定しておきました

localstack/localstack:0.11.0コンテナ

SERVICES、DEBUG、HOSTNAME_EXTERNAL はlocalstack固有の環境変数です。localstackを調べると理解できると思います

HOSTNAME_EXTERNAL はcircleciのprimaryコンテナからlocalstackにアクセスできるようにcircleciのデフォルトhost名であるlocalhostに合わせます。これでterraformがlocalstackに付けて実行可能になります

AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_DEFAULT_REGION はaws cliを便利に使うために設定しました

步骤说明

name: Wait for localstack

localstackコンテナが起動することを待ちます。一番前に置いた理由はterraform実行する前にlocalstackのもろもろ初期化作業する時間を稼ぐためです。当プロジェクトはlambdaとcloudwatch logs二つのサービスだけ使っていてこれで大丈夫ですが、localstackで使おうとするサービスが多い場合は大目にsleep 300などを入れることも考える必要があります

使用CircleCI本地执行–job test的工作流程。

    1. 创建circleci/python:3.7-buster-node容器(主要容器)

 

    1. 可以创建localstack容器

 

    1. 执行主要容器的步骤

 

    1. 在名称为”Wait for localstack step”的步骤中,等待至少一个端口打开

 

    1. 将python的包指定到目录/home/circleci/project/sam-lambda/hello_world/packages并进行安装

 

    1. 将其放置在$LAMBDA_ZIP_PATH中

 

    1. 安装terraform

 

    1. 将terraform文件移动到$TERRAFORM_PATH

 

    1. 执行terraform init

 

    1. 执行terraform apply。同时将lambda的zip路径($LAMBDA_ZIP_PATH)和circleci的默认主机名传递给$COMMON_NETWORK

 

    由terraform创建lambda

运行 `circleci local execute –job test` 的结果

circleci-local.gif
广告
将在 10 秒后关闭
bannerAds