为什么我们建立路德维希-当今和未来云的DSL

The approach taken by Fugue is to allow cloud infrastructure to be treated as code. This concept is required if developers are to generate applications that can exploit the cloud’s capabilities and deliver on the promise of immutable infrastructure.

Fugue采取的方法是允许将云基础架构视为代码。 如果开发人员要生成可以利用云功能并实现不变基础架构的应用程序,则需要使用此概念。

Fugue provides simplification of your life on the cloud through abstractions. Abstractions can be expressed in one of two ways: as black boxes, or as language. Fugue puts as much into language as we can, so that you can do things with it that we didn’t predict.

Fugue通过抽象来简化您在云上的生活。 抽象可以两种方式之一表示:黑盒子或语言。 Fugue尽可能地投入语言,以便您可以使用我们无法预料的语言来做事。

Black boxes are easier for a platform builder to make, because they do things in one particular way. They are also less flexible for the user, because they do things in one particular way, which may not be the way the user needs or prefers.

黑匣子对于平台构建者来说更容易制造,因为它们以一种特定的方式进行工作。 它们对于用户来说也不太灵活,因为它们以一种特定的方式来做事,而这可能不是用户所需要或喜欢的方式。

As users, we prefer flexibility and access, so we prefer languages to black boxes. We made Fugue to be something we would enjoy using, so we decided to express a lot of the system as a language. Since we knew we wanted to go down the language path, we first looked to see if there was something out there that would be a good choice, based on our criteria. These are:

作为用户,我们更喜欢灵活性和访问性,因此我们更喜欢语言而不是黑匣子。 我们使Fugue成为我们喜欢使用的东西,因此我们决定将很多系统表达为一种语言。 既然我们知道我们想走语言的道路,那么我们首先要根据我们的标准来看看是否有一些不错的选择。 这些是:

  1. Doing typical things on the cloud should be easy, and not feel like programming.
  2. Users should get great error messages, fast.
  3. If the program compiles, it should almost always work when operating against the cloud.
  4. Doing sophisticated things should be possible, in a safe and predictable way.
  5. Doing sophisticated things once should turn them into shareable, easy things.
  1. 在云上做典型的事情应该很容易,并且不会像编程。
  2. 用户应该很快收到错误消息。
  3. 如果程序可以编译,则在针对云进行操作时,它几乎应该始终可以运行。
  4. 以安全且可预测的方式进行复杂的工作应该是可能的。
  5. 一次做复杂的事情应该将它们变成可共享的简单事情。

We didn’t find anything that would meet these criteria, so we created a minimalist domain-specific language called Ludwig. Ludwig is a declarative language that also has functions for abstraction.

我们找不到满足这些条件的任何东西,因此我们创建了一种称为Ludwig的极简主义特定领域语言。 路德维希(Ludwig)是一种声明性语言,也具有抽象功能。

在云上做典型的事情应该很容易,并且不会像编程。 (Doing typical things on the cloud should be easy, and not feel like programming.)

Most uses for Fugue can be expressed in Ludwig by declaring simple records. If you’re familiar with YAML or JSON, Ludwig records should look really familiar:

可以通过声明简单的记录在路德维希语中表达赋格曲的大多数用法。 如果您熟悉YAML或JSON,那么Ludwig记录应该看起来非常熟悉:

ConfigConfig :
  :
  region: region: AWS.AWS . Region
  Region
  ami: ami: String

String

Config Config jsonish: {
  jsonish: {
  region: region: AWS.AWS . Us-east-Us -east- 1,
  1 ,
  ami: ami: "ami-6869aa05",
}"ami-6869aa05" ,
}

For most users, this is all you really need to know about Ludwig, because we provide a rich standard library that covers a lot of ground for building and operating cloud services. Need a VPC network, a compute instance, or a Lambda function? They look like this:

