使用 AWS SDK
一个 Winforms 应用程序,用于配置 EC2 安全组 - 未来版 Winforms EC2 控制台。
引言
本文将全面介绍 Amazon Web Services 软件开发工具包。通过使用 C# 编写一个 Winforms 程序来配置 EC2 实例的安全组,您将能初步了解如何使用 SDK。简单来说,此程序允许您为实例设置入站[1]规则,重点在于实例之间的限制。此程序在 GUI 开发方面有很大的潜力。请注意,这里的异常检查非常稀少。
[1] 入站规则有点像您在 Windows 防火墙中设置的规则,用于限制传入流量。相反的操作是设置出站规则,这是用于传出流量的规则,您在在线控制台中看不到这些设置。
背景
我最初的想法是创建一个我自己的控制站,用于启动和维护 Amazon EC2 实例。直到我发现了 AWS Toolkit for Visual Studio,它拥有一切,我才意识到我之前的编程努力都是徒劳的。但 Visual Studio 插件更侧重于对象(快照、Ami、S3 存储桶等),而不是过程以及您习惯的做事方式。所以,我最初的需求是配置实例安全组;主要是因为我想通过不翻阅大量网页来快速更改内容,从而无需逐个读取 IP 地址等信息。
Using the Code
我使用 Visual Studio Toolkit 是因为它有一个 GUI……并且在“新建项目”对话框中包含了一些示例应用程序。
- 您需要下载并安装 AWS SDK for .NET。您可以从这里下载:下载 SDK。但等等:如果您安装了Toolkit for Visual Studio,它包含了 AWS SDK for .NET,因此您无需单独安装 SDK。您可以从这里下载 Visual Studio Toolkit:Visual Studio Toolkit。
- 在安装之前阅读此处时,您会看到其中有一部分是关于 AWS 访问凭证的。我建议您先在 Web 控制台中设置一个 IAm 用户,并在应用程序开发中使用该用户名(及其访问密钥和秘密访问密钥)。
图形用户界面
用于控制 GUI 元素的代码与代码交织在一起,没有太多关于关注点分离的考虑,所以请多包涵。
双击实例列表中的某个项目,该特定 EC2 实例的安全组将显示在中间的列表中。此时,安全组数据是从内部存储中获取的,而不是从 AWS Web 服务获取的。所有安全组都会在加载窗体时从 AWS 获取,并存储在命名为InstanceModel.cs和SettingsModel.cs的文件中声明的内部数据结构中。
单击实例列表中的某个项目,并将该实例的私有
IP 地址填充到“操作”组字段中的 CIDR 框中。
右键单击实例列表中的任意单元格,并将该实例的公共
IP 地址填充到“操作”组字段中的 CIDR 框中。
或者,您可以单击左侧的实例,并使用“操作”组字段中的私有或公共 IP 按钮来填充所选实例的 CIDR 地址。
右键单击安全组列表中的第二个级别节点,将特定的安全设置传输到“操作”面板。
单击添加规则或删除规则,对当前选定的安全组执行相应操作。
代码
建立联系
在GetInstancesFromAWS()
中,ec2Client
对象是为整个类范围创建的。这是与 AWS 通信的客户端。每当您访问任何 Amazon Web 服务时,您都可以通过声明一个以该服务名称为前缀的对象来描述上下文(您会在Amazon.EC2 API reference中找到很多“Describe this’nthat”)。在此上下文中,我们使用DescribeInstancesRequest
创建一个可以发送到 AWS 的对象。此对象包含可选参数,形式为属性设置。例如,您可以使用 filter 属性请求一个response
对象,该对象仅包含与网络接口关联了特定私有 IP 地址的实例。您还可以设置DescribeInstancesRequest
的InstanceIds
属性,以获取具有特定实例 ID 的所有实例;或者仅获取一个特定实例。例如:要获取特定实例的信息,您可以使用DescribeInstancesRequest
的InstanceIds
属性,如下所示:
DescribeInstancesRequest ec2Request = new DescribeInstancesRequest();
ec2Request.InstanceIds = new List<string>() { "i-6407c1xxx", "i-6407c1xxx2"};
如果您省略了声明InstanceIds
属性的行,您将返回所有实例。仅凭这一点不会给您带来任何好处,所以您需要像这样创建一个response
对象:
DescribeInstancesResponse ec2Response = ec2Client.DescribeInstances(ec2Request);
// int NumberofInstances = ec2Response.Reservations[0].Instances.Count;
int NumberofInstances = ec2Response.Reservations.Count;
您可以通过调用Reservations
列表属性的Count
属性来读取响应返回的实例数量。这个“Mumble Jumble”可能意味着实例可以批量预订,并且我理解有关实例的信息存储在Reservations
下的列表中。但在实践中,我认为计算预订似乎是个更好的主意,因为它能给出正确的实例数量。
获取实例数据
实例数据存储在AWSinstancedata
列表中。此列表是 SDK 类型Instance
,但我创建了自己的数据结构,其中我将来自两个单独对象(即Instances
和SecurityGroup
)的数据进行了扁平化处理。请注意,为了读取安全组,在PopulateInternalInstanceModel()
方法中会创建另一个请求和响应对象。其余代码都是平稳运行的。
为安全组编写/设置安全规则
首先,您用所有必要的信息填充一个IpPermission
对象,然后您声明一个AuthorizeSecurityGroupIngressRequest
对象用于请求,以及一个AuthorizeSecurityGroupIngressResponse
对象用于处理响应。此请求对象作为参数传递给上述ec2Client
对象的AuthorizeSecurityGroupIngress
方法。如果成功,响应对象将返回“OK”。
删除安全组的安全规则
这与设置安全规则几乎相同,只是在通过Ec2Client
访问 Amazon Web 服务时,您使用了两个不同的对象。首先,您用所有必要的信息填充一个IpPermission
对象;请求对象名为RevokeSecurityGroupIngressRequest
,响应对象名为RevokeSecurityGroupIngressResponse
。删除规则的概念如下:
作为RevokeSecurityGroupIngressRequest
对象参数设置的IpPermission
对象必须包含一个现有的协议名称、一个现有的安全组名称以及为规则注册的端口号。如果成功,响应对象将返回一个“OK”string
。
关于附加的源代码
为了尽可能减小压缩包大小,我已将 SDK 库文件从 zip 文件中取出,而是将库AWSSDK.dll作为单独的文件(AWSSDK.zip)上传。该文件可以放置在项目根文件夹(而非解决方案文件夹)。但最好使用您自己的 SDK 下载附带的AWSSDK.dll文件。
现在,开始一些完全不同的内容
我想知道是否有人对 Linq 查询的有效性进行过一些研究,但在尝试了一段时间后,我发现 Linq 是一个强大的工具。我偶然发现了SelectMany
方法,它使得从数据层级结构中投影属性变得容易。例如,在此程序中,有一个名为InstanceModel
的数据结构,它又包含一个名为SettingsModel
的结构(一个SettingModel
类型实体的列表)。如果我想投影SettingsModel
子关系中的所有实体,例如,其索引值为6
,我就可以使用SelectMany
。如果我没记错的话,这在关系数据库中需要 SQL 子查询。
这是您可以在此程序中尝试的一个示例:
List<SettingsModel> flattenedinstance2 =
SecuritySettingsForAllinstances.AsQueryable().SelectMany(w => w.SecuritySettings).Where
(b => b.index == 6).ToList<SettingsModel>();
结果将是一个有限数量的实体,前提是子关系中有一个或多个索引值为6
的实体。换句话说,如果您查询父关系Animals
中名为 dog types 的子关系,您可以从子集中投影出所有棕色的狗。我可能在这里弄错了,但到目前为止,我对SelectMany
方法感到非常惊讶。
关注点
AWS SDK 的潜在用途绝对是自动化流程,特别是那些在使用在线 AWS 控制台时通常需要跨越多个网页的流程。例如 - 如上文所述 - 您需要在在线控制台中切换到“实例”页面来读取实例的内部 IP 地址,然后再切换回“安全组”页面来插入 CIDR 地址。另一个有用的例子是,当您需要额外的计算能力来处理应用程序[2]时,您可以以编程方式启动一个新的竞价实例,然后使用此出色程序中的逻辑 :-) 来设置两个实例之间的访问限制。
关于在 AWS 中使用访问密钥:这是一篇很好的阅读材料:最佳实践。
[2] 例如,当您在处理大型文本语料库时,或者当您针对其他客户的数据库测试应用程序时。
历史
- 2014 年 6 月 1 日:更改了计算实例数量的代码行,改为计算预订数量。