使用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 上查看所有源代码。
这个项目是基于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的工作流程。
-
- 创建circleci/python:3.7-buster-node容器(主要容器)
-
- 可以创建localstack容器
-
- 执行主要容器的步骤
-
- 在名称为”Wait for localstack step”的步骤中,等待至少一个端口打开
-
- 将python的包指定到目录/home/circleci/project/sam-lambda/hello_world/packages并进行安装
-
- 将其放置在$LAMBDA_ZIP_PATH中
-
- 安装terraform
-
- 将terraform文件移动到$TERRAFORM_PATH
-
- 执行terraform init
-
- 执行terraform apply。同时将lambda的zip路径($LAMBDA_ZIP_PATH)和circleci的默认主机名传递给$COMMON_NETWORK
- 由terraform创建lambda