Projects
A Pulumi project is any folder that contains a Pulumi.yaml project file. At runtime, the nearest parent folder containing a Pulumi.yaml file determines the current project. Projects are created with the pulumi new command.
The project file (Pulumi.yaml)
The project file specifies which runtime to use and determines where to look for the program that should be executed during deployments. Supported runtimes are nodejs, python, dotnet, go, java, and yaml.
Project files also contain metadata about your project. The project file must begin with a capital P, although either .yml or .yaml extension will work.
A typical Pulumi.yaml file looks like the following:
name: webserver
runtime: nodejs
description: A minimal JavaScript Pulumi program.
In addition, when using JavaScript or TypeScript, the working directory for the project should contain a package.json file that points to an entrypoint such as index.js. In Python, the presence of a __main__.py or setup.py file defines the entrypoint.
The following are other examples of Pulumi.yaml files that define project configurations for other use cases:
A
Pulumi.yamlfile for a Node.js program that uses JavaScript rather than TypeScript:name: my-project runtime: name: nodejs options: typescript: falseA
Pulumi.yamlfile for a Go program that uses a pre-built executable namedmybinary:name: my-project description: A precompiled Go Pulumi program. runtime: name: go options: binary: mybinaryA
Pulumi.yamlfile for a .NET program that uses a pre-built assembly namedMyInfra.dllin thebindirectory:name: my-project description: A precompiled .NET Pulumi program. runtime: name: dotnet options: binary: bin/MyInfra.dllA
Pulumi.yamlfile for a Java program that uses a pre-built JAR file:name: my-project description: A precompiled Java Pulumi program. runtime: name: java options: binary: target/my-project-1.0-SNAPSHOT-jar-with-dependencies.jarA
Pulumi.yamlfile for aYAMLprogram that includes its resources inline:name: my-project runtime: yaml resources: bucket: type: aws:s3:Bucket
For more information on valid Pulumi project metadata, see the Pulumi.yaml reference.
Project-relative paths
When your Pulumi program refers to resources in the local filesystem, paths are always relative to the working directory. In the following example, the aws.ecr.Image resource refers to a subfolder of the working directory named app that contains a Dockerfile:
"use strict";
const pulumi = require("@pulumi/pulumi");
const awsx = require("@pulumi/awsx");
const repository = new awsx.ecr.Repository("repository", {
forceDelete: true,
});
const image = new awsx.ecr.Image("image", {
repositoryUrl: repository.url,
context: "./app",
platform: "linux/amd64",
});
exports.url = repository.url;
import * as pulumi from "@pulumi/pulumi";
import * as awsx from "@pulumi/awsx";
const repository = new awsx.ecr.Repository("repository", {
forceDelete: true,
});
const image = new awsx.ecr.Image("image", {
repositoryUrl: repository.url,
context: "./app",
platform: "linux/amd64",
});
export const url = repository.url;
import pulumi
import pulumi_awsx as awsx
repository = awsx.ecr.Repository("repository", force_delete=True)
image = awsx.ecr.Image(
"image",
repository_url=repository.url,
context="./app",
platform="linux/amd64",
)
pulumi.export("url", repository.url)
package main
import (
"github.com/pulumi/pulumi-awsx/sdk/v3/go/awsx/ecr"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
repository, err := ecr.NewRepository(ctx, "repository", &ecr.RepositoryArgs{
ForceDelete: pulumi.Bool(true),
})
if err != nil {
return err
}
_, err = ecr.NewImage(ctx, "image", &ecr.ImageArgs{
RepositoryUrl: repository.Url,
Context: pulumi.String("./app"),
Platform: pulumi.String("linux/amd64"),
})
if err != nil {
return err
}
ctx.Export("url", repository.Url)
return nil
})
}
using System.Collections.Generic;
using Pulumi;
using Awsx = Pulumi.Awsx;
return await Deployment.RunAsync(() =>
{
var repository = new Awsx.Ecr.Repository("repository", new()
{
ForceDelete = true,
});
var image = new Awsx.Ecr.Image("image", new()
{
RepositoryUrl = repository.Url,
Context = "./app",
Platform = "linux/amd64",
});
return new Dictionary<string, object?>
{
["url"] = repository.Url,
};
});
package myproject;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.awsx.ecr.Repository;
import com.pulumi.awsx.ecr.RepositoryArgs;
import com.pulumi.awsx.ecr.Image;
import com.pulumi.awsx.ecr.ImageArgs;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var repository = new Repository("repository", RepositoryArgs.builder()
.forceDelete(true)
.build());
var image = new Image("image", ImageArgs.builder()
.repositoryUrl(repository.url())
.context("./app")
.platform("linux/amd64")
.build());
ctx.export("url", repository.url());
}
}
name: awsx-ecr-image-yaml
runtime: yaml
resources:
repository:
type: awsx:ecr:Repository
properties:
forceDelete: true
image:
type: awsx:ecr:Image
properties:
repositoryUrl: ${repository.url}
context: "./app"
platform: "linux/amd64"
outputs:
url: ${repository.url}
Root-relative paths
You can get the directory containing the Pulumi.yaml file, which may differ from your working directory if it specified a main option (see main attribute), with the ProjectDirectory function.
The path returned is an absolute path. When using this in resource properties, ensure it’s relative to the working directory. This prevents diffs from running the project on multiple machines with different roots.
import * as awsx from "@pulumi/awsx";
import * as pulumi from "@pulumi/pulumi";
import { join, relative } from "path";
const root = pulumi.getRootDirectory();
const cwd = process.cwd();
const appPath = join(root, "app");
const relativePath = relative(cwd, appPath);
const repository = new awsx.ecr.Repository("repository", {
forceDelete: true,
});
const image = new awsx.ecr.Image("image", {
repositoryUrl: repository.url,
context: relativePath,
platform: "linux/amd64",
});
export const url = repository.url;
import pulumi
import pulumi_awsx as awsx
import os
root = pulumi.get_root_directory()
cwd = os.getcwd()
app_path = os.path.join(root, "app")
relative_path = os.path.relpath(app_path, cwd)
repository = awsx.ecr.Repository("repository", force_delete=True)
image = awsx.ecr.Image(
"image",
repository_url=repository.url,
context=relative_path,
platform="linux/amd64",
)
pulumi.export("url", repository.url)
package main
import (
"os"
"path/filepath"
"github.com/pulumi/pulumi-awsx/sdk/v3/go/awsx/ecr"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
root := ctx.RootDirectory()
cwd, err := os.Getwd()
if err != nil {
return err
}
path := filepath.Join(root, "app")
path, err = filepath.Rel(cwd, path)
if err != nil {
return err
}
repository, err := ecr.NewRepository(ctx, "repository", &ecr.RepositoryArgs{
ForceDelete: pulumi.Bool(true),
})
if err != nil {
return err
}
_, err = ecr.NewImage(ctx, "image", &ecr.ImageArgs{
RepositoryUrl: repository.Url,
Context: pulumi.String(path),
Platform: pulumi.String("linux/amd64"),
})
if err != nil {
return err
}
ctx.Export("url", repository.Url)
return nil
})
}
using System.Collections.Generic;
using System.IO;
using Pulumi;
using Awsx = Pulumi.Awsx;
return await Deployment.RunAsync(() =>
{
var root = Pulumi.Deployment.Instance.RootDirectory;
var cwd = Directory.GetCurrentDirectory();
var appPath = Path.Combine(root, "app");
var relativePath = Path.GetRelativePath(cwd, appPath);
var repository = new Awsx.Ecr.Repository("repository", new()
{
ForceDelete = true,
});
var image = new Awsx.Ecr.Image("image", new()
{
RepositoryUrl = repository.Url,
Context = relativePath,
Platform = "linux/amd64",
});
return new Dictionary<string, object?>
{
["url"] = repository.Url,
};
});
Getting the current project programmatically
The getProject
getProject
get_project
context.Project
Deployment.Instance.ProjectName
context.projectName()
pulumi.project
const project = pulumi.getProject();
const project = pulumi.getProject();
project = pulumi.get_project()
project := ctx.Project()
var project = Deployment.Instance.ProjectName;
var project = ctx.projectName();
variables:
project: ${pulumi.project}
Stack settings files
Each stack that is created in a project will have a file named Pulumi.<stackname>.yaml that contains the configuration specific to this stack. This file typically resides in the root of the project directory.
For stacks that are actively developed by multiple members of a team, the recommended practice is to check them into source control as a means of collaboration. Since secret values are encrypted, it is safe to check in these stack settings. When using ephemeral stacks, the stack settings are typically not checked into source control.
For more information about configuration and how to manage these files on the command line and programmatically, refer to the Configuration and Secrets documentation.
Thank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.
