亚马逊CloudFormation配置和部署

Perfect Assistant 软件助手支持亚马逊弹性云计算的CloudFormation堆栈模板平台。这是一种强大的功能,能够同时将包括服务器、数据库等多个项目栈同时部署到云。目前支持的组件包括Redis 弹性缓存以及基于RDS云存储的Postgres和MySQL数据库。

AWS 命令行工具安装

软件助手通过调用亚马逊AWS命令行工具来控制配套部署方案。如果您已经预装了AWS命令行工具,并且在当前bash路径环境变量$PATH支持下能够直接调用,则软件助手会应用当前的IAM钥匙码和预置的EC2 区域设置。

如果当前环境下尚未安装AWS命令行工具,则软件助手会在第一次调用CloudFormation部署方案配置时提示安装。该提示会自动为AWS命令行工具建立一个本地副本,并安装到路径“~/Library/Perfect/PerfectAssistant/aws/”下。

快速上手

开始之前,首先从欢迎页面的部署选项中选择“Amazon Web Services: CloudFormation”,或者在项目编辑器右侧的部署视图中新建一个亚马逊云堆栈配置。新建配置会在欢迎页面左侧“Deployment”部署栏目中出现。创建新配置方案后,配置编辑器窗口会自动打开并启动编辑操作。


选择1:从项目管理窗口中选择“Project Deployments”菜单


选择2:从欢迎页面中双击配置模板后选择创建新方案

如果是在项目编辑器中点击新建配置方案,则可以自动将新建的部署方案关联到当前项目上。您也可以随时在项目编辑器中选择预先做好的配置部署方案。


从现存配置方案中选择关联到当前项目

完成项目到部署方案的关联操作之后,请使用组合键(⌘-S)保存操作,否则关联无效。

CloudFormation方案创建或关联后,部署方案编辑器的窗口会如下图所示:


CloudFormation 部署方案及其关联项目

方案配置

首先在当前方案配置窗口中,您可以随时点击左上角的索引按钮回到项目管理目录(欢迎页面)中去。您也可以选择配置窗口顶部菜单中的各个命令:浏览器查看AWS CloudFormation管理面板、部署或者删除(取消部署)应用程序栈。

完成新建部署操作后,请给当前方案起一个名称。点击标题栏右侧“Set”按钮就可以激活名称修改栏进行编辑。编辑好标题后请键盘输入回车用于提交修改。之后必须按组合键(⌘-S)保存操作,否则编辑无效。

在标题栏下方的主配置视图中,请选择目标部署区域,并输入程序栈名称、IAM应用程序钥匙密码和SSH连接钥匙对。此外,您还可以选择目标应用程序栈部署的VPC虚拟私有云。

下面逐个介绍这些配置栏目

区域

“Region” 下拉菜单会列出所有AWS亚马逊弹性计算云部署可用地区。请注意如果区域发生改变则配套的SSH连接钥匙对和和VPC虚拟私有云都会发生变化。如果您希望在多个区域内同时部署,那么最好创建多个内容雷同但是区域设置不同的一系列方案。

应用程序栈名称

此类配置需要一个应用程序栈名称,用于识别在您的亚马逊专属资源中是否属于该应用程序栈的一部分。在您当前帐号、当前区域设置下,应用程序栈的名称必须是唯一的。一旦栈部署完成,如果改变堆栈名称则会导致现有堆栈内的资源被识别为其他栈部件而引起混乱。因此建议设置一个具有一定描述性的应用程序栈名称便于管理相关资源。

IAM 钥匙码

IAM 钥匙码必须从AWS亚马逊账号获取。您之前输入过的IAM 密码都会在下拉菜单中列出。点击“Add ...”按钮能够输入新的钥匙码,内容包括钥匙编号、密码和该代码的描述信息。

软件助手会对AWS命令行工具中引用的密码文件进行读写。该文件位于“~/.aws/credentials”。如果您在使用软件助手之前已经输入过AWS密码,则这些密码会出现在菜单中。同样在软件助手中输入的AWS密码一样会在命令行中体现,二者是互通的。