对于大多数用户来说,这是您真正需要了解的Ludwig的全部信息,因为我们提供了一个丰富的标准库,该库涵盖了构建和运行云服务的大量基础。 是否需要VPC网络,计算实例或Lambda函数? 他们看起来像这样:

VPC (VPC)

EC2 (EC2)

instance: instance: EC2.EC2 . Instance.new {
  Instance .new {
  keyName: keyName: "example-key",
  "example-key" ,
  instanceType: instanceType: EC2.EC2 . M4_large,
  M4_large ,
  subnet: public-subnet: public- 10-10 - 0-0 - 1-1 - 0,
  0 ,
  tags: [example-tag],
  tags: [example-tag],
  securityGroups: [example-sg],
  securityGroups: [example-sg],
  iamInstanceProfile: example-profile,
  iamInstanceProfile: example-profile,
  image: image: "ami-d0f506b0"
}"ami-d0f506b0"
}

Lambda函数 (Lambda Function)

用户应该很快收到错误消息。 (Users should get great error messages, fast.)

So far, you might be thinking that Ludwig is just another YAML or JSON template format, but it’s actually much more, even when declaring simple records based on the standard library. Behind these records are well-defined types and functions that contain a lot of knowledge about cloud services, and return useful errors as you work. Often, when someone learns Ludwig, they start by reading a few documents, but quickly realize that the error messages are so rich that they form a sort of interactive documentation, and instead of poring over specs, they experiment.

到目前为止,您可能会认为Ludwig只是另一种YAML或JSON模板格式,但实际上甚至更多,即使在基于标准库声明简单记录时也是如此。 这些记录的后面是定义明确的类型和函数,其中包含许多有关云服务的知识,并在您工作时返回有用的错误。 通常,当有人学习路德维希时,他们会先阅读一些文档,但很快就意识到错误消息是如此丰富,以至于它们形成了一种交互式文档,而不是研究规格,而是进行试验。

For example, let’s take a look at the VPC example that we just provided and how this might work in practice. We will intentionally make some errors to show how intuitive and easy it is to get things right with Ludwig.

例如,让我们看一下我们刚刚提供的VPC示例以及它在实践中如何工作。 我们将故意犯一些错误,以显示使用Ludwig进行正确处理是多么直观和容易。

network: network: Network.new {
  Network .new {
  name: name: "demo-app-network",
  "demo-app-network" ,
  region: region: AWS.AWS . Us-west-Us -west- 3,
  3 ,
  cidr: cidr: "10.0.0.0/8",
  "10.0.0.0/8" ,
  publicSubnets: [ (publicSubnets: [ ( AWS.AWS . A, A , "10.0.1.0/24"),
                   ("10.0.1.0/24" ),
                   ( AWS.AWS . B, B , "10.0.2.0/24"), ],
  "10.0.2.0/24" ), ],
  privateSubnets: [],
}privateSubnets: [],
}

If you know AWS, you probably know that there is no region called Us-west-3, but someone new to the cloud might not, or might fat finger the region name. If we try to run this composition, the Ludwig compiler (/opt/fugue/bin/lwc) will return the following error:

如果您了解AWS,那么您可能知道不存在名为Us-west-3 ,但是新加入云的人可能不会,或者可能会误以为该区域名称。 如果我们尝试运行此组合,则Ludwig编译器( /opt/fugue/bin/lwc )将返回以下错误:

First, you get the actual line and column for where the error occurred – this becomes particularly important when you have modules that are imported with a stack trace. No more searching through thousands of lines of code to find what generated an unhelpful AWS error. Second, you get some hints as to what the correct answer might be. This isn’t black box code, but lwc being smart enough to look at the type definition for regions and matching things that look close. Here’s the Region type:

首先,获得发生错误的实际行和列–当您使用堆栈跟踪导入模块时,这一点尤为重要。 无需再搜索成千上万的代码来查找导致无用的AWS错误的原因。 其次,您会得到一些关于正确答案的提示。 这不是黑盒代码,但是lwc足够聪明,可以查看区域的类型定义并匹配看起来很近的东西。 这是Region类型:

