KubeVela: 如何用 100 行代码快速引入 AWS 最受欢迎的 50 种云资源

本文涉及的产品
应用实时监控服务-用户体验监控,每月100OCU免费额度
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
可观测监控 Prometheus 版,每月50GB免费额度
简介: 本文提供了一个方案,用不到 100 行代码快速引入 AWS 前 50 最受欢迎的云资源。

作者:KubeVela 社区


KubeVela 目前已经支持了 AWS、Azure、GCP、阿里云、腾讯云、百度云、UCloud 等云厂商,也提供了简单快捷的命令行工具[1]引入云服务商的云资源,但是在 KubeVela 里一个一个地支持云服务商的云资源不利于快速满足用户对于云资源的需求,本文提供了一个方案,用不到 100 行代码快速引入 AWS 前 50 最受欢迎的云资源。

同时,我们也期望用户受到本文的启发,贡献其他云服务商的云资源。


AWS 最受欢迎的云资源在哪里?


Terraform 官网提供了各个云服务商的 Terraform modules,比如 AWS 的云资源 Terraform modules[2]。其中,云资源按照受欢迎的使用程度(下载量)排序,比如 AWS VPC 下载量为 1870 万次。


通过简单分析,我们发现 AWS 前 50 Terraform modules 的数据可以通过请求 https://registry.terraform.io/v2/modules?filter%5Bprovider%5D=aws&include=latest-version&page%5Bsize%5D=50&page%5Bnumber%5D=1 获取。


开始之前


代码接受两个用户传入参数:

  • provider 的名称
  • 该 provider 对应的 Terraform Modules 的 URL


对于 AWS 来说,Provider名称为 “aws”,对应的 Terraform modules 为 Terraform Modules json 格式接口[3](即在 Terraform Registry[4]中搜索 provider 为 aws 时最受欢迎的 50 种云资源)。

在执行代码之前需要确认 providerName(aws) 和 Modules 链接无误。


执行代码


那么你就可以通过以下 100 行左右的代码(文件名 gen.go)来批量地快速引入 AWS 最受欢迎的前 50 种云资源。