SSH 钥匙对

钥匙对用于通过SSH连接您的云虚拟机实例并进行管理员操作。尽管您可能不会手工进行SSH操作,但是在部署中该钥匙对是需要的。任何现有的钥匙对都会出现在钥匙对的下拉菜单中。

点击“Add ...”按钮会弹出一个对话框拥有创建新钥匙对,或者导入一个现成的钥匙对。

如果希望执行该操作,首先要输入钥匙名称,然后选择“创建钥匙对”,或者“导入钥匙对”

Create Key Pair 用于创建一个新的钥匙对,即一把公有钥匙,一把私有钥匙。公有钥匙会发给AWS,而私有钥匙则会提示保存到本地磁盘。如果需要用该钥匙进行SSH连接,请到您的“~/.ssh”目录下选择私有钥匙文件。软件助手会提示一个对话框用于选择这些隐藏目录。此外无论您把钥匙保存到哪一个路径,私有钥匙文件都会被重新设置权限,即除非您本人账号可以读写之外,其他任何账号都无法读取该钥匙的内容。

Import Key Pair会提示您选择一个现有的公有钥匙文件。该文件会被发给AWS,而私有钥匙请自行保管。

钥匙对是无法跨区使用的,这意味着无论是新建钥匙对还是导入钥匙对,一旦您选择了另外一个区域,则钥匙对不会在新选择的区域内自动出现,除非您将公有钥匙再次导入到新选区域。因此右侧的“Add to all regions”选项能够解决钥匙跨区问题,即新建或导入的钥匙对能够在所有AWS区域机房内跨区通用。

虚拟私有云

软件助手在设置CloudFormation部署方案中能够自动创建一个新的VPC(虚拟私有云)以及为新建的应用程序栈配套的公有云及私有云子网。但是如果您在进行该部署方案配置之前已经有了VPC,则您也可以选择部署到现存VPC上。VPC下拉菜单会列出所有已建成的虚拟私有云,并且还有“managed”(已管理)选项,也是如此。

在这里推荐使用默认的“managed”配置,当然您也可以从下拉菜单中选择部署到已有的VPC网络。如果VPC被设置为“managed”则首次部署新应用程序栈时会自动创建一个新的虚拟私有云。不过不论是新建还是加载现有VPC,公有子网和私有子网都会在部署过程中自动建立。如果整个应用程序栈被删除,则任何由该方案创建的资源也会被一同清理释放。

资源

在这里所谓的“资源”指的是用于构成整个应用程序栈的一部分因公程序,比如您的Swift应用服务器软件,以及配套的组件服务器,比如用户认证服务器、RDS关系数据库活着一个ElasticCache弹性缓存服务器。当您将项目关联到部署配置方案时您就能够从该方案的资源清单中看到这些附属服务器。您还可以随时通过点击“➕”号按钮添加应用程序栈需要的任何资源。点击后会弹出菜单列出所有可用资源。此时您可以看到诸如Redis、Postgres和MySQL等等一系列业务专用服务器,我们称之为“Swiftlets”,即当前我们支持的基于Swift语言的一系列服务器。请根据您自己的项目决定是否采用这种架构。

所有这些追加到应用程序栈的资源都会一同部署,并根据其公有子网属性和私有子网属性决定在部署时在公网中提供服务,还是仅为云端的私网提供服务。此外,通过增加在项目编辑器的端口控制,您可以要求软件助手在部署过程中根据端口控制自动创建安全组。

每个资源类型都有其自己的配置和选项,在此说明如下:

项目资源

如果您将一个项目关联到一个CloudFormation配置时,项目的可执行二进制文件编译目标将被追加为一个资源。您可以在项目管理资源清单中看到该项目。注意这些关联的项目是无法和其他资源一样在CloudFormation的方案中删除的,您必须从项目的配置方案中手工解除关联。

如果当前项目需要在云端对公服务,则必须在项目编辑器内正确设置“Deploy Port”部署端口。请确定在项目编辑器中的任何修改操作都要用组合键(⌘-S)进行保存。


