使用 Pulumi 打造自己的多云管理平台
前言
在公有云技术与产品飞速发展的时代,业务对于其自身的可用性提出了越来越高的要求,当跨区域容灾已经无法满足业务需求的情况下,我们通常会考虑多云部署我们的业务平台,以规避更大规模的风险。但在多云平台部署的架构下,多云资源的管理成为了一个耗时耗力,管理与运维成本颇高的难点。这导致了第一,云管人员需要精通掌握两家甚至多家云厂商的技术与服务产品,或者第二,多支独立团队分别运维与管理导致的高团队成本等诸多痛点。所以公有云资源纳管平台(以下简称云管平台)应运而生。
亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术,观点,和项目,并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏,看到这里请一定不要匆匆划过,点这里让它成为你的技术宝库! |
云管平台简化了运管人员的操作流程,降低了公有云产品的技术门槛,但是在多云产品的集中式纳管上,却难度重重。其一,不同公有云厂商,使用独立的 infrastructure-as-code (以下简称 IaC )体系或者服务,譬如亚马逊云科技的 Cloudformation 服务;其二,不论云厂商还是开源的 IaC 产品,均使用标记语言或者类标记语言编写代码,鲜有使用 Java, Python 或者 Golang 等开发语言的运行时,这对于精通于开发语言的,云管平台的开发人员导致了额外学习成本,需要从0开始学习标记语言,往往会导致开发团队的抵触甚至拒绝;其三,标记语言运行过程中,更倾向于将整体堆栈运行完毕之后,输出对应的 outputs,但在运行过程中,存在难以直接循环调用 outputs,无法写入数据库等诸多难点,这增大了编写难度以及代码编写工作量。有没有一款产品,能够适配主流公有云 IaC,又可以使用高级编程语言编写代码呢?
什么是 Pulumi?
Pulumi 是非常流行的,现代化 IaC 平台。Pulumi 引入了主流编程语言,譬如 JavaScript,Python,Java,Golang,.NET,以及标记语言 YAML,可以使用上述语言,通过 Pulumi SDK 管理不同云厂商的资源。Pulumi 目前已经支持了主流公有云厂商譬如亚马逊云科技,微软 Azure,谷歌云与阿里云,及其生态譬如 Fastly,Akamai,Cloudflare,Kubernetes,Kong,Apache Kafka 等。
Pulumi 的组成如下图所示:
每一个 Pulumi 项目包含至少一个程序组,程序组由编程语言书写,描述不同资源的运作

以及彼此之间的关系。
以下以 Python 代码为例,描述我们在 Pulumi 中创建了 web-sg 名称安全组,并附加该安全组,以 ’ami-6869aa05’为镜像,创建了实例规格为 t2.micro 的 EC2 虚拟机。
import pulumi
import pulumi_aws as awsgroup = aws.ec2.SecurityGroup('web-sg',description='Enable HTTP access',ingress=[{ 'protocol': 'tcp', 'from_port': 80, 'to_port': 80, 'cidr_blocks': ['0.0.0.0/0'] }])server = aws.ec2.Instance('web-server',ami='ami-6869aa05',instance_type='t2.micro',vpc_security_group_ids=[group.name]
)pulumi.export('public_ip', server.public_ip)
pulumi.export('public_dns', server.public_dns)
Pulumi 如何工作 Pulumi 的运作由几个部分组成:
第一,语言处理中枢。Language Host 负责运行 Pulumi 的程序,并为您的开发语言准备好与之对应的环境,譬如 Python3.7。语言中枢由两部分组成:
1.执行器。它会协助 Pulumi 准备并设置好相应的 Runtime(运行时);

2.运行时。它会负责为您编写的程序做好运行准备,并在过程中监控程序的运行。
第二,资源提供方 Provider。
资源提供方通过资源插件(Resource Plugin,用来管理资源)与原生 SDK 协作,来管理云端资源。
有了上述两部分组成,Engine 引擎就可以实现云端资源的管理。引擎已经被封装进 pulumi cli,无需额外安装与部署。
如何创建一个 Pulumi 项目
1.安装 Pulumi(以 Linux 为例)
curl -fsSL https://get.pulumi.com | sh
复制代码
2.安装运行时(以 Python 为例)
请阅读 如何在 Linux 上安装 Python3 本文不再复述
3.配置权限
请阅读 安装或更新最新版本的 Amazon CLI ,完成 Amazon CLI 的安装,本文不再复述
请阅读 配置 Amazon CLI 完成完成权限配置,本文不再复述
4.创建新项目
$mkdir newproject && cd newproject
$pulumi new aws-python
Pulumi new 的命令行会通过交互式的方式,为您创建新的项目与新的堆栈(stack),并安装好所有需要的组件(Module)。



