Trying to get an azure function app running and I ...
# azure
c
Trying to get an azure function app running and I keep getting this error:
Copy code
Error: Invoke of 'azure:storage/getAccountBlobContainerSAS:getAccountBlobContainerSAS' failed: "container_name": required field is not set ()
        at deserializeResponse (/home/kyle/workspace/ops/mapped_infrastructure/node_modules/@pulumi/pulumi/runtime/invoke.js:194:15)
        at /home/kyle/workspace/ops/mapped_infrastructure/node_modules/@pulumi/pulumi/runtime/invoke.js:145:20
        at Generator.next (<anonymous>)
        at fulfilled (/home/kyle/workspace/ops/mapped_infrastructure/node_modules/@pulumi/pulumi/runtime/invoke.js:18:58)
        at processTicksAndRejections (node:internal/process/task_queues:93:5)
but those resources seem to be validly defined in my index.ts file:
Copy code
// The container to put our files into
const container = new azure.storage.Container("files", {
    
    storageAccountName: storageAccount.name,
    containerAccessType: "private",
});

// <http://ASP.NET|ASP.NET> deployment package
const blob = new azure.storage.Blob("zip", {
    storageAccountName: storageAccount.name,
    storageContainerName: container.name,
    type: "Block",
    source: new pulumi.asset.FileArchive("<https://github.com/mapped/connector-functions/suites/1471048737/artifacts/25311357>"),
});
anyone have any ideas what's going on?
g
Is there more to your code? The error message refers to
azure:storage/getAccountBlobContainerSAS:getAccountBlobContainerSAS
which is a lookup function, but isn't present in the code you shared.
c
yeah, of course. that's referring to something in a bunch of the node_modules that are automatically installed on a new pulumi project. Here's the full stacktrace.
Copy code
Diagnostics:
  pulumi:pulumi:Stack (pulumi-scratch-dev):
    Error: Invoke of 'azure:storage/getAccountBlobContainerSAS:getAccountBlobContainerSAS' failed: "container_name": required field is not set ()
        at deserializeResponse (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:194:15)
        at /home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:145:20
        at Generator.next (<anonymous>)
        at fulfilled (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:18:58)
        at processTicksAndRejections (node:internal/process/task_queues:93:5)
    Error: Invoke of 'azure:storage/getAccountBlobContainerSAS:getAccountBlobContainerSAS' failed: "container_name": required field is not set ()
        at deserializeResponse (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:194:15)
        at /home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:145:20
        at Generator.next (<anonymous>)
        at fulfilled (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:18:58)
        at processTicksAndRejections (node:internal/process/task_queues:93:5)
    Error: Invoke of 'azure:storage/getAccountBlobContainerSAS:getAccountBlobContainerSAS' failed: "container_name": required field is not set ()
        at deserializeResponse (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:194:15)
        at /home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:145:20
        at Generator.next (<anonymous>)
        at fulfilled (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:18:58)
        at processTicksAndRejections (node:internal/process/task_queues:93:5)
 
    unhandled rejection: CONTEXT(708): resource:mappingFunctions[azure:appservice/functionApp:FunctionApp]
    STACK_TRACE:
    Error:
        at Object.debuggablePromise (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/debuggable.js:69:75)
        at Object.registerResource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/resource.js:132:18)
        at new Resource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/resource.js:211:24)
        at new CustomResource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/resource.js:303:9)
        at new FunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/functionApp.ts:318:9)
        at new PackagedFunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/zMixins.ts:698:28)
        at new ArchiveFunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/zMixins.ts:712:9)
        at Object.<anonymous> (/home/kyle/workspace/pulumi-scratch/index.ts:38:13)
        at Module._compile (node:internal/modules/cjs/loader:1083:30)
        at Module.m._compile (/home/kyle/workspace/pulumi-scratch/node_modules/ts-node/src/index.ts:439:23)
    unhandled rejection: CONTEXT(708): resource:mappingFunctions[azure:appservice/functionApp:FunctionApp]
    STACK_TRACE:
    Error:
        at Object.debuggablePromise (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/debuggable.js:69:75)
        at Object.registerResource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/resource.js:132:18)
        at new Resource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/resource.js:211:24)
        at new CustomResource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/resource.js:303:9)
        at new FunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/functionApp.ts:318:9)
        at new PackagedFunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/zMixins.ts:698:28)
        at new ArchiveFunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/zMixins.ts:712:9)
        at Object.<anonymous> (/home/kyle/workspace/pulumi-scratch/index.ts:38:13)
        at Module._compile (node:internal/modules/cjs/loader:1083:30)
        at Module.m._compile (/home/kyle/workspace/pulumi-scratch/node_modules/ts-node/src/index.ts:439:23)
    unhandled rejection: CONTEXT(708): resource:mappingFunctions[azure:appservice/functionApp:FunctionApp]
    STACK_TRACE:
    Error:
        at Object.debuggablePromise (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/debuggable.js:69:75)
        at Object.registerResource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/resource.js:132:18)
        at new Resource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/resource.js:211:24)
        at new CustomResource (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/resource.js:303:9)
        at new FunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/functionApp.ts:318:9)
        at new PackagedFunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/zMixins.ts:698:28)
        at new ArchiveFunctionApp (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/appservice/zMixins.ts:712:9)
        at Object.<anonymous> (/home/kyle/workspace/pulumi-scratch/index.ts:38:13)
        at Module._compile (node:internal/modules/cjs/loader:1083:30)
        at Module.m._compile (/home/kyle/workspace/pulumi-scratch/node_modules/ts-node/src/index.ts:439:23)
 
    error: Running program '/home/kyle/workspace/pulumi-scratch' failed with an unhandled exception:
    Error: Invoke of 'azure:storage/getAccountBlobContainerSAS:getAccountBlobContainerSAS' failed: "container_name": required field is not set ()
        at deserializeResponse (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:194:15)
        at /home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:145:20
        at Generator.next (<anonymous>)
        at fulfilled (/home/kyle/workspace/pulumi-scratch/node_modules/@pulumi/pulumi/runtime/invoke.js:18:58)
        at processTicksAndRejections (node:internal/process/task_queues:93:5)