项目编辑器的测试端口和部署端口。

在一个项目资源首次部署之前,该资源不会拥有一个堆栈部件编号,并且状态图标会显示为红色并标明“No ID”。 一旦项目成功部署则会被自动分配一个编号并且在服务器实例启动中,状态灯会显示黄色,直到实例完全运行之后,才会显示为绿色。

每个项目资源栏目都包含不同的设置和选项。每个选项都可以通过点击标题右侧的编辑按钮进行修改。这些选项分类如下:

地址控制 —— 用于弹性地址IP创建和分配。


任何已经申请的弹性计算IP地址都会出现在“existing”弹出菜单。

实例类型 —— 用于决定实例所需的CPU和内存数量


该弹出菜单能够包括所有有效的AWS EC2 实例类型。

访问控制 —— 允许或者禁止一个或多个IP地址的SSH远程访问


默认设置为禁止SSH远程访问。

负载伸缩 —— 允许通过负载均衡器自动伸缩。同时用于控制负载均衡器的加密证书配置。


如果允许自动负载伸缩,则实际上是允许通过创建一个负载均衡器,根据流量调度是否在幕后启动一个或者多个服务器实例,即如果当前流量超标则自动启动新的服务器实例用于继续接受新的客户访问。

其中,“minimum size”用于控制负载均衡器至少启动的实例数量,而“maximum size”用于即使出现负荷极限时,允许启动的最大实例数量。软件助手能够在当前选择的随机区域内自动创建两个公有子网和两个私有子网。每个子网均应用这两个极限配置数值。比如,如果设置了实例最低启动数量,则负载均衡器会在每个公网内启动一个实例(如果禁止公网访问则会在私网内启动)。因此,服务器总是会保证最少两个实例正在运行。这种方式不但能够防范应用程序的软件故障,并且能够实现硬件的容灾备份。将服务器放置在不同的可用区内能够有效确保不是所有服务器实例都在同一个物理计算机上运行。

负载均衡器会不时向服务器根路由发送一个http请求以检测服务器响应能力。如果响应变慢或者服务器无法访问,则额外的实例就会自动启动用于应对新的请求,直到到达最高实例启动限额。如果响应速度重新变快,则之前启动的实例会被逐个关闭,直到回到最低实例配额。此外,负载均衡器会利用“粘滞会话”技术,即尝试将请求个体尽量重新定向到同一个服务器上去。

一旦负载均衡器被成功部署,则会绑定到一个亚马逊的公网域名上。为了能够使用您自己的域名,您需要增加一个CNAME用于映射到亚马逊的这个域名。在部署完成后该亚马逊域名会出现在同一个“自动伸缩”设置页面中。

负载均衡器支持通过亚马逊ACM证书管理器注册或创建的证书。此类证书会在“TLS 证书管理器”下拉菜单中显示。注意只有在负载均衡功能开启后这些证书才会显示。当使用该功能时,请注意您的服务器只能监听一个端口,通常来说就是80端口。如果不使用负载均衡器的时候,请不要使用443端口。负载均衡器会监听443端口并将所有请求转发到目标服务器。

Swiftlet预制应用

一个Swiftlet小应用是一个预制的、具有特定功能Swift组件服务器。参考范例中已经包括了不少这样的小应用,比如认证服务器或者日志处理器。您可以通过“增加资源”菜单追加这些小应用。


在可追加资源菜单中的Perfect认证服务器小应用

Swiftlet小应用通常与其他应用保持应用关系——比如需要RDS数据库。这种情况下,增加一个小应用会自动将依存资源一同追加。小应用同其他所有普通项目资源一样允许正常配置。除此之外,Swiftlet小应用还能够有一系列选项供配置。比如,Perfect Auth Server认证服务器就允许与外部服务通过一系列关键字段进行通信。


Perfect认证服务器小应用的可选项

如果要删掉一个小应用,请选择该条目并按下删除键即可。这种情况下配置方案已经改变,必须按下(⌘-S)用于变更生效。

RDS资源

在“add resource”(增加资源)菜单中您还可以根据需要为应用程序栈增加关系型数据库实例。目前Perfect Assistant支持PostgreSQL和MySQL的RDS实例。一旦RDS实例被添加到您的堆栈配置中,您可以对不同的选项进行修改调整。所有的RDS选项都是一样的,与数据库类型无关。可选项分组如下:

资源名称——每个应用程序栈的资源都必须有一个唯一的名称。RDS实例能够自动获得一个默认名称,但是您可以随时修改这个名称,只要名称内不包含特殊字符。资源名称必须要用英文字母开头,名称内只能包括英文字母或数字。如果在资源已经配置完成后再变更名称,则会将当前实例移除,并重新部署一个新的实例。

资源类型——用于控制数据库所需的资源尺寸。


该菜单列出了所有亚马逊AWS RDS实例类型。

访问控制——用于设置数据库的用户名、密码、端口,并决定是否允许实例在运行中拥有一个或多个公网地址。


默认情况下RDS的公网访问是被禁止的,并被自动分配一个用户名和密码。

如果要删掉一个RDS数据库实例,请选择该条目并按下删除键即可。这种情况下配置方案已经改变,必须按下(⌘-S)用于变更生效。

弹性缓存资源

目前软件助手仅支持Redis弹性缓存实例。一旦Redis被追加到您的应用程序栈,您就可以进行方案配置。可选项分类如下:

资源名称——每个应用程序栈的资源都必须有一个唯一的名称。ElastiCache实例能够自动获得一个默认名称,但是您可以随时修改这个名称,只要名称内不包含特殊字符。资源名称必须要用英文字母开头,名称内只能包括英文字母或数字。如果在资源已经配置完成后再变更名称,则会将当前实例移除,并重新部署一个新的实例。

资源类型——用于控制缓存所需的资源尺寸。


该菜单列出了所有亚马逊AWS ElastiCache实例类型。

如果要删掉一个ElastiCache资源实例,请选择该条目并按下删除键即可。这种情况下配置方案已经改变,必须按下(⌘-S)用于变更生效。

连接变量

当您的应用程序栈部署后,所有的资源连接变量,包括主机名称、端口、用户名和地址,都能够进行发布并为堆栈内的服务器提供服务。您可以通过Perfect CloudFormation组件轻松访问这些关键变量。该组件函数库被设计为轻量、简洁,并与所有Swift服务器框架兼容。您只要在您项目的Package.swift文件中包含以下依存关系即可:

.Package(url: "https://github.com/PerfectlySoft/Perfect-CloudFormation.git", majorVersion: 0)

该函数库包括了三个不同的程序接口,分别用于对接应用程序栈中的RDS、ElastiCache和Swiftlet。

加载RDS实例

public enum CloudFormation {
	public struct RDSInstance {
		public enum DBType {
			case postgres, mysql
		}
		public let resourceType: DBType
		public let resourceId: String
		public let resourceName: String
		public let userName: String
		public let password: String
		public let hostName: String
		public let hostPort: Int
	}
}

public extension CloudFormation {
	static func listRDSInstances() -> [RDSInstance] 
	static func listRDSInstances(type: RDSInstance.DBType) -> [RDSInstance]
}

通过使用“listRDSInstances”函数,您的应用程序可以获得应用程序栈内所有RDS实例的信息,或者获取一个具体类型的实例信息。

加载ElastiCache弹性缓存实例

public enum CloudFormation {
	public struct ElastiCacheInstance {
		public enum ElastiCacheType {
			case redis
		}
		public let resourceType: ElastiCacheType
		public let resourceId: String
		public let resourceName: String
		public let hostName: String
		public let hostPort: Int
	}
}

public extension CloudFormation {
	static func listElastiCacheInstances() -> [ElastiCacheInstance] 
	static func listElastiCacheInstances(type: ElastiCacheInstance.ElastiCacheType) -> [ElastiCacheInstance]
}