| Ap-northeast-1
  | Ap-northeast-1
  | Ap-northeast-2
  | Ap-northeast-2
  | Ap-southeast-1
  | Ap-southeast-1
  | Ap-southeast-2
  | Ap-southeast-2
  | Eu-central-1 
  | Eu-central-1 
  | Eu-west-1
  | Eu-west-1
  | Sa-east-1
  | Sa-east-1
  | Us-east-1
  | Us-east-1
  | Us-west-1
  | Us-west-1
  | Us-west-2
  | Us-west-2
  | Ap-south-1| Ap-south-1

This is a sum type, meaning that a Region can be constructed of any of the following items preceded by the pipe (|). Regions are just one of many domains of information encoded in the types that ship with Fugue. Those type definitions are right on disk in /opt/fugue/lib as well, so you can take a look yourself. Let’s keep working on getting this VPC correct, though. Now we’ve changed the region to Us-west-2, so that will be fine, but we’ve made an error in the CIDR block:

这是一个求和类型,这意味着可以用管道号( | )后面的以下任意项构造一个Region 。 区域只是Fugue附带的类型中编码的许多信息域之一。 这些类型定义也位于/opt/fugue/lib磁盘上,因此您可以自己看看。 但是,让我们继续努力以使此VPC正确无误。 现在,我们将区域更改为Us-west-2 ,这样就可以了,但是在CIDR块中出现了错误:

ludwig (runtime error):
  "/opt/fugue/lib/Fugue/AWS/EC2/Vpc.lw" (line 132, column 29):
  error:

    132| Bool isValid(VpcSpec spec): isValidCidr(spec.cidrBlock)
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

  Vpc cidrBlock size must be between a /28 and /16 netmask.

  Stack trace:
    In call to isValid at "/opt/fugue/lib/Fugue/AWS/EC2/Vpc.lw" (line 40, column 6)
    In call to new at "/opt/fugue/lib/Fugue/AWS/Pattern/Network.lw" (line 67, column 12)
    In call to new at "FugueDemo.lw" (line 19, column 19)
ludwig (runtime error):
  "/opt/fugue/lib/Fugue/AWS/EC2/Vpc.lw" (line 132, column 29):
  error:

    132| Bool isValid(VpcSpec spec): isValidCidr(spec.cidrBlock)
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

  Vpc cidrBlock size must be between a /28 and /16 netmask.

  Stack trace:
    In call to isValid at "/opt/fugue/lib/Fugue/AWS/EC2/Vpc.lw" (line 40 , column 6 )
    In call to new at "/opt/fugue/lib/Fugue/AWS/Pattern/Network.lw" (line 67 , column 12 )
    In call to new at "FugueDemo.lw" (line 19 , column 19 )

Note that the error information has AWS specific knowledge which is also written into the library. In this case, we need a /28 to a /16. This error has a full stack trace at the bottom because the record we defined above is passed into the Network.new function in the standard library.

请注意,错误信息具有AWS特定知识,该知识也已写入库中。 在这种情况下,我们需要/28/16 。 由于我们在上面定义的记录已传递到标准库的Network.new函数中,因此该错误在底部具有完整的堆栈跟踪。

如果程序可以编译,则在针对云进行操作时,它几乎应该始终可以运行。 (If the program compiles, it should almost always work when operating against the cloud.)

This feedback loop ends when the user gets a successful compile of the Ludwig program, and because the standard library is pretty good at knowing what works and what doesn’t on the cloud, this generally means the composition will run successfully. While it is still possible to have runtime errors when a composition is run against actual cloud APIs — for example, trying to create an object that is a duplicate on a service where this isn’t allowed, such as S3 — the vast majority of actual user mistakes can be caught during compilation.