g
Sorry, I meant is there more code to your Pulumi application?
c
oh yeah, of course. hang on, I'll drop it here. thanks for taking some time with this 🙂
index.ts:
Copy code
import * as pulumi from "@pulumi/pulumi";
import * as azure from "@pulumi/azure";
import * as eventhub from "@pulumi/azure/eventhub";
import * as iot from "@pulumi/azure/iot";

// Create an Azure Resource Group
const resourceGroup = new azure.core.ResourceGroup("resourceGroup", {
    location: azure.Locations.WestUS2,
});

let stack_name: string = pulumi.getStack();

// use first 10 characters of the stackname as prefix for resource names   
const prefix = pulumi.getStack().substring(0, 9);


//create namespace 
const namespace = new eventhub.EventHubNamespace(stack_name, {
    resourceGroupName: resourceGroup.name,
    sku: "standard",
});



// create eventhubs (change to a forloop at some point I'm sure)
const ingest_eventHub = new eventhub.EventHub("ingest", {
    resourceGroupName: resourceGroup.name,
    namespaceName: namespace.name,
    partitionCount: 2,
    messageRetention: 7,
});

const merge_eventHub = new eventhub.EventHub("merge", {
    resourceGroupName: resourceGroup.name,
    namespaceName: namespace.name,
    partitionCount: 2,
    messageRetention: 7,
});

// create CosmosDB account
const db = new azure.cosmosdb.Account( stack_name, {
    location: resourceGroup.location,
    resourceGroupName: resourceGroup.name,
    offerType: "Standard",
    kind: "MongoDB",
    enableAutomaticFailover: false,
    capabilities: [
        {
            name :"EnableMongo"
        },
        {
            name: "EnableAggregationPipeline",
        },
        {
            name: "mongoEnableDocLevelTTL",
        },
        {
            name: "MongoDBv3.4",
        },
    ],
    consistencyPolicy: {
        consistencyLevel: "BoundedStaleness",
        maxIntervalInSeconds: 10,
        maxStalenessPrefix: 200,
    },
    geoLocations: [
        {
            location: resourceGroup.location,
            failoverPriority: 0,
        }
    ],
});

