https://pulumi.com logo
Title
f

flaky-planet-42808

09/02/2021, 2:50 PM
Hey team - how do I get the identity of the ingress application gateway add-on of AKS cluster?  My scenario is as below, I'm creating a new AKS cluster using
ManagedCluster
API with
ingressApplicationGateway
as one of the add-on profiles. After the creation, I’m trying to get the identity of this add-on in-order to assign the required permissions to manage the application gateway. But I’m having trouble getting this identity using
UserAssignedIdentity.Get
. Pulumi preview fails because it expects the identity to be already available but it wouldn’t be until the cluster is created. Thanks!
t

tall-librarian-49374

09/03/2021, 6:59 AM
Could you share your relevant code? There’s probably an
apply
missing somewhere in the chain.
f

flaky-planet-42808

09/03/2021, 11:37 AM
Sure.
var ingressAddOnProfileName = "ingressApplicationGateway";

var cluster = new ManagedCluster(
  clusterName,
  new ManagedClusterArgs
  {
	<SNIP>
	AddonProfiles =
	{
  	{
    ingressAddOnProfileName,
    new ManagedClusterAddonProfileArgs
    {
      Enabled = true,
      Config = { { "applicationGatewayId", appGateway.Id } }
    }
  	}
	}
	};

var agicReader = new RoleAssignment(cluster.AddonProfiles.Apply(x => x![ingressAddOnProfileName].Identity.ObjectId!), AzureBuiltInRole.Reader, resourceGroupName, roleName);
So RoleAssignment is our custom method to create role assignments.
Pulumi preview fails with this error:
failed with an unhandled exception:
System.NullReferenceException: Object reference not set to an instance of an object.
  at KubernetesCluster(string clusterName, string location, string environment, string environmentPrefix, Output<string> securityStorageAccountId, UserAssignedIdentity appGatewayIdentity, string clusterSubnetId, Output<string> loganalyticsWorkspaceId, PublicIPAddress appGatewayPublicIp)+(ImmutableDictionary<string, ManagedClusterAddonProfileResponse> x) => { } [2] in KubernetesCluster.cs:line 321
  at Output<U> Pulumi.Output<T>.Apply<U>(Func<T, U> func)+(T t) => { }
  at async Task<OutputData<U>> Pulumi.Output<T>.ApplyHelperAsync<U>(Task<OutputData<T>> dataTask, Func<T, Output<U>> func)
  at async Task<OutputData<object>> Pulumi.Output<T>.Pulumi.IOutput.GetDataAsync()
  at async Task<object> Pulumi.Serialization.Serializer.SerializeAsync(string ctx, object prop, bool keepResources) x 2
  at async Task<SerializationResult> Pulumi.Deployment.SerializeFilteredPropertiesAsync(string label, IDictionary<string, object> args, Predicate<string> acceptKey, bool keepResources)
  at async Task<PrepareResult> Pulumi.Deployment.PrepareResourceAsync(string label, Resource res, bool custom, bool remote, ResourceArgs args, ResourceOptions options)
  at async Task<(string urn, string id, Struct data, ImmutableDictionary<string, ImmutableHashSet<Resource>> dependencies)> Pulumi.Deployment.RegisterResourceAsync(Resource resource, bool remote, Func<string, Resource> newDependency, ResourceArgs args, ResourceOptions options)
  at async Task<(string urn, string id, Struct data, ImmutableDictionary<string, ImmutableHashSet<Resource>> dependencies)> Pulumi.Deployment.ReadOrRegisterResourceAsync(Resource resource, bool remote, Func<string, Resource> newDependency, ResourceArgs args, ResourceOptions options)
  at async Task Pulumi.Deployment.CompleteResourceAsync(Resource resource, bool remote, Func<string, Resource> newDependency, ResourceArgs args, ResourceOptions options, ImmutableDictionary<string, IOutputCompletionSource> completionSources)
line 321 is the where we do the role assignments
t

tall-librarian-49374

09/03/2021, 2:18 PM
I see… I think the engine assumes that AddonProfiles are populated already because they are both input and outputs. You may need to add null checks inside your Apply and return some default value for the sake of preview.
i

important-book-47803

09/06/2021, 4:57 PM
I have run into a similar issue where once a change is made to the managed cluster the AddonProfiles["ingressApplicationGateway"].Identity gets set to null and so fails with a null exception. If deploying to an empty stack this works or changes outside of the managed cluster. Looks like as the managged cluster already exists it assumes all values are populated. Will let you know if I find anything.
f

flaky-planet-42808

09/14/2021, 4:16 PM
Update: I was able to workaround this problem by doing the role assignment within the
Apply
, also made role assignment function to explicitly depend on the cluster by using
CustomResourceOptions { DependsOn = cluster }
- so that the role assignments wouldn’t run before cluster creation during preview.
var ReaderAssignment = cluster.AddonProfiles.Apply(
    x => new RoleAssignment(x![ingressAddOnProfileName].Identity.ObjectId!, AzureBuiltInRole.Reader, ApplicationResourceGroup.GetResourceGroupId(environment), $"{clusterName}-agic-reader-assignment", cluster));
t

tall-librarian-49374

09/14/2021, 8:31 PM
Creating resources inside
Apply
is generally discouraged as your previews may not be accurate. I’m fairly sure you could produce inputs in Apply and then assign them to
RoleAssignment
at the top level. Let me know if you need help with that.