当用户成功编译Ludwig程序时,该反馈循环结束,并且由于标准库非常善于了解云中哪些有效,哪些无效,因此通常意味着该组合将成功运行。 当针对实际的云API运行合成时,仍然可能会出现运行时错误,例如,尝试在不允许这样做的服务(例如S3)上创建与之重复的对象,但实际中绝大多数在编译过程中可能会发现用户错误。

Prior to actually building, modifying, or terminating cloud infrastructure, you’ll probably want to know what will actually happen in the environment. So, after compilation, the next recommended step is a dry run. The dry-run feature produces a JSON output of what is going to happen in AWS if you were to execute fugue run, fugue kill, fugue resume, or fugue update. The workflow of using Fugue with Ludwig is therefore fast, interactive, and low-risk.

在实际构建,修改或终止云基础架构之前,您可能需要了解环境中实际发生的情况。 因此,编译后,下一个建议步骤是空运行。 如果您要执行fugue runfugue killfugue resumefugue update ,则空运行功能会生成AWS中将发生的情况的JSON输出。 因此,将Fugue与Ludwig一起使用的工作流程是快速,交互式且低风险的。

We cannot fully solve for runtime environment issues and some kinds of API errors in Ludwig, so these are the domain of the Fugue Conductor, which has commands like status and history that can return detailed information on what is happening, what went right, and what went wrong.

我们无法完全解决运行时环境问题和路德维希(Ludwig)中的某些API错误,因此这些是赋格指挥(Fugue Conductor)的领域,它具有statushistory等命令,可以返回有关正在发生的事情,发生的事情以及发生的事情的详细信息。出错。

以安全且可预测的方式进行复杂的工作应该是可能的。 (Doing sophisticated things should be possible, in a safe and predictable way.)

Declaring records is fine and good, but you may eventually want to create some of your own abstractions, and this is where you can use functions in Ludwig. Like any language, learning how to write functions in Ludwig has a learning curve, but it’s not too bad. You can read our docs on Ludwig to learn how to write these, so we won’t focus on a tutorial in this blog post. We will point out a couple interesting use cases for functions.

声明记录既好又好,但是您最终可能想要创建一些自己的抽象,这就是您可以在Ludwig中使用函数的地方。 与任何语言一样,学习如何在路德维希中编写函数也具有学习曲线,但这并不算太糟。 您可以阅读路德维希(Ludwig)上的文档以学习如何编写这些文档,因此我们不会在此博客文章中重点介绍教程。 我们将为函数指出几个有趣的用例。

Combining a collection of cloud services into a higher order abstraction is the most typical use case for functions. For example, your company might have a standard way to build a Kubernetes laboratory. With Fugue, you can write a Kubernetes cluster constructor that takes in a few parameters in the familiar record form shown above. The constructor can take a few arguments that are key decisions for deploying the cluster:

将一组云服务组合成更高阶的抽象是功能的最典型用例。 例如,您的公司可能具有建立Kubernetes实验室的标准方法。 使用Fugue,您可以编写Kubernetes集群构造器,该构造器以上面显示的熟悉的记录形式输入一些参数。 构造函数可以接受一些参数,这些参数是部署集群的关键决策:

This code makes a simple laboratory like this:

这段代码使一个简单的实验室像这样:

kubernetes_lab_rt.png

Then, making a new cluster is as easy as a few lines of code.

然后,创建新集群就像几行代码一样容易。

KubernetesCluster as KubernetesCluster as KubeCluster
import KubeCluster
import Fugue.Fugue . AWS as AWS as AWS


my-AWS


my- kube: kube: KubeCluster.new {
             KubeCluster .new {
             name: name: "my-kube-net",
             "my-kube-net" ,
             region: region: AWS.AWS . Us-west-Us -west- 2,
             2 ,
             subnetAZ: subnetAZ: AWS.AWS . A,
             A ,
             keyName: keyName: "kubernetes_the_hard_way"
         }"kubernetes_the_hard_way"
         }