通过调用“listElastiCacheInstanes”函数,您的服务器可以获得所有缓存服务器的接口方法,或者特定服务器的信息。注意:目前仅支持Redis

加载Swiftlet小应用实例

public enum CloudFormation {
	public struct SwiftletInstance {
		public let resourceId: String
		public let resourceName: String
		public let hostName: String
		public let hostPorts: [Int]
	}
}

public extension CloudFormation {
	static func listSwiftlets() -> [SwiftletInstance]
}

通过调用"listSwiftlets"函数您的应用程序可以获得所有小应用的接口信息。然而每个小应用具体的连接参数和用法都是千变万化的,因此您需要查阅每个小程序的具体文档。

部署应用程序栈

一旦完成所有的方案配置和资源准备,只要点击工具栏按钮“Deploy”即可开始全栈部署。 堆栈内所有资源都会被逐个推送到云端。软件助手的任务窗口会处于开启状态并提供每一步操作结果的远程反馈,包括所有关联的小应用的本地linux编译并以发行模式进行编译。所有这些编译操作都是同步执行。每一个编译结果都会完成一套二进制程序并拷贝到您账号的S3云端文件库(桶)中。每个“桶”都以“perfect-deployed”开头并跟随一个随机的短名字。每个应用程序栈成品都将被放置在这个“桶”中,然后以不同命名的子目录区分堆栈应用。随后软件助手会自动创建一个CloudFormation模板然后发给AWS用于部署整个应用程序栈。您能够在“桶”中看到这个模板,以及所有其他编译成品。

一旦部署请求发送到AWS后,您可以在部署状态栏中看到结果。详细报告请通过点击“CloudFormation Console”工具栏按钮,此时软件助手会自动打开浏览器并跳转到CloudFormation控制面板页。如果应用程序栈部署完成,则栈状态会显示为“CREATE_COMPLETE”。

注意整个部署根据堆栈内资源数量的不同,可能需要数分钟时间或更久。实测中单个程序构成的堆栈几分钟就可以完成部署,但是如果包括RDS实例,可能会长达20分钟以上。因此整个部署过程需要一顶的耐心。如果您在提交部署后,发现部署失败,则打开CloudFormation的控制面板可以看到出错原因,用于调试。

一旦AWS服务器创建了目标资源,则部署配置窗口内的状态指示灯都会逐个亮起。整个服务栈完全部署成功并全面运行可能需要数分钟时间。每个代表资源的标签页上,在部署成功开始运行时,会提供访问链接——有可能是端口号、指向该服务器的连接,或者是AWS对应资源页上的链接。

对比一下项目资源在部署前后标签页的不同:


点击资源代码会打开该资源在AWS控制面板页对应的链接。点击端口可以查看目标服务器。

更新应用服务器堆栈部署

如果您的应用程序栈中的某些组件需要更新,或者您需要重新配置某个资源,则整个服务器程序栈都需要重新部署。如果之前已经成功部署,则点击“Deploy Stack” 按钮会进行更新。只有变更部分的内容会进行重新发布。比如,如果是因为一些代码发生了变化,则您只需要重新部署这段代码所在的组件即可,其他资源,比如RDS关系数据库,则保持不动,也不会因为部署而暂停。

通常如果是因为代码变更而导致的重新部署应该都能够很快完成。但是,请注意因为每个Swift服务器会在每两分钟完成一次轮询,因此要确认部署成功也需要至少两分钟。

如果是改变了实例的类型或者计算资源(处理器/内存/磁盘),那么实例可能需要关闭并重新启动部署一个新版本。

一旦应用程序堆栈更新完成,则堆栈状态应该变成“UPDATE_COMPLETE”。

删除应用程序栈

点击工具栏按钮“Delete Stack”后,软件助手首先要确认您是否准备删除堆栈。如果确认则所有已创建资源都会被删除,包括所有实例、已管理的弹性计算IP地址、虚拟私有云以及子网,等等等等所有内容均会被删除。唯一的例外就是每个RDS实例会保留数据库快照到备份中。您可以随时手工删除这些快照。