Get started with Pulumi and Azure
Make an update
Now you will update your project to serve a static website out of your Azure storage account. You will change your code and then re-run pulumi up which will update your infrastructure.
Add new resources
Pulumi knows how to evolve your current infrastructure to your project’s new desired state, both for the first deployment as well as subsequent updates.
To turn your storage account into a static website, you will add two new Azure resources:
StorageAccountStaticWebsite: enables static website support on your storage accountBlob: uploads your website content to the storage container
Add an index.html
First, from within your project directory, create a new index.html file with some content in it.
cat <<EOT > index.html
<html>
<body>
<h1>Hello, Pulumi!</h1>
</body>
</html>
EOT
cat <<EOT > index.html
<html>
<body>
<h1>Hello, Pulumi!</h1>
</body>
</html>
EOT
@"
<html>
<body>
<h1>Hello, Pulumi!</h1>
</body>
</html>
"@ | Out-File -FilePath index.html
Now open index.jsindex.ts__main__.pymain.goProgram.csProgram.fsProgram.vbApp.javaPulumi.yamlStorageAccountStaticWebsite resource right after the storage account is created:
// Create an Azure resource (Storage Account)
const storageAccount = new storage.StorageAccount("sa", {
/* existing storage account configuration */
});
// Enable static website support - add this code
const staticWebsite = new storage.StorageAccountStaticWebsite("staticWebsite", {
accountName: storageAccount.name,
resourceGroupName: resourceGroup.name,
indexDocument: "index.html",
});
# Create an Azure resource (Storage Account)
account = storage.StorageAccount(
"sa",
# existing storage account configuration
)
# Enable static website support - add this code
static_website = storage.StorageAccountStaticWebsite(
"staticWebsite",
account_name=account.name,
resource_group_name=resource_group.name,
index_document="index.html",
)
// Create an Azure resource (Storage Account)
account, err := storage.NewStorageAccount(ctx, "sa", &storage.StorageAccountArgs{
// existing storage account configuration
})
if err != nil {
return err
}
// Enable static website support - add this code
staticWebsite, err := storage.NewStorageAccountStaticWebsite(ctx, "staticWebsite", &storage.StorageAccountStaticWebsiteArgs{
AccountName: account.Name,
ResourceGroupName: resourceGroup.Name,
IndexDocument: pulumi.String("index.html"),
})
if err != nil {
return err
}
// Create an Azure resource (Storage Account)
var storageAccount = new StorageAccount("sa", new StorageAccountArgs
{
/* existing storage account configuration */
});
// Enable static website support - add this code
var staticWebsite = new StorageAccountStaticWebsite("staticWebsite", new StorageAccountStaticWebsiteArgs
{
AccountName = storageAccount.Name,
ResourceGroupName = resourceGroup.Name,
IndexDocument = "index.html",
});
First, add the following imports at the top of App.java:
import com.pulumi.azurenative.storage.StorageAccountStaticWebsite;
import com.pulumi.azurenative.storage.StorageAccountStaticWebsiteArgs;
import com.pulumi.azurenative.storage.Blob;
import com.pulumi.azurenative.storage.BlobArgs;
import com.pulumi.azurenative.storage.outputs.EndpointsResponse;
import com.pulumi.asset.FileAsset;
Then add the following right after the storage account creation:
// Create an Azure resource (Storage Account)
var storageAccount = new StorageAccount("sa", StorageAccountArgs.builder()
// existing storage account configuration
.build());
// Enable static website support - add this code
var staticWebsite = new StorageAccountStaticWebsite("staticWebsite",
StorageAccountStaticWebsiteArgs.builder()
.accountName(storageAccount.name())
.resourceGroupName(resourceGroup.name())
.indexDocument("index.html")
.build());
resources:
# Create an Azure resource (Storage Account)
sa:
type: azure-native:storage:StorageAccount
# existing storage account configuration
# Enable static website support - add this code
staticWebsite:
type: azure-native:storage:StorageAccountStaticWebsite
properties:
accountName: ${sa.name}
resourceGroupName: ${resourceGroup.name}
indexDocument: index.html
Notice that resources can reference each other, which forms automatic dependencies between them. Pulumi uses this information to parallelize deployments safely.
Now use all of these cloud resources and a local FileAsset resource to upload index.html into your storage container by adding a Blob at the end of the file (after enabling the static website support):
// Upload the file
const indexHtml = new storage.Blob("index.html", {
resourceGroupName: resourceGroup.name,
accountName: storageAccount.name,
containerName: staticWebsite.containerName,
source: new pulumi.asset.FileAsset("index.html"),
contentType: "text/html",
});
# Upload the file
index_html = storage.Blob(
"index.html",
resource_group_name=resource_group.name,
account_name=account.name,
container_name=static_website.container_name,
source=pulumi.FileAsset("index.html"),
content_type="text/html",
)
// Upload the file
_, err = storage.NewBlob(ctx, "index.html", &storage.BlobArgs{
ResourceGroupName: resourceGroup.Name,
AccountName: account.Name,
ContainerName: staticWebsite.ContainerName,
Source: pulumi.NewFileAsset("index.html"),
ContentType: pulumi.String("text/html"),
})
if err != nil {
return err
}
// Upload the file
var indexHtml = new Blob("index.html", new BlobArgs
{
ResourceGroupName = resourceGroup.Name,
AccountName = storageAccount.Name,
ContainerName = staticWebsite.ContainerName,
Source = new FileAsset("./index.html"),
ContentType = "text/html",
});
// Upload the file
var index_html = new Blob("index.html", BlobArgs.builder()
.resourceGroupName(resourceGroup.name())
.accountName(storageAccount.name())
.containerName(staticWebsite.containerName())
.source(new FileAsset("index.html"))
.contentType("text/html")
.build());
resources:
# ...
# Upload the file
index-html:
type: azure-native:storage:Blob
properties:
resourceGroupName: ${resourceGroup.name}
accountName: ${sa.name}
containerName: ${staticWebsite.containerName}
source:
fn::fileAsset: ./index.html
contentType: text/html
blobName: index.html
type: Block
This uploads the index.html file to your storage container using a Pulumi concept called an asset.
Export the website URL
Now to export the website’s URL for easy access, add the staticEndpoint export to your return statement as shown in this example:
// Export the storage account name
export const storageAccountName = storageAccount.name;
// Web endpoint to the website
export const staticEndpoint = storageAccount.primaryEndpoints.web;
# Export the storage account name
pulumi.export("storage_account_name", account.name)
# Web endpoint to the website
pulumi.export("staticEndpoint", account.primary_endpoints.web)
// Export the storage account name
ctx.Export("storageAccountName", account.Name)
// Web endpoint to the website
ctx.Export("staticEndpoint", account.PrimaryEndpoints.Web())
// Export outputs
return new Dictionary<string, object?>
{
["storageAccountName"] = storageAccount.Name,
["staticEndpoint"] = storageAccount.PrimaryEndpoints.Apply(primaryEndpoints => primaryEndpoints.Web)
};
// Export the storage account name
ctx.export("storageAccountName", storageAccount.name());
// Web endpoint to the website
ctx.export("staticEndpoint", storageAccount.primaryEndpoints()
.applyValue(EndpointsResponse::web));
outputs:
# Export the storage account name
storageAccountName: ${sa.name}
# Web endpoint to the website
staticEndpoint: ${sa.primaryEndpoints.web}
The storage account’s endpoint is an output property that Azure assigns at deployment time, not a raw string, meaning its value is not known in advance.
Deploy the changes
To deploy the changes, run pulumi up again and it will figure out the deltas:
$ pulumi up
> pulumi up
Just like the first time you will see a preview of the changes before they happen:
Previewing update (dev):
Type Name Plan
pulumi:pulumi:Stack quickstart-dev
+ ├─ azure-native:storage:StorageAccountStaticWebsite staticWebsite create
+ └─ azure-native:storage:Blob index.html create
Outputs:
+ staticEndpoint : "https://sa8dd8af62.z22.web.core.windows.net/"
Resources:
+ 2 to create
3 unchanged
Do you want to perform this update?
> yes
no
details
Choose yes to perform the deployment:
Do you want to perform this update? yes
Updating (dev):
Type Name Status
pulumi:pulumi:Stack quickstart-dev
+ ├─ azure-native:storage:StorageAccountStaticWebsite staticWebsite created
+ └─ azure-native:storage:Blob index.html created
Outputs:
storageAccountName: "sa8deefa78"
+ staticEndpoint : "https://sa8dd8af62.z22.web.core.windows.net/"
Resources:
+ 2 created
3 unchanged
Duration: 4s
In just a few seconds, your new website will be ready. Curl the endpoint to see it live:
$ curl $(pulumi stack output staticEndpoint)
> curl (pulumi stack output staticEndpoint)
This will reveal your new website!
<html>
<body>
<h1>Hello, Pulumi!</h1>
</body>
</html>
Feel free to experiment, such as changing the contents of index.html and redeploying.
Next, wrap the website into an infrastructure abstraction.
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.