import (
  "encoding/json"
  "fmt"
  "io"
  "log"
  "net/http"
  "os"
  "os/exec"
  "path/filepath"
  "strings"
  "github.com/pkg/errors"
)
type TFDownload struct {
  Data     []DataItem     `json:"data"`
  Included []IncludedItem `json:"included"`
}
type IncludedItem struct {
  Id         string     `json:"id"`
  Attributes Attributes `json:"attributes"`
}
type DataItem struct {
  Attributes    Attributes    `json:"attributes"`
  Relationships Relationships `json:"relationships"`
}
type Relationships struct {
  LatestVersion RelationshipLatestVersion `json:"latest-version"`
}
type RelationshipLatestVersion struct {
  Data RelationshipData `json:"data"`
}
type RelationshipData struct {
  Id string `json:"id"`
}
var errNoVariables = errors.New("failed to find main.tf or variables.tf in Terraform configurations")
type Attributes struct {
  Name        string `json:"name"`
  Downloads   int    `json:"downloads"`
  Source      string `json:"source"`
  Description string `json:"description"`
  Verified    bool   `json:"verified"`
}
func main() {
  if len(os.Args) < 2 {
     fmt.Println("Please provide the cloud provider name and an official Terraform modules URL")
     os.Exit(1)
  }
  providerName := os.Args[1]
  terraformModulesUrl := os.Args[2]
  resp, err := http.Get(terraformModulesUrl)
  if err != nil {
     log.Fatal(err)
  }
  defer resp.Body.Close()
  body, err := io.ReadAll(resp.Body)
  if err != nil {
     log.Fatal(err)
  }
  var modules TFDownload
  if err := json.Unmarshal(body, &modules); err != nil {
     fmt.Println(err.Error())
     os.Exit(1)
  }
  if _, err = os.Stat(providerName); err == nil {
     if err := os.RemoveAll(providerName); err != nil {
        log.Fatal(err)
     }
     fmt.Printf("Successfully deleted existed directory %s\n", providerName)
  }
  if _, err = os.Stat(providerName); os.IsNotExist(err) {
     if err := os.Mkdir(providerName, 0755); err != nil {
        if !os.IsExist(err) {
           log.Fatal(err)
        }
        fmt.Printf("Successfully created directory %s\n", providerName)
     }
  }
  for _, module := range modules.Data {
     var description string
     for _, attr := range modules.Included {
        if module.Relationships.LatestVersion.Data.Id == attr.Id {
           description = attr.Attributes.Description
        }
     }
     if description == "" {
        description = strings.ToUpper(providerName) + " " + strings.Title(module.Attributes.Name)
     }
     outputFile := fmt.Sprintf("%s/terraform-%s-%s.yaml", providerName, providerName, module.Attributes.Name)
     if _, err := os.Stat(outputFile); !os.IsNotExist(err) {
        continue
     }
     if providerName == "aws" && (module.Attributes.Name == "rds" || module.Attributes.Name == "s3-bucket" ||
        module.Attributes.Name == "subnet" || module.Attributes.Name == "vpc") {
        continue
     }
     if err := generateDefinition(providerName, module.Attributes.Name, module.Attributes.Source, "", description); err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
     }
  }
}
func generateDefinition(provider, name, gitURL, path, description string) error {
  defYaml := filepath.Join(provider, fmt.Sprintf("terraform-%s-%s.yaml", provider, name))
  cmd := fmt.Sprintf("vela def init %s --type component --provider %s --git %s.git --desc \"%s\" -o %s",
     name, provider, gitURL, description, defYaml)
  if path != "" {
     cmd = fmt.Sprintf("%s --path %s", cmd, path)
  }
  fmt.Println(cmd)
  stdout, err := exec.Command("bash", "-c", cmd).CombinedOutput()
  if err != nil {
     return errors.Wrap(err, string(stdout))
  }
  fmt.Println(string(stdout))
  return nil


执行命令:


go run gen.go aws "https://registry.terraform.io/v2/modules?filter%5Bprovider%5D=aws&include=latest-version&page%5Bsize%5D=50&page%5Bnumber%5D=1"



代码简要说明

解析云资源数据


访问用户传入的 URL,将返回的 json 数据解析为 Go 中的结构体。

资源对应的 json 格式如下:


{
  "data": [
    {
      "type": "modules",
      "id": "23",
      "attributes": {
        "downloads": 18440513,
        "full-name": "terraform-aws-modules/vpc/aws",
        "name": "vpc",
        "namespace": "terraform-aws-modules",
        "owner-name": "",
        "provider-logo-url": "/images/providers/aws.png",
        "provider-name": "aws",
        "source": "https://github.com/terraform-aws-modules/terraform-aws-vpc",
        "verified": true
      },
      "relationships": {
        "latest-version": {
          "data": {
            "id": "142143",
            "type": "module-versions"
          }
        }
      },
      "links": {
        "self": "/v2/modules/23"
      }
    },
    ...
  ],
  "included": [
    {
      "type": "module-versions",
      "id": "36806",
      "attributes": {
        "created-at": "2020-01-03T11:35:36Z",
        "description": "Terraform module Terraform module for creating AWS IAM Roles with heredocs",
        "downloads": 260030,
        "published-at": "2020-02-06T06:26:08Z",
        "source": "",
        "tag": "v2.0.0",
        "updated-at": "2022-02-22T00:45:44Z",
        "version": "2.0.0"
      },
      "links": {
        "self": "/v2/module-versions/36806"
      }
    },
    ...
  ],
  ...
}


在 Modules 对应的 json 数据中,我们只关心两个键值对,即:


  • data:包含 Modules 名称及属性的列表
  • Included:筛选出的特定版本的 Modules 具体信息


其中,对于 data 中的每个 Module 元素,解析它的属性,Id 和 relationship 中的 latest-version 对应的 id;对于 Included 中的每个 Module 版本元素,解析它的属性和Id。


属性又解析如下五项:

  • Name
  • Downloads
  • Source
  • Description
  • Verified


结构体定义在结构体 TFDownload 中,通过 http 库获取 json 数据,再通过 json.Unmarshal 解析出 Terraform modules 的结构体。


批量生产云资源


  1. 新建目录,生成资源所需文件


解析完毕后,在当前目录下新建文件夹,文件夹命名为 provider 名称。

遍历解析后的 data,对于其中每个 Module 元素,执行下述操作,为其生成相应配置文件,定义和相应文档。


  1. 生成定义文件


通过下述 vela 指令从模块对应的 github 仓库读取相应信息生成定义文件。


vela def init {ModuleName} --type component --provider {providerName} --git {gitURL} --desc {description} -o {yamlFileName}


指令中需要填入的几项由解析好的 Module 结构体传入。


  • gitURL: {Module.Attributes.Source}.git
  • description: 如果 Included 中存在元素 ID 与模块 relationship 中 latest-version 对应 ID 相同,则 description 为 Included 中对应元素属性的 description;否则 description 为 providerName 与模块名称的拼接
  • yamlFileName:terraform-{providerName}-{Module.Attributes.Name}.yaml


你也来试试?


还有不少云服务商也提供了丰富的 Terraform modules,比如


GCP:

https://registry.terraform.io/namespaces/terraform-google-modules


阿里云:

https://registry.terraform.io/namespaces/terraform-alicloud-modules


你要不要也为 KubeVela 引入你正在使用的、或喜欢的云服务商的云资源?


相关链接


[1] 简单快捷的命令行工具

https://kubevela.io/docs/next/platform-engineers/components/component-terraform


[2] AWS 的云资源 Terraform modules

https://registry.terraform.io/namespaces/terraform-aws-modules


[3] Terraform Modules json 格式接口

https://registry.terraform.io/v2/modules?filter%5Bprovider%5D=aws&include=latest-version&page%5Bsize%5D=50&page%5Bnumber%5D=1


[4] Terraform Registry

https://aregistry.terraform.io/

相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云专有网络VPC使用教程
专有网络VPC可以帮助您基于阿里云构建出一个隔离的网络环境,并可以自定义IP 地址范围、网段、路由表和网关等;此外,也可以通过专线/VPN/GRE等连接方式实现云上VPC与传统IDC的互联,构建混合云业务。 产品详情:https://www.aliyun.com/product/vpc
相关文章
|
2月前
|
开发框架 前端开发 定位技术
Flutter框架中的插件市场及开源资源的利用方法。内容涵盖插件市场的扩展功能、时间节省与质量保证
本文深入探讨了Flutter框架中的插件市场及开源资源的利用方法。内容涵盖插件市场的扩展功能、时间节省与质量保证,常见插件市场的介绍,选择合适插件的策略,以及开源资源的利用价值与注意事项。通过案例分析和对社区影响的讨论,展示了这些资源如何促进开发效率和技术进步,并展望了未来的发展趋势。
46 11
|
5月前
|
监控 Linux 数据库连接
手把手教你从本地到云端:全面解析Blazor应用的部署流程与最佳实践,助你轻松掌握发布Blazor WebAssembly应用到Azure的每一个细节
【8月更文挑战第31天】本文详细介绍了将 Blazor 应用从本地部署到 Azure 的全过程。首先确保已在 Visual Studio 中创建 Blazor WebAssembly 应用,接着清理项目并配置发布选项。然后在 Azure 中创建 App Service 并完成应用部署。最后,配置环境变量、SSL 和监控,确保应用稳定运行。附带示例代码,展示如何加载和使用 Azure 环境变量。通过最佳实践指导,帮助你顺利完成 Blazor 应用的云端部署。
131 0
|
5月前
|
Kubernetes Cloud Native 搜索推荐
探索云原生技术:Kubernetes入门与实践打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第31天】云原生技术正改变着应用开发和部署的方式。本文将带你了解云原生的基石——Kubernetes,通过实际的代码示例,从安装到部署一个简单的应用,让你迅速掌握Kubernetes的核心概念和操作方法。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你进入云原生世界的桥梁。
|
5月前
|
Kubernetes Cloud Native Go
云原生之旅:构建和部署一个简单的Go应用程序
【8月更文挑战第31天】在本文中,我们将探索如何利用云原生技术构建和部署一个Go语言编写的简单Web应用。通过实际操作示例,我们不仅能够了解云原生的基本概念,还能学习到如何在Kubernetes集群上运行和管理容器化应用。文章将引导读者从零开始,逐步搭建起自己的云原生环境,并实现代码的容器化与自动化部署,最终达到持续交付的目的。
|
8月前
|
Kubernetes 监控 安全
「译文」在 K8S/OpenShift 上开发应用程序的 14 种最佳实践
「译文」在 K8S/OpenShift 上开发应用程序的 14 种最佳实践
|
Kubernetes Cloud Native Dubbo
Higress 开源后,我们整理了开发者最关心的 15 个问题
云原生网关 Higress 开源后,引起了开发者们的热烈讨论,我们整理了大家在 GitHub、钉群、微信群讨论的问题,并将回答汇总如下,方便各位更准确的读懂 Higress,也非常欢迎您和我们一起共建、定义 Higress。
355 12
Higress 开源后,我们整理了开发者最关心的 15 个问题
|
SQL JSON Kubernetes
KubeVela 项目和能力简介 | 学习笔记
快速学习 KubeVela 项目和能力简介
KubeVela 项目和能力简介 | 学习笔记
|
Kubernetes Cloud Native 安全
Higress 开源后,我们整理了开发者最关心的15个问题
云原生架构下,网关承载着流量管理、服务调用、安全管理等多重职能,在稳定性、性能、安全性、易用性上存在着更高的要求。在 CNCF Landscpae 编排和管理的 API Gateway 领域中,已经有不少开源的网关选择,开发者们也有着不小的选型诉求。
Higress 开源后,我们整理了开发者最关心的15个问题
|
运维 Cloud Native API
KubeVela 插件指南:轻松扩展你的平台专属能力
本文作者为 KubeVela 社区贡献者 姜洪烨。 我在原文基础上做了适量修改。KubeVela 插件(addon)可以方便地扩展 KubeVela 的能力。正如我们所知,KubeVela 是一个微内核高度可扩展的平台,用户可以通过 模块定义(Definition)扩展 KubeVela 的系统能力,而 KubeVela 插件正是方便将这些自定义扩展及其依赖打包并分发的核心功能。不仅如此,Kube
KubeVela 插件指南:轻松扩展你的平台专属能力
|
消息中间件 Kubernetes Cloud Native
sealer 成为 CNCF Sandbox 项目,旨在构建分布式应用交付新标准
sealer 的核心理念是像 Docker 一样构建整个集群以及分布式应用,在整个集群纬度保障一致性,实现整个集群里所有分布式软件的 Build、 Share、 Run!
sealer 成为 CNCF Sandbox 项目,旨在构建分布式应用交付新标准