The goal of this exercise is to start getting some hands-on experience with Pulumi, using the azure-native
provider. While doing so, you will deploy 2 stacks, and exchange information between them using a StackReference
See: https://www.pulumi.com/docs/using-pulumi/organizing-projects-stacks/
name
parameter is passed as the 1st argument. This parameter sets the resource's identifier, and is used to generate the resources' target name with a random suffix.
In order to avoid random resource names, pay attention to Args
arguments passed to Pulumi resources, as they typically contain properties that set the resources' name directly.
Example property names:
ResourceName
RuleName
etc.
In order to consume outputs of a stack by another stack, a StackReference can be used.
Outputs can be retrieved using GetOutput
which will return na nullable result if an output has not been set. Alternatively RequireOutput
can be used in order to get a non-nullable output value.
var stackRef = new Pulumi.StackReference(stackId);
string? value1 = stackRef.GetOutput("url");
string value2 = stackRef.RequireOutput("url");
Using C# it is completely possible, to have StronglyTyped stack references:
public class StackReference<T> : StackReference where T : Stack
{
public static StackReference<T> Create(string? stackName = null) {
return new StackReference<T>(typeof(T).Name, new StackReferenceArgs
{
Name = $"organization/{typeof(T).Assembly.GetName().Name}/{stackName}"
});
}
public StackReference(string name, StackReferenceArgs args, CustomResourceOptions? options = null)
: base(name, args, options)
{
}
public Output<G> RequireOutput<G>(Expression<Func<T, Output<G>>> action) =>
RequireOutput(((MemberExpression)action.Body).Member.Name).Apply(_ => (G)_);
}
Example usage:
var kv = StackReference<KeyVaultStack>.Create(Pulumi.Deployment.Instance.StackName);
var vaultRef = (
ResourceGroup: kv.RequireOutput(x => x.ResourceGroupName),
Resource: kv.RequireOutput(x => x.Name)
);
- navigate to
/exercise02/src
folder and examine both projects which are a part of the solution. - follow the comments in order to implement the solution
Stack outputs can be defined in the following way
public class MyStack: Stack
{
[Output] public Output<string> Name { get; set; }
[Output] public Output<string> ResourceGroupName { get; set; }
}
(ResourceGroup ResourceGroup, StorageAccount Resource) storage = // (...);
bool primary = true;
ListStorageAccountKeys.Invoke(new ListStorageAccountKeysInvokeArgs()
{
ResourceGroupName = storage.ResourceGroup.Name,
AccountName = storage.Resource.Name
}).Apply(x => x.Keys[primary ? 0 : 1].Value);