5.部署这个项目
执行 pulumi up 进行项目部署

执行成功后,我们可以在 S3 中看到有 pulumi 创建出来的 S3 桶

6.调整项目部署
我们要在已经部署的项目中,做出一些调整。之前的部署结束后,我们创建了一个 S3 桶,这次我们需要为其添加一个 index.html 并将其托管为静态站点
6.1创建站点首页
#touch index.html
在其中添加文本:
<html><body><h1>Hello, Amazon!</h1></body>
</html>
保存后,编辑__main__.py
在结尾处添加:
bucketObject = s3.BucketObject( ‘index.html’, bucket=bucket.id, source=pulumi.FileAsset(‘index.html’))
再次执行 pulumi up 变更部署

6.2 调整部署
这次我们需要编辑 S3 bucket 的属性,使其托管静态站点,并调整 Bucket ACL,使其可以被匿名访问。
编辑 main.py
替换 bucket segment,使其成为:
bucket = s3.Bucket('my-bucket',website=s3.BucketWebsiteArgs(index_document="index.html",
))
在结尾处,增加输出:
pulumi.export('bucket_endpoint', pulumi.Output.concat('http://', bucket.website_endpoint))
执行 Pulumi up,发布项目变更后,得到输出结果:
Outputs:+ bucketEndpoint: "http://my-bucket-e7bfd5a.s3-website-us-west-2.amazonaws.com"bucketName : "my-bucket-e7bfd5a"
访问 bucketEndpoint,我们可以看到

7.销毁项目
我们可以执行 pulumi destroy 销毁项目。

结论
通过这个简单的案例,我们展示了通过 pulumi 可以轻松的创建,管理与删除一个项目,在项目中,我们可以创建,调整,管理,删除与项目相关的 Resource,将 pulumi 与编程语言相结合,可以实现云管平台的个性化需求,并通过云管平台的几次点击,实现复杂逻辑下,不同云服务的组合,满足业务场景的需求。
额外案例
我们会额外提供几个 pulumi program,方便大家直观的了解到 pulumi 的编码方式。
创建一个名称为 “DocumentDBCluster”Amazon DocumentDB 的 Cluster,自动备份保存15天,必须开启删除保护。然后将 DocumentDB Cluster Endpoint 输出。
import pulumi
import pulumi_aws as awsdocdb = aws.docdb.Cluster("docdb",backup_retention_period=5,cluster_identifier="DocumntDBCluster",engine="docdb",master_password="mustbeeightchars",master_username="foo",deletion_protection=True,skip_final_snapshot=True)
pulumi.export('DocumentCluster_endpoint', docdb.endpoint)
下面是一个稍微复杂一些的场景:
场景共由五个部分组成,第一部分,环境定义;第二部分,创建 SSH&HTTP 的安全组,第三部分,创建 EC2 并附加 EIP,第四部分,创建 Aurora ServerlessV2,第五部分,输出。大家能够通过下列 python 代码与场景逐一对应。
import pulumi
import pulumi_aws as awsconfig = pulumi.Config()
availability_zone = config.require("availabilityZone")
environment_type = config.get("environmentType")
if environment_type is None:environment_type = "dev"
ami_id = config.get("amiID")
if ami_id is None:ami_id = ""
ami_id_value = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" if ami_id == "" else aws.get_ssm_parameter_string().value
key_pair_name = config.require("keyPairName")
db_instance_identifier = config.get("dbInstanceIdentifier")
if db_instance_identifier is None:db_instance_identifier = "mydatabase"
db_username = config.get("dbUsername")
if db_username is None:db_username = "postgres"
db_password = config.require("dbPassword")web_app_security_group = aws.ec2.SecurityGroup("webAppSecurityGroup",name="webAppSG",description="Allow HTTP/HTTPS and SSH inbound and outbound traffic",ingress=[aws.ec2.SecurityGroupIngressArgs(ip_protocol="tcp",from_port=80,to_port=80,cidr_ip="0.0.0.0/0",),aws.ec2.SecurityGroupIngressArgs(ip_protocol="tcp",from_port=443,to_port=443,cidr_ip="0.0.0.0/0",),aws.ec2.SecurityGroupIngressArgs(ip_protocol="tcp",from_port=22,to_port=22,cidr_ip="0.0.0.0/0",),
])web_app_instance = aws.ec2.Instance("webAppInstance",availability_zone=availability_zone,image_id=ami_id_value,instance_type="t2.small",key_name=key_pair_name,security_groups=[web_app_security_group.id,default,])
web_app_eip = aws.ec2.EIP("webAppEIP",vpc=True,
instance=web_app_instance.id)web_app_database = aws.rds.Cluster("webAppDatabase",cluster_identifier=db_instance_identifier,engine="aurora-postgresql",engine_mode="provisioned",engine_version="13.6",database_name=db_username,master_username=db_username,master_password=db_password,serverlessv2_scaling_configuration=aws.rds.ClusterServerlessv2ScalingConfigurationArgs(max_capacity=1,min_capacity=0.5,))
web_app_database_instance = aws.rds.ClusterInstance("webAppDatabaseInstance",cluster_identifier=web_app_database.id,instance_class="db.serverless",engine=web_app_database.engine,engine_version=web_app_database.engine_version)pulumi.export("websiteURL", web_app_eip.id.apply(lambda id: f"http://{id}"))
pulumi.export("webServerPublicDNS", web_app_instance.public_dns_name)
pulumi.export("webAppDatabaseEndpoint", web_app_database.endpoint)
参考资源:
了解 Pulumi 的 Registry
https://www.pulumi.com/registry?trk=cndc-detail/
安装 Python3
https://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/install-linux-python.html?trk=cndc-detail
安装或更新最新版本的 Amazon CLI
https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/getting-started-install.html?trk=cndc-detail
配置 Amazon CLI
https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli-chap-configure.html?trk=cndc-detail
本篇作者