Another use case is to enforce company policy on how infrastructure is used. For example, you might have an application that needs to conform to HIPAA regulations because it contains patient healthcare data. HIPAA on AWS is possible, but it can be a laborious and manual process to get it right, generally implemented with monitoring and reporting solutions. Fugue allows HIPAA rules to be abstracted, with all the other Ludwig features such as useful error messages. This allows you to move really fast when developing on cloud, while maintaining policy and compliance of the cloud services.

另一个用例是强制执行有关如何使用基础结构的公司策略。 例如,您可能有一个需要遵循HIPAA法规的应用程序,因为它包含患者医疗数据。 可以在AWS上使用HIPAA,但要使其正确进行可能是费力且手动的过程,通常会通过监视和报告解决方案来实施。 Fugue允许抽象化HIPAA规则以及所有其他Ludwig功能,例如有用的错误消息。 这使您在云上进行开发时可以真正快速地移动,同时保持云服务的策略和合规性。

For instance, HIPAA rules require that instances be dedicated. With Ludwig, we can build validations which confirm this is the case. For example, consider this EC2 instance, which is meant to be HIPAA-compliant:

例如,HIPAA规则要求实例必须专用。 使用路德维希,我们可以构建验证来确认这种情况。 例如,请考虑此EC2实例,该实例旨在符合HIPAA:

By virtue of importing the Fugue.HIPAA.AWS library, Ludwig will check that the instance is HIPAA-compliant. In this case, it actually is not, because the t2.nano instance type doesn’t support dedicated tenancy.

通过导入Fugue.HIPAA.AWS库,Ludwig将检查实例是否符合HIPAA。 在这种情况下,实际上不是,因为t2.nano实例类型不支持专用租期。

ludwig (runtime error):
  "hipaa-instance.lw" (line 5, column 17):
  error:

    25|   instanceType: EC2.T2_nano,
                        ^^^^^^^^^^^

HIPAA: The instance type t2.nano does not support dedicated instances, which are required by AWS HIPAA guidelines
ludwig ( runtime error ):
  "hipaa-instance.lw" (line 5 , column 17 ):
  error:

    25 |   instanceType: EC2.T2_ nano ,
                        ^^^^^^^^^^^

HIPAA: T he instance type t2 . nano does not support dedicated instances , which are required by AWS HIPAA guidelines

一次做复杂的事情应该将它们变成可共享的简单事情。 (Doing sophisticated things once should turn them into shareable, easy things.)

Once you’ve written your abstractions, they can be shared across your organization just like any other code. Most organizations that use cloud have a DevOps team that is expert on cloud, and lots of development teams that aren’t. Functions allow the DevOps team to vend simple code to the dev teams for environments that they can use that span all the AWS services Fugue covers, automatically. Through data externalization and the Fugue process model, you get real infrastructure as code. Statically-typed, safe code with great error messages.

编写抽象后,就可以像在其他组织中的代码一样在组织中共享这些抽象。 大多数使用云的组织都有一个DevOps团队,该团队是云专家,而许多开发团队却不是。 通过功能,DevOps团队可以为开发团队自动提供简单的代码,以便他们可以使用的环境涵盖所有Fugue涵盖的所有AWS服务。 通过数据外部化和赋格过程模型,您将获得真正的基础结构作为代码。 静态类型的安全代码,带有大量错误消息。

We continue to expand Fugue and Ludwig to make it easier to use and more powerful, and in the near future we’ll be making some announcements on even more powerful validation and safety features, as well as lots of additional service coverage.

我们将继续扩展Fugue和Ludwig,以使其更易于使用和更强大,并且在不久的将来,我们将发布有关更强大的验证和安全功能的公告,以及许多其他服务范围。

翻译自: https://www.pybloggers.com/2016/10/why-we-built-ludwig-a-dsl-for-the-cloud-of-today-and-the-future/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值