// create CosmosDB database in mogomode
const exampleMongoDatabase = new azure.cosmosdb.MongoDatabase("device_profiles", {
    resourceGroupName: resourceGroup.name,
    accountName: db.name,
    throughput: 400
});


// Create IOT Hub
const iotHub = new iot.IoTHub(stack_name, {
    resourceGroupName: resourceGroup.name,
    sku: {
        capacity: 1,
        name: "S1",
    },
    fallbackRoute: {
        source: "DeviceMessages",
        enabled: true,
        endpointNames: ["events"],
        condition: "true",
    },
});

// Create Azure Function
// Create an Azure resource (Storage Account)
const storageAccount = new azure.storage.Account("storage", {
    // The location for the storage account will be derived automatically from the resource group.
    resourceGroupName: resourceGroup.name,
    accountTier: "Standard",
    accountReplicationType: "LRS",
});

// The container to put our files into
const container = new azure.storage.Container("files", {
    name: "files",
    storageAccountName: storageAccount.name,
    containerAccessType: "private",
});

const plan = new azure.appservice.Plan("asp", {
    resourceGroupName: resourceGroup.name,
    kind: "FunctionApp",
    sku: {
        tier: "Dynamic",
        size: "Y1",
    },
});




//Use this to create a function app from a remote archive
const archiveApp = new azure.appservice.ArchiveFunctionApp("archive-app", {
    resourceGroup,
    archive: new pulumi.asset.RemoteArchive("<https://github.com/mapped/connector-functions/suites/1471048737/artifacts/25311357>"),
});

// Export the connection string for the storage account
export const connectionString = storageAccount.primaryConnectionString;
I know the function itself is working, currently running in some docker setup that predates me at this company. working on getting it migrated to pulumi administered microservices. If I point to a different, "hello world" app it works fine, but as soon as I point it to this function instead, it fails like this
g
Is that the entirety of the code in your Pulumi application? Given the error, message I would expect to see a call to
getAccountBlobContainerSAS
- https://www.pulumi.com/docs/reference/pkg/azure/storage/getaccountblobcontainersas/#getaccountblobcontainersas.
c
yeah, 100% of our code is in the pulumi app I copied above. that
getAccountBlobContainerSAS
function lives in the node_modules installed by default with pulumi new. Which is part of why this has been so difficult to troubleshoot
g
Do you get this during
preview
or only on an
up
?
Your code previews successfully for me.
Ah... I think I see what's happening.
Still looking into this. Thanks for your patience.
Ok, unfortunately I think
pulumi.asset.RemoteArchive
is failing silently in this case because it is expecting a .tar, .tar.gz, or .zip file extension which the URL you're using does not have. Also, I suspect you might hit another issue where the URL you're using seems to require an authenticated user as it returns a 404 and it looks like the
pulumi.asset.RemoteArchive
also isn't handling 404's correctly.
So... the fix would be to use a URL that ends in .zip (or other archive extension) and make sure that it's reachable - so likely would need a signed URL or other means to authenticate.
And I'll open an issue to improve the error handling and messaging in these scenarios/
c
@gentle-diamond-70147 thanks a ton. I continued tinkering with it last night, got it working this morning. I was definitely doing it wrong. Wrote it out this way and it works fine. I think the main issue with the previous method was that the errors were so obscure I couldn't figure out how to troubleshoot it. Here's the version that worked, for reference.
Copy code
//Use this to create a function app from a remote archive
const app = new azure.appservice.FunctionApp("connectorFunctions", {
    resourceGroupName: resourceGroup.name,
    appServicePlanId:plan.id,
    storageAccountName: account.name,
    storageAccountAccessKey: account.primaryAccessKey,
    appSettings: { 
        runtime: "dotnet",
        websiteRunFromPackage:  "<https://github.com/mapped/connector-functions/suites/1483831234/artifacts/25707154>"
    }
});
g
Glad you got it fixed. Agreed the errors were very obscure.
I'm not familiar with the
websiteRunFromPackage
option. I'm curious... how does azure authenticate to download the private artifact?
c
getting the authentication sorted was key. You have to run
Copy code
pulumi config set github:token <token> --secret
g
Interesting. Learned something new today, thanks!
https://github.com/pulumi/pulumi/issues/5756 to provide a better error message and user experience here