vlambda博客
学习文章列表

AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)


往期推荐




B站新增实操视频,直接点击观看

简介

在之前文章中,我们利用 AWS 界面控制台,或者 AWS CLI 命令行,来配置使用 AWS 资源。

AWS 界面控制台的优点是,新手友好,图文并茂,一步一步配下来非常方便理解。

缺点也明显,AWS 熟了之后用这种方式很费时间,有些配置步骤繁多,容易出现手工错误。

AWS CLI 命令行优点是简洁,比如 ECS Fargate service 在界面控制台上要配好几页,AWS CLI 用一个 JSON 模板文件搞定。

缺点是,学习成本稍微高一些。

另外,对于一个综合运用了多个 AWS 资源的项目,可能要分开写很多模板文件和命令,给后续变更维护带来一定难度。

除了上述两种方式,我们还可以利用以下 IaC(Infrastructure as Code基础设施即代码)工具来维护配置 AWS 资源。

  • Terraform:基于 go 语言,利用 HashiCorp 配置语言(HCL)对资源进行管理,支持大部分云平台
  • AWS Cloudformation:利用 JSON 或者 YAML 对资源进行管理,颗粒度细,功能强大,不过 JSON 文件很长,读起来有点困难
  • AWS CDK:AWS 自己的框架,基于 nodejs,可以直接利用编程语言对 AWS 资源进行控制

AWS CDK 分版本 1 和 2。

本文介绍 AWS CDK 1 的主要概念以及在公司内网通过代理访问 internet 环境中的安装配置过程。

AWS CDK 2 目前处于开发中,非稳定版本。

目录

- 环境(配置)

- AWS CDK

  1. 简介

  2. 主要概念

     - Constructs

     - Apps

       - App 生命周期(部署流程)

     - Stacks

     - Assets

     - Bootstrapping

- 实战步骤

  1. 配置 CDK

     - 安装 Python

       - 多 Python 版本环境的处理

     - 安装 node

     - 安装 CDK

  2. 测试第一个 CDK 应用

     - 创建 App

     - 修改 App

     - 生成 CloudForamtion 模板(Synthesize)

     - 部署 App

     - 删除 App

- 总结

- 引申

- 资源下载

- 后记

环境(配置)

  • AWS 中国或 Global 帐号,可在官网申请,一年内使用指定资源免费
  • Linux Redhat 7
  • python
  • nodejs
  • CDK 1

AWS CDK

简介

AWS Cloud Development Kit (AWS CDK) 是 AWS 开发的软件框架,真正实现了用代码(通用编程语言,不是声明式的语言)对 AWS 资源进行配置管理。

CDK 本质上是利用代码生成 Cloudformation 模板,然后利用 Cloudformation 对资源进行操作。

图 2AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

CDK 支持以下语言

  • TypeScript
  • JavaScript
  • Python
  • Java
  • C#/.Net
  • GO(开发中)

本文使用 Python 语言,操作 CDK 部署 AWS 资源。

主要概念

为顺利进行测试,本文会介绍和本次测试相关的一些概念,完整概念还请参考官网。

Constructs

Constructs 是构建 CDK App 的基本模块,一个 Construct 代表一个“云元件”,还包含了利用 CloudFormation 创建此资源的所需的相关内容。

一个 Construct 可以表示一个单独的 AWS 资源,比如 S3。也可以表示由几个 AWS 资源组合成的高一级的“云元件”,比如一个 Queue 和与它相关的计算资源一起构成一个“云元件”。AWS 提供了 Construct 库,里面包含了所有 AWS 资源的 Construct 类,代码中通过实例化类来定义 Construct。

在这个库中有三种层次的 Construct

  • CFN(CloudFormation)Resources

称为 Level 1(L1)或者底层资源,与 CloudFormation 中的 AWS 资源相对应(比如一个 S3 Bucket),使用时需要显式配置所有的属性,要求对 CloudFormation 的资源模型有完整的了解,使用起来相对比较复杂。

  • Level 2(L2)Construct

高一级的 Construct,提供了额外的方法和属性,默认值以及模板,使得用户不需要知道资源的全部细节,便可以方便地定义资源,本文主要也是利用 L2 Resources 定义云架构。

  • patterns

更高级的 Construct,通过一个 Construct 调用多个资源来完成一个任务。

比如 aws-ecs-patterns.ApplicationLoadBalancedFargateService 这个 construct 包括了一个 AWS Fargate Cointainer 和 ALB。

Stacks

AWS 资源需要通过 Construct 定义在 Stack(属于高级的 Construct)中,一个 Stack 就是一个部署单位。

CDK Stack 与 CloudFormation 中的 Stack 相对应,每个 CDK Stack 在部署时,会在 CloudFormation 中生成对应的同名 Stack。

Apps

Stack 需要通过 App(属于高级的 Construct)实例化,生成 CloudFormation 模板。一个 App 中可以包含多个 Stacks。

低级的 Constructs(代表 AWS 资源)定义在 Stack 中,而 Stack 定义在 App 中。

每次 CDK 部署时以 App 为单位进行,但可以指定 App 内某些 Stack 单独部署。

App 生命周期(部署流程)

图 3AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

  1. Construction (or Initialization)

代码实例化并链接所有 Constructs(app, stacks, 和其中的 constructs),CDK 的大部分代码是在这一步执行。

  1. Preparation

对实现 prepare 方法的 Constructs 做进一步修改,一般用户很少需要修改些步骤。

  1. Validation

对实现 validate 方法的 Constructs 做验证,当验证失败时会通知用户。官方推荐尽可能早地进行验证,以便尽早发现问题。

  1. Synthesis

通过 app.synth()触发,生成 CloudForamtion 模板、Lambda bundles、Docker images assets 以及其它部署需要的文件,也称为 Cloud assemblies。

  1. Deployment

AWS CDK 把 Cloud assemblies 中的内容上传到 AWS S3,ECR 或者其它需要的地方,然后启动 CloudFormation 进行部署。

Assets

AWS CDK 部署时需要的本地文件,目录或者 Docker images。

Bootstrapping

在利用 AWS CDK 部署时,可能需要对所部署的环境(某个 AWS account 及地区)做初始化。

包括建一个 CDK 自己使用的 S3 bucket 用来保存部署时需要上传的文件,或者创建 IAM Role 来授权部署操作。

CDK 初化时,会在 AWS 环境上创建一个 CloudFormation 的 Stack,一般叫“CDKToolkit”。

一个 AWS 环境上只会有一个“CDKToolkit”,多次执行初化时可能会升级此 Stack,不需要升级时就没有动作,也不会报错。

以下几种情况,需要初始化 AWS 环境

  • 部署时用到 Assets
  • 产生的 CloudFormation template 大小超过 50 Kilobytes
  • 有 Stack 中使用了 DefaultSynthesizer,比如 CDK Pipelines

实战步骤

1. 配置 CDK

AWS CDK Python 环境要求如下

  • Node.js 10.13 或者高版本,目前推荐 14.x
  • Python 3.6 或者高版本
  • pip
  • virtualenv

安装 Python

在 Redhat7、CentOS7 上安装方法

#下载python包
wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz
#解压
tar xvf Python-3.8.3.tgz
#进入解压目录,配置后编译安装
cd Python-3.8*/
./configure --enable-optimizations
sudo make altinstall
多 Python 版本环境的处理

Python 本身的安装方法很多,也不复杂,上面只举了一个例子。我们经常遇到的情况是一个环境上有多个 Python 版本。

例如下面这个环境中有三个版本的 Python

图 4AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

下面我想用 pyhton3.8,那么可以进行如下操作

先用“type”查看 pyhton3.8 命令所在的目录,然后检查“/usr/local/python3.8/bin”目录下是否有 pip 和 virtualenv。

图 5AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

在运行接下来的命令前用“export”命令指定此目录为优先查找命令目录

export PATH=/usr/local/python3.8/bin:$PATH

然后再运行 python3 命令,可见已经默认使用 Python3.8

图 6AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

如果希望使用“python”而不是 python3”,那么可以建一个软链接

ln -s /usr/local/python3.8/bin/python3.8 /usr/local/python3.8/bin/python

然后直接用 python 就可以使用 3.8 版本了

图 7AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

安装 node

Redhat 7 环境,依次执行以下命令安装 nodejs

#下载符合Linux版本的nodejs仓库信息包
wget https://rpm.nodesource.com/pub_14.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm
#安装nodejs仓库信息包
rpm -ivh nodesource-release-el7-1.noarch.rpm
#安装nodejs
yum install nodejs

安装完成

图 8AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

升级 npm

#直接连internet
npm install -g npm
#需要proxy连internet
npm --proxy http://YOUR_PROXY_SERVER:PORT install -g npm

图 9AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

安装 CDK

运行以下命令,用 npm 安装 CDK

