7

Announcing Cross-Language Enum Support

 3 years ago
source link: https://www.pulumi.com/blog/announcing-enum-support/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Here at Pulumi, we believe in leveraging the best features of programming languages to create a delightful development experience for our users. Today, we continue our contributions in this area by announcing cross-language support for enum types in our provider SDKs, available in all Pulumi languages - Python, TypeScript, .NET and Go.

Enum types explained

An enum (short for enumerated) type is a data type consisting of a set of named values. In the Pulumi resource model, a property is an enum type when its value can only be set to a finite number of predetermined values.

For instance, consider a simple S3 bucket.

import * as pulumi from "@pulumi/pulumi";
import { s3 } from "@pulumi/aws";

const myBucket = new s3.Bucket("myBucket", { acl: "private" });
Click to copy

In the above code, the S3 Bucket resource has a property called acl, where we pass in the string private to indicate that this is a private bucket.

If we look at the resource docs, we can see that the acl property can only be set to one of a few different values: private, public-read, public-read-write, aws-exec-read, authenticated-read, and log-delivery-write. The acl property is the perfect candidate for an enum type and is emitted as one, so you can use the following code instead.

import * as pulumi from "@pulumi/pulumi";
import { s3 } from "@pulumi/aws";

const myBucket = new s3.Bucket("myBucket", { acl: s3.CannedAcl.Private });
Click to copy

IDE Superpowers

Enum properties provide discoverable and normalized constants that can be used in place of raw strings, allowing you to move faster with the added boosts of IDE tooling like type hints and autocomplete.

Using the provided constants, you can avoid referring back to the documentation to remember the valid values and save precious moments in the development cycle that would be lost to debugging errors caused by typos.

ENUM_TYPESCRIPT

Optimized for flexibility

While some properties make sense as “strict” enums (i.e., the input value must be one of the enumerated values), there are times when it would be beneficial to have constants for commonly used values without restricting the input to only those values. We call this second category “relaxed” enums, and we model them a little differently in our SDKs.

“Strict” enums

A property is a “strict” enum when the input value must be one of the enumerated values. In this case, the property type is specified as the enum type.

We will use “strict” enums when we are sure that the enum will include all legal values, such as when a provider is auto-generated from a cloud provider specification (like our Azure NextGen or Kubernetes providers).

export class StorageAccount extends pulumi.CustomResource {
    constructor(name: string, args: StorageAccountArgs, opts?: pulumi.CustomResourceOptions) {...}
}

export interface StorageAccountArgs {
    readonly accessTier?: pulumi.Input<enums.storage.latest.AccessTier>;
    ...
}
Click to copy

When using TypeScript, “strict” enums will accept both the constant (AccessTier.Cool) or the literal string ("Cool"). If there is an accidental spelling error in the literal, you are immediately alerted to the issue rather than having to wait until runtime.

ENUM_ERROR_TYPESCRIPT

“Relaxed” enums

When a property is a “relaxed” enum, the property type is specified as the Union of the enum type and the underlying primitive type. This means that you have the convenience of using the enum constants (i.e., s3.CannedAcl.Private), but you may also pass in the raw string (i.e., "private").

In the AWS provider (and other Terraform-based providers), we have opted for only using “relaxed” enums. The reasoning is twofold. Allowing the primitive type maintains backward compatibility and also allows users to use values that may not yet be represented in the Pulumi schema (e.g., a new Managed Policy ARN, EC2 Instance type, etc.).

export class Bucket extends pulumi.CustomResource {
    constructor(name: string, args?: BucketArgs, opts?: pulumi.CustomResourceOptions) {...}
}

export interface BucketArgs {
    readonly acl?: pulumi.Input<string | enums.s3.CannedAcl>;
    ...
}
Click to copy

Try them out!

You can find enum types integrated into v3.19.0 of the AWS provider and v0.3.0 of the Azure NextGen provider, and we will be adding enums to other providers in the coming weeks and months.

Azure NextGen: In the Azure NextGen provider, all properties labeled as enums in the OpenAPI spec are represented as such. In all, there are over 1300 enums provided in the SDKs. The Azure NextGen provider uses both “strict” and “relaxed” enums since the OpenAPI specification explicitly defines its properties as such.

AWS: The AWS provider enums are manually identified and maintained as part of the provider schema. We’ve already added many that you might find useful, such as Lambda Runtimes, EC2 Instance Types, and IAM Managed Policies, and will continue to add more in the coming months.

Take the new providers for a spin and let us know what you think in the Community Slack! If there are properties that you would like to see represented as enums, let us know. Or even better, submit a PR like this one to add them to the schema!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK