1. Docs
  2. Pulumi IaC
  3. Concepts
  4. Resources
  5. Provider functions

Provider functions

    A provider may make functions available in its SDK as well as resource types. These “provider functions” are often for calling a platform API to get a value that is not part of a resource. For example, the AWS provider includes the function aws.apigateway.getDomainName:

    using Pulumi;
    using Aws = Pulumi.Aws;
    
    class MyStack : Stack
    {
        public MyStack()
        {
            var example = Output.Create(Aws.ApiGateway.GetDomainName.InvokeAsync(new Aws.ApiGateway.GetDomainNameArgs
            {
                DomainName = "api.example.com",
            }));
        }
    }
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/apigateway"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    		_, err := apigateway.LookupDomainName(ctx, &apigateway.LookupDomainNameArgs{
    			DomainName: "api.example.com",
    		}, nil)
    		if err != nil {
    			return err
    		}
    		return nil
    	})
    }
    
    package generated_program;
    
    import java.util.*;
    import java.io.*;
    import java.nio.*;
    import com.pulumi.*;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(App::stack);
        }
    
        public static void stack(Context ctx) {
            final var example = Output.of(ApigatewayFunctions.getDomainName(GetDomainNameArgs.builder()
                .domainName("api.example.com")
                .build()));
        }
    }
    
    import pulumi
    import pulumi_aws as aws
    
    example = aws.apigateway.get_domain_name(domain_name="api.example.com")
    
    import * as pulumi from "@pulumi/pulumi";
    import * as aws from "@pulumi/aws";
    
    const example = pulumi.output(aws.apigateway.getDomainName({
        domainName: "api.example.com",
    }));
    
    variables:
      example:
        fn::aws:apigateway:getDomainName:
          domainName: api.example.com
    

    Provider functions are exposed in each language as regular functions, in two variations:

    1. The direct form accepts plain arguments (e.g. string, as opposed to pulumi.Input<string>) and returns an asynchronous value (e.g. a Promise in NodeJS, or a Task in Python), or blocks until the result is available. These functions are typically named, e.g., getFoo().
    2. The output form accepts Input values (or plain values) and returns an Output. These functions are typically named, e.g., getFooOutput().

    The Pulumi Registry contains authoritative documentation for all provider functions.

    Invoke options

    Functions also accept “invoke options”, similar to the way Pulumi resources accept resource options. Invoke options may be specified either as an object or as a list of arguments depending on the language you’re writing your Pulumi program in. The options are as follows:

    • parent: Supply a parent resource for this function call. Much like the parent resource option, the parent will be consulted when determining the provider to use.

    • pluginDownloadURL: Pass a URL from which the provider plugin should be fetched. This may be necessary for third-party packages such as those not hosted at https://get.pulumi.com.

    • provider: Pass an explicitly configured provider to use for this function call, instead of using the default provider. This is useful, for example, if you want to invoke a function in each of a set of AWS regions.

    • version: Pass a provider plugin version that should be used when invoking the function.

    • async: This option is deprecated and will be removed in a future release.

    Dependencies and ordering

    While the direct and output forms of a provider function are equivalent in terms of the results they produce when invoked, they differ in how they interact with the rest of the Pulumi program and the order in which they may be executed. Specifically:

    • Direct form invocations execute just like any other function call in the language. Since they do not accept Pulumi Inputs nor return Pulumi Outputs, they are not tracked by the Pulumi engine and do not participate in the dependency graph.

    • Output form invocations, on the other hand, are tracked by the Pulumi engine and participate in the dependency graph. This means, for example, that Pulumi will ensure that input resources are created or updated before an invocation and that the invocation is executed before its dependent resources are created or updated.

    If you require that dependent resources are created or updated before an invocation, you must use a provider function’s output form. If you need to specify a dependency that can’t be captured by passing an appropriate input (that is, if you wish to simulate something like the dependsOn resource option), you can use Pulumi’s all function and Output’s apply method:

    import * as pulumi from "@pulumi/pulumi";
    
    const res1 = new MyResource("res1", {});
    const res2 = new MyResource("res2", {});
    
    // Assuming `myFunctionOutput` is an output-form invocation of the `myFunction`
    // provider function, this use of `all` and `apply` will ensure that it does not
    // happen until `res1` and `res2` have been processed. This will work for any
    // set of resources, even those with no explicit outputs, since the `.urn`
    // output is always available.
    pulumi.all([res1.urn, res2.urn]).apply(() => myFunctionOutput());
    
    using System.Collections.Generic;
    using System.Linq;
    using Pulumi;
    
    return await Deployment.RunAsync(() =>
    {
        var res1 = new MyResource("res1", new MyResourceArgs());
        var res2 = new MyResource("res2", new MyResourceArgs());
    
        // Assuming `myFunctionOutput` is an output-form invocation of the `myFunction`
        // provider function, this use of `Tuple` and `Apply` will ensure that it does
        // not happen until `res1` and `res2` have been processed. This will work for
        // any set of resources, even those with no explicit outputs, since the `.Urn`
        // output is always available.
        Output.Tuple(res1.Urn, res2.Urn).Apply(t => myFunctionOutput());
    });
    
    package main
    
    import (
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    		res1, err := NewMyResource(ctx, "res1", nil)
    		if err != nil {
    			return err
    		}
    
    		res2, err := NewMyResource(ctx, "res2", nil)
    		if err != nil {
    			return err
    		}
    
    		// Assuming `myFunctionOutput` is an output-form invocation of the `myFunction`
    		// provider function, this use of `All` and `ApplyT` will ensure that it does not
    		// happen until `res1` and `res2` have been processed. This will work for any set
    		// of resources, even those with no explicit outputs, since the `.URN` output is
    		// always available.
    		_, err = pulumi.All(res1.URN, res2.URN).ApplyT(func(args []interface{}) (interface{}, error) {
    			return myFunctionOutput()
    		})
    		if err != nil {
    			return err
    		}
    
    		return nil
    	})
    }
    
    import pulumi
    
    res1 = MyResource("res1", {})
    res2 = MyResource("res2", {})
    
    # Assuming `my_function_output` is an output-form invocation of the `my_function`
    # provider function, this use of `all` and `apply` will ensure that it does not
    # happen until `res1` and `res2` have been processed. This will work for any set
    # of resources, even those with no explicit outputs, since the `.urn` output is
    # always available.
    pulumi.all(res1.urn, res2.urn).apply(lambda args: my_function_output())
    
    package generated_program;
    
    import com.pulumi.Context;
    import com.pulumi.Output;
    import com.pulumi.Pulumi;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(App::stack);
        }
    
        public static void stack(Context ctx) {
            final var res1 = new MyResource("res1", new MyResourceArgs());
            final var res2 = new MyResource("res2", new MyResourceArgs());
    
            // Assuming `myFunctionOutput` is an output-form invocation of the `myFunction`
            // provider function, this use of `tuple` and `applyValue` will ensure that it does
            // not happen until `res1` and `res2` have been processed. This will work for
            // any set of resources, even those with no explicit outputs, since the `.urn`
            // output is always available.
            Output.tuple(res1.getUrn(), res2.getUrn()).applyValue(t -> myFunctionOutput());
        }
    }
    

    Output form invocations are not yet supported in YAML.

    Resource methods

    Provider SDKs may also include methods attached to a resource type. For example, in the EKS SDK, the Cluster resource has a .GetKubeconfig method:

    getKubeconfig(args?: Cluster.GetKubeconfigArgs): Output<Cluster.GetKubeconfigResult>
    
    public Output<string> GetKubeconfig(Cluster.GetKubeconfigArgs? args)
    
    func (r *Cluster) GetKubeconfig(ctx *Context, args *ClusterGetKubeconfigArgs) (pulumi.StringOutput, error)
    
    def get_kubeconfig(self,
                       profile_name: Optional[pulumi.Input[str]] = None,
                       role_arn: Optional[pulumi.Input[str]] = None) -> Output[str]
    

    No example available for Java

    No example available for YAML

    Unlike provider functions, methods always appear in the output form: they take Input arguments, and return an Output. Moreover, methods do not accept invoke options.

      PulumiUP 2024. Watch On Demand.