#直接连internet
npm install -g aws-cdk
#需要proxy连internet
export NODE_EXTRA_CA_CERTS=[THE PATH OF YOUR PROXY SERVER CERTIFICATE]
npm --proxy http://YOUR_PROXY_SERVER:PORT install -g aws-cdk

注意:

如果在公司内网环境,通过 proxy 访问外网的话,nodejs 需要验证 proxy 证书。

所以我们通过 export NODE_EXTRA_CA_CERTS 来指定 proxy 证书。如果没有 proxy 证书则会报“unable to get local issuer certificate”。(是不是和“AWS CLI SSL: CERTIFICATE_VERIFY_FAILED 错误分析与解决”一文中的情况很相似)

图 10AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

安装成功

图 11AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

2. 测试第一个 CDK 应用

下面我们创建一个关于 S3 的 CDK 应用。

创建 App

创建 CDK 应用目录,并进入目录

mkdir hello-cdk
cd hello-cdk

创建一个空的 App

cdk init app --language python

注意:

如果运行上述命令之前,已经在环境中用如下命令配置了代理服务器

export http_proxy=YOUR_PROXY_SERVER:PORT
export https_proxy=YOUR_PROXY_SERVER:PORT

在运行 CDK 前,要把代理服务器前加上协议“http://”

export http_proxy=http://YOUR_PROXY_SERVER:PORT
export https_proxy=http://YOUR_PROXY_SERVER:PORT

否则会报如下“unsupported proxy protocal”错误

图 12AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

创建 App 完成

图 13 图 14AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

生成的文件夹结构如下图,这里我们主要关注“hello_cdk_stack.py”文件,这个文件是我们要定义 AWS 资源的地方。

图 15AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

在 App 创建后,依次运行以下命令,启动 Python 虚拟环境及安装依赖

source .venv/bin/activate
python -m pip install -r requirements.txt

图 16 图 17AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

顺便升级下 pip

图 18AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

可以用如下命令列出当前 App 中的 Stack,默认由文件夹名生成一个空的 Stack。

cdk ls

图 19AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

修改 App

配置 account, region

首先我们要配置CDK要部署的AWS环境,即account和region。

用文本编辑器打开 app.py 文件,找到如下内容,取消注释并添加 AWS Account 和 Region 信息。

    env=core.Environment(account='YOUR_AWS_ACCOUNT', region='YOUR_AWS_REGION'),
修改 Stack

到目前为止我们建了一个空的 App,现在我们在里面定义一个 AWS 资源 S3 Bucket。

在定义 S3 之前,我们先要从 AWS Construct 库中安装 S3 包

pip install aws-cdk.aws-s3

图 20 图 21AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

打开 hello_cdk/hello_cdk_stack.py 添加两段内容(中文注释的为新添加内容)

from aws_cdk import core as cdk

# For consistency with other languages, `cdk` is the preferred import name for
# the CDK's core module.  The following line also imports it as `core` for use
# with examples from the CDK Developer's Guide, which are in the process of
# being updated to use `cdk`.  You may delete this import if you don't need it
.
from aws_cdk import core
#添加引入S3
from aws_cdk import aws_s3 as s3

class HelloCdkStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> N
one:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your stack goes here
        #定义一个S3 Bucket
        bucket = s3.Bucket(self,
             "tsFirstBucket",
             versioned=True,)

说明:

bucket = s3.Bucket(self,
             "tsFirstBucket",
             versioned=True,)
  • self:指定在当前 stack 范围内(scope)
  • "tsFirstBucket":在当 stack 内唯一的逻辑 ID(ID)
  • versioned=True:是附加的参数部分(props),这里指定了为 bucket 中的文件开启 version

所有 constructs 都有这三个相同的输入参数 scope,ID, props

生成 CloudForamtion 模板(Synthesize)

运行下列命令生成 CloudForamtion 模板

cdk synth

运行结果

图 22AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

生成的模板及相关内容保存在 hello-cdk/cdk.out 目录下

cdk.out/
├── cdk.out
├── HelloCdkStack.template.json
├── manifest.json
└── tree.json

注意:

需要在 App 项目的根目录运行 cdk 命令,如果在其子目录中运行,会出现如下报错

--app is required either in command-line, in cdk.json or in ~/.cdk.json

图 23AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

部署 App

运行下列命令在 AWS 部署