付晓明
亚马逊云解决方案架构师,负责云计算解决方案的咨询与架构设计,同时致力于数据库,边缘计算方面的研究和推广。在加入亚马逊云科技之前曾在金融行业 IT 部门负责互联网券商架构的设计,对分布式,高并发,中间件等具有丰富经验。
文章来源:
https://dev.amazoncloud.cn/column/article/6309e39986218f3ca3e8f81f?sc_channel=CSDN
相关文章:

使用 Pulumi 打造自己的多云管理平台
前言在公有云技术与产品飞速发展的时代,业务对于其自身的可用性提出了越来越高的要求,当跨区域容灾已经无法满足业务需求的情况下,我们通常会考虑多云部署我们的业务平台,以规避更大规模的风险。但在多云平台部署的架构下…...

什么是MyBatis?无论是基础教学还是技术精进,你都应该看这篇MyBatis
文章目录学习之前,跟你们说点事情,有助于你能快速看完文章一、先应用再学习,代码示例1. 第一个MyBatis程序2. MyBatis整合Spring3. SpringBoot整合MyBatis二、MyBatis整体流程,各组件的作用域和生命周期三、说说MyBatis-config.xm…...

【编程基础之Python】10、Python中的运算符
【编程基础之Python】10、Python中的运算符Python中的运算符算术运算符赋值运算符比较运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级运算符总结Python中的运算符 Python是一门非常流行的编程语言,它支持各种运算符来执行各种操作。这篇文章将详细介绍…...

Android的基础介绍
一、Android介绍 Android是一种基于Linux的自由及开放源代码的操作系统,Android 分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。 Android 是Google开发的基于Linux平台的开源手机操作系统。它包括操作系统、用户界面和应用程序——…...

用户登录请求100w/每天, JVM如何调优
用户登录请求100w/每天, JVM如何调优 大概可以分为以下8个步骤。 Step1:新系统上线如何规划容量? 1.套路总结 任何新的业务系统在上线以前都需要去估算服务器配置和JVM的内存参数,这个容量与资源规划并不仅仅是系统架构师的随意估算的&am…...

C/C++每日一练(20230306)
目录 1. 判断素数的个数 ☆ 2. 分隔链表 ★★ 3. 数据流的中位数 ★★ 1. 判断素数的个数 在一个数组A中存放100个数据,用子函数判断该数组中哪些是素数,并统计该素数的个数,在主函数中输出该素数的个数。 代码: #includ…...

多线程的创建、Thread类、线程安全、同步、通信
目录 多线程的创建 方式一:继承Thread类 方式二:实现Runnable接口 方式三:JDK 5.0新增:实现Callable接口 Thread的常用方法 线程安全 线程安全问题是什么、发生的原因 线程安全问题案例模拟 线程同步 同步思想概述 方式…...

