基于AWS cloudformation的部署框架
项目描述
humilis
帮助您使用 Cloudformation 部署AWS基础设施。
该项目最初基于 cumulus 项目。有关许可证信息,请参阅 CUMULUS_LICENSE。
安装
安装 AWS CLI
pip install awscli
配置AWS CLI
aws configure
humilis 将使用您在配置AWS CLI安装时提供的任何凭据。
现在您可以安装最新“稳定”版本的 humilis
pip install humilis
如果您更喜欢开发版本
pip install git+https://github.com/humilis/humilis
安装后,您需要配置humilis。要为系统全局配置
humilis configure
上面的命令将存储和读取配置选项,来自~/.humilis.ini。您也可以通过以下方式,将配置存储在当前工作目录下的.humilis.ini文件中:
humilis configure --local
humilis将始终首先从当前工作目录下的.humilis.ini文件中读取配置。如果未找到,则从系统全局配置文件~/.humilis中读取。
开发环境
假设您已安装virtualenv
make develop . .env/bin/activate
测试
目前,大多数测试都是与AWS SDK的集成测试。这意味着如果您想运行测试套件,您需要设置系统以访问AWS资源。
py.test tests
快速入门
根据示例目录中的示例定义您的基础设施环境。然后,要创建环境
humilis create examples/humilis-firehose.yaml
在部署后更新环境
humilis update examples/humilis-firehose.yaml
以及删除它
humilis delete examples/humilis-firehose.yaml
Humilis环境
humilis环境只是所需用于应用程序的云formation堆栈的集合。而不是为您的完整应用程序有一个单一的CF模板,humilis允许您定义基础设施层,它们被组合成一个环境。每个humilis层精确地对应一个CF模板(因此层部署后对应一个CF堆栈)。
将复杂的基础设施环境分解成更小的层至少有两个明显的优点
易于维护。维护仅包含一些CF资源的简单层比维护一个有明确目的的服务要容易。
易于重用。您应该努力以使您的基础设施层可以在各种环境中重用。例如,许多项目可能需要一个基础层,该层定义了VPC、几个子网、网关和一些路由表,可能还有一个(管理的)NAT。您可以为这些资源定义一个humilis层,并设置一组层参数(例如,VPC CIDR),这将允许您轻松地在环境中重用它。
环境结构
环境定义文件是一个yaml文档,它指定了构成您环境的层列表。文件应命名为您的环境。也就是说,对于环境my-app-environment,环境描述文件应称为my-app-environment.yaml。环境定义的内容应按以下方式组织
--- my-app-environment: description: A description of what this environment is for layers: # The layers that you environment requires. They will be deployed in the # same order as you list them. Note that you can also pass parameters # to a layer (more on that later). - {layer: name_of_first_layer, layer_param: layer_value} - {layer: name_of_second_layer} - {layer: name_of_third_layer}
层结构
与特定层相关的一切都必须存储在与层同名且位于环境定义文件相同目录下的目录中。如果我们考虑上面使用的my-app-environment环境,那么您的目录树应如下所示
. ├── my-app-environment.yaml ├── name_of_first_layer │ ├── meta.yaml │ └── resources.yaml ├── name_of_second_layer │ ├── meta.json │ └── meta.yaml └── name_of_third_layer ├── resources.json.j2 └── resources.yaml.j2
一个层至少包含两个文件
meta.yaml:有关层的元信息,例如描述和层参数。
resources.yaml:基本上是一个包含层的资源的CF模板。
这两个文件也可以是.json格式(meta.json和resources.json)。或者,如果您想使用Jinja2模板编译器预处理文件,可以添加扩展名.j2。
以下是一个层meta.yaml可能的样子示例
--- meta: description: Creates a VPC, that's it parameters: vpc_cidr: description: The CIDR block of the VPC value: 10.0.0.0/16
上面我们只声明了一个层参数:vpc_cidr。Humilis会将该参数传递给Jinja2,以便在编译层中包含的任何模板时使用。因此,同一层的resources.yaml.j2可能看起来像这样
--- resources: VPC: Type: "AWS::EC2::VPC" Properties: CidrBlock: {{ vpc_cidr }}
参考
您可以在您的meta.yaml文件中使用引用来引用除同一层中的资源以外的其他事物(要引用层中的资源,您可以使用CloudFormation的Ref或GetAtt函数)。Humilis引用通过设置层参数的值为具有ref键的字典来使用。以下是一个引用另一个层(称为vpc_layer)中包含的资源(逻辑名称为VPC)的meta.yaml
--- meta: description: Creates an EC2 instance in the vpc created by the vpc layer dependencies: - vpc parameters: vpc: description: Physical ID of the VPC where the instance will be created value: ref: parser: layer parameters: layer_name: vpc_layer resource_name: VPC
每个引用都必须有一个parser键,以标识用于解析引用的解析器。还有两个可选键
parameters:允许您向引用解析器传递参数。您可以传递命名参数(作为字典)或位置参数(作为列表)。
priority:解析优先级。值较低的priority参数将先于值较高的参数解析。这允许某些引用解析器在同一个层内部部引用其他参数。例如,当解析模板化的lambda代码时,lambda解析器使用之前解析的层参数作为模板参数。
有关Humilis附带的相关引用解析器的更多信息,请见下文。
可用的引用解析器
layer_resource引用
layer_resource引用允许您引用另一个层中资源的物理ID。
参数:
layer_name:您要引用的层的名称
resource_name:层资源的逻辑名称
示例:
考虑以下环境定义
--- my-environment: description: Creates a VPC with a NAT in the public subnet layers: - {layer: vpc} - {layer: nat}
显然,负责在公共子网中部署NAT的nat层需要知道该子网的物理ID。您可以通过在nat层的meta.yaml中声明layer_resource引用来实现这一点
--- meta: description: Creates a managed NAT in the public subnet of the NAT layer parameters: subnet_id: description: The physical ID of the subnet where the NAT will be placed value: ref: parser: layer_resource parameters: layer_name: vpc # The logical name of the subnet in the vpc layer resource_name: PublicSubnet
当解析meta.yaml时,Humilis将用以下内容替换它
ref: parser: layer_resource parameters: layer_name: vpc # The logical name of the subnet in the vpc layer resource_name: PublicSubnet
以所需的物理ID(例如subnet-bafa90cd)替换。然后您可以在nat层的resources.yaml.j2部分中使用此物理ID
{# Pseudo-content of layers/nat/resources.yaml.j2 #} resources: {# An Elastic IP reservation that will be associated to the NAT #} NatEip: Type: 'AWS::EC2::EIP' Properties: {} {# Custom resource deploying the NAT #} NatGateway: Type: 'Custom::NatGateway', Properties: {# The ARN of the Lambda function backing the custom resource #} ServiceToken: 'arn:aws:lambda:eu-west-1:XXXX:function:CreateNatGateway' {# Here we use the subnet_id reference defined in meta.yaml #} SubnetId: {{subnet_id}} AllocationId: Ref: NatEip
environment_resource引用
environment_output引用允许您引用属于其他Humilis环境的资源。
参数:
environment_name:您要引用的环境的名称
layer_name:您要引用的层的名称
resource_name:层资源的逻辑名称
layer_output引用
layer_output引用允许您引用由另一个层产生的输出。
参数:
layer_name:您要引用的层的名称
output_name:输出参数的逻辑名称
通常,您应该首选使用layer_output引用而不是layer_resource引用。层产生的输出参数定义了一个非正式的层接口,它比层中资源的逻辑名称更有可能保持不变。
boto3引用
boto3 引用定义了对 boto3facade 的任意调用。后者只是 boto3 之上更简单的封装接口。
参数:
service:AWS 服务,例如 ec2 或 cloudformation。注意,只有 boto3facade 中有封装的 AWS 服务才受支持。
call:相应的封装方法,例如 get_ami_by_name。此参数的值必须是一个字典,包含一个 method 键(要调用的封装方法名称)和一个可选的 args 键(传递给封装方法的参数)。最好查看下面的示例来理解它是如何工作的。
output_attribute:可选。如果提供,引用解析器将返回封装方法返回的对象中此属性的值。
以下是一个使用 boto3 引用的示例
--- meta: description: Creates an EC2 instance using a named AMI # More stuff omitted for brevity ami: description: The AMI to use when launching the EC2 instance value: ref: parser: boto3 parameters: service: ec2 call: method: get_ami_by_name args: - test-ami output_attribute: id
humilis 将使用以下代码解析引用
# Import the Ec2 facade from boto3facade.ec2 import Ec2 # Create a facade object ec2_facade = Ec2() # Make the call ami = ec2_facade.get_ami_by_name('test-ami') # Extract the requested attribute ref_value = ami.id
文件引用
文件引用 允许您引用本地文件。该文件将被上传到 S3,引用将评估为相应的 S3 路径。
参数:
path:文件的路径,相对于层根目录。
lambda 引用
lambda 引用允许您引用您本地机器上的某些 Python 代码。如果您的代码遵循一些简单约定,humilis 将为您处理构建 部署包,将其上传到 S3,引用将评估为部署包的 S3 路径。
参数:
path:指向完全自包含的 .py 文件或 lambda 代码根目录的路径。在后一种情况下,您的代码需要遵循一些简单约定才能正常工作。更多信息见下文。
dependencies:要包含在 Lambda 部署包中的依赖项列表。依赖项可以是可安装的 pip 包,或本地 Python 包或模块的路径,或本地 requirements 文件的路径。
示例:
ref: parser: lambda parameters: # Path to the root directory containing your lambda code path: dummy_function dependencies: # The Lambda code requires Pypi's pyyaml - pyyaml # It also requires a local package in this path - mycode/mypkgdir # And this local module - mycode/mymodule.py
将评估为类似以下 S3 路径
s3://[bucket_name]/[environment_name]/[stage_name]/[func_name]-[commithash].zip
代码约定:
按照上面的示例,负责部署 dummy_function lambda 的层的目录内容可能如下所示
. ├── dummy_function │ ├── dummy_function.py │ └── setup.py ├── meta.yaml ├── outputs.yaml.j2 └── resources.yaml.j2
基本上,您所有的代码都需要包含在 dummy_function 目录下。在这种情况下,只有一个文件:dummy_function.py。外部依赖项需要在您的 setup.py 中指定。
secret 引用
secret 引用使用 Python 的 keyring 模块检索秘密。
参数:
service:与秘密关联的服务名称。
key:标识秘密的键(例如用户名)。
示例:
ref: parser: secret parameters: {"service": "mysqldb", "key": "adminuser"}
自定义 Jinja2 过滤器
Humilis 定义了以下 自定义 Jinja2 过滤器
uuid:一个随机 UUID。示例:{{''|uuid}}。
password(length=8):一个随机密码。示例:{{10|password}}。
项目详情
humilis-1.7.1.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d989727c604608dc0aac2900bdeeb826f885bfd65aab81b2f89ccd70225307c2 |
|
MD5 | 60fb9e71a620f1710e56bd164e249571 |
|
BLAKE2b-256 | dbc7cdc76915e8d15b46dcce91ba3b92a36a697116655a8f821d1291876a68f9 |