export AWS_ACCESS_KEY_ID=AKIAZEGH37QUP6LRRGMS
export AWS_SECRET_ACCESS_KEY=ua2jqx0aCAoMkcxAzdxiT****
export AWS_DEFAULT_REGION=cn-north-1
export NODE_EXTRA_CA_CERTS=[THE PATH OF YOUR PROXY SERVER CERTIFICATE]
cdk deploy

运行结果

图 24AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

在 CloudFormation 中,可以看到新建的 Stack

图 25AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

在 S3 中,可以看到新建的 Bucket

图 26AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

注意:

如果在公司用代理的情况下,用“export NODE_EXTRA_CA_CERTS=”引入代理证书非常重要,如果忘记这一点可能导致以下错误。

Need to perform AWS calls for account 123456789516, but no credentials have been configured=

这个错误,一种情况是真的没有“credential”,另一种就是没有引入代理证书。

删除 App

我们可以用如下命令,删除 App,同时删除 CloudFormation 中的 Stack,但 CDK 生成的 AWS 资源默认会保留下来。

cdk destroy

如果我们想同时删除 AWS 资源,需要更改删除策略。修改 hello_cdk/hello_cdk_stack.py

        # The code that defines your stack goes here
        bucket = s3.Bucket(self,
             "tsFirstBucket",
             versioned=True,
             removal_policy=core.RemovalPolicy.DESTROY,
             auto_delete_objects=True)

说明:

  • removal_policy:指定删除策略
  • auto_delete_objects:当 S3 中有对象时,AWS 不会删除 S3 Bucket。这时需要加 auto_delete_object 参数,在删除 Bucket 前,先删除其中对象

用如下命令查看变更

cdk diff

图 28 图 29AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)说明:

可以看到增加了 Lambda 函数,此函数用来自动删除 S3 中的对象。

Lambda 函数属于上面讲的“asset”,所以我们的 AWS 环境需要做一次初始化(Bootstrap)

运行 Bootstrap

cdk bootstrap

运行结果

图 30AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

可以看到在 CloudFormation 中,新建了一个 CDKToolkit 的 Stack

图 31AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

在 S3 中,新建了一个 Bucket

图 32AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

AWS 环境初始化完成,这时我们先运行 deploy,把新的策略部署上去

cdk deploy

然后再运行 destroy

cdk destroy

图 33AWS CDK IaC 基础设施即代码 代理环境下安装配置 (Python)

这时除了 CloudFormation 的 Stack 被删除外,S3 Bucket 也被删除

图 34

总结

AWS CDK 简单来说就是,通过编程代码,生成 CloudFormation 模板及相关内容。然后由 CloudFormation 生成 AWS 环境中的具体资源。

CDK 部署的 App 删除后,CloudFormation 对应的 Stack 随即被删除,但默认 Stack 生成的 AWS 资源保留,可改变删除策略实现 AWS 资源的删除。

对于多 Python 环境,最好在使用前确保使用的是正确的 python 和 pip 命令的路径版本,这样会避免很多麻烦。

另外,对于 CDK 的 app 文件夹,不能直接改名或者移动到其它路径下,会报错。如有需要,要重新 init。

引申

看上去 AWS CDK 好像只是比 CloudFormation 多了一步用代码生成 CloudFormation 的操作,但这一步非常重要。

JSON、YAML 只是模板,Terraform 用的是配置语言并不是真正的代码。

而 AWS CDK 是用的编程语言(代码)来实现对基础架构的控制。我们可以真正像编程一样来控制基础架构。

另外,用过 CloudFormation 就知道它的 JSON 模板编写起来有多麻烦,配置一点点资源就要写很长的一段,还不好查错。

资源下载

官网 CDK 文档 

https://docs.aws.amazon.com/cdk/latest/guide/home.html

后记

这里的第一个 CDK 程序就是官网上的程序。本来以为照着官网提供的步骤做下去没问题。

在直连 internet 的环境下,确实没什么问题,测试很顺畅。等换成公司内网加代理的情况时,就变成各种报错。

好在有之前解决 AWS CLI 证书问题的经验,最后定位到是 nodejs 要求代理的证书。

这个问题在和 AWS 相关的内容中没找到解决办法,最后在关于 nodejs 的资料中查到用“NODE_EXTRA_CA_CERTS”环境变量解决。

整个过程踩了一堆坑,分享出来,以供参考。



喜欢请点赞,禁止转载,转发请标明出处

B 站 UP 主“我是手拉面” 

全是AWS干货
分享aws云经验,提供实操干货
20篇原创内容
Official Account