GraphPad Prism v9.5.1.733 科研绘图软件多语言
GraphPad Prism集生物统计、曲线拟合和科技绘图于一体,其所具有的功能均非常实用和精炼,包括了一些特色的功能,如ROC曲线分析、Bland-Altman分析等;曲线拟合功能是GraphPad Prism8 汉化版超越其他统计软体的制胜法宝,GraphPad Prism8 汉化版的线性/非线性拟合功能使用操作…...

基于intel soc+fpga智能驾驶舱和高级驾驶辅助系统软件设计(三)
虚拟化操作系统介绍 车载平台有逐渐融合的趋势,车载 SoC 的计算性能和应用快速增长,面临着多种应用在 多个显示子系统融合在一起的问题,这就要求平台运行多个操作系统。虚拟化(Virtualization) 技术飞速发展࿰…...

什么?年终奖多发1块钱竟要多缴9.6W的税
对于大多数的工薪阶级来说,目前现行的个人所得税适用于全年累计收入一次性税收优惠。 有可能有的人不理解一次性税收优惠是什么意思,所以这里我首先解释下什么是一次性税收优惠,然后在讲一下为什么明明公司多发了钱,到手反而会更…...
动态绑定右键菜单控件
一、动态绑定右键菜单控件 /// <summary> /// 通过递归获取执行控件 /// </summary> /// <typeparam name"T"></typeparam> /// <param name"c"></param> /// <pa…...

JavaScript基础三、数据类型
零、文章目录 文章地址 个人博客-CSDN地址:https://blog.csdn.net/liyou123456789个人博客-GiteePages:https://bluecusliyou.gitee.io/techlearn 代码仓库地址 Gitee:https://gitee.com/bluecusliyou/TechLearnGithub:https:…...

Python 随机漫步
目录 1. 创建 RandomWalk 类 2. 选择方向 3. 绘制随机漫步图 4. 总结 本篇博客将使用 Python 来 生成随机漫步数据,再使用 Matplotlib 库,将以引人注目的方式将这些数据呈现出来。 随机漫步 顾名思义就是随机走出的步伐,它是这样行…...

Spark SQL优化机制
Spark SQL优化机制Spark SQLCatalyst 优化器逻辑优化物理优化TungstenUnsafe RowWSCGRDD 缺点 : RDD的算子都是高阶函数 ,Spark Core 不知函数内的操作,只能闭包形式发给 Executors, 无法优化 DataFrame 不同点: 数据的表示形式…...

十五、Spring中的八大模式
1 简单工厂模式 BeanFactory的getBean()方法,通过唯一标识来获取Bean对象。是典型的简单工厂模式(静态工厂模式); 2 工厂方法模式 FactoryBean是典型的工厂方法模式。在配置文件中通过factory-method属性来指定工厂方法&#x…...

GrabCut算法、物体显著性检测
图割GraphCus算法。利用颜色、纹理等信息对GraphCut进行改进,形成效果更好的GrabCut算法。 对图像的目标物体和背景建立一个K维的全协方差高斯混合模型。 其中,单高斯模型的概率密度函数用公式表示为: 高斯混合模型可表示为n个单高斯模型的概…...

亚马逊、速卖通、lazada店铺一直不出单,没流量怎么办?
近几年,跨境电商入驻的卖家越来越多,平台的流量越来越分散,导致店铺没有流量没有订单的情况经常发生,因此卖家对店铺的优化尤为主要。 对于亚马逊卖家来说,几乎每天都会问虽然我把我的产品放在货架上,但没…...

深度剖析C语言符号篇
致前行的人: 人生像攀登一座山,而找寻出路,却是一种学习的过程,我们应当在这过程中,学习稳定冷静,学习如何从慌乱中找到生机。 目录 1.注释符号: 2.续接符和转义符: 3.回车与换行…...
【学习总结】ORBSLAM3使用自己相机数据
本文仅用于自己学习总结。本文档记录如何修改ORBSLAM3的接口,用自己的图片和数据。 单目视觉,无IMU,离线数据运行的配置过程 euroc_examples.sh 首先从euroc_examples.sh这个运行指令改。这个文件在最新版的代码中被删掉了,但通…...

C++单例模式实现
目录 1.提出的需求 2.如何定义一个类,使得这个类最多只能创建一个对象? 3.代码 4.小结 C/CLinux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂 1.提出的需求 在架构设计时&am…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...