Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/bicep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Bicep

on:
pull_request:
push:
branches: ["main"]

env:
CLASS_RG: rg-hyf-students

jobs:
what-if:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Preview deployment
run: |
az deployment group what-if \
--resource-group "$CLASS_RG" \
--template-file main.bicep \
--parameters \
storageName=sthyfhalyna \
environment=dev \
dbAdminPassword=not-a-real-secret

deploy:
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Apply deployment
run: |
az deployment group create \
--resource-group "$CLASS_RG" \
--template-file main.bicep \
--parameters \
storageName=sthyfhalyna \
environment=dev \
dbAdminPassword=not-a-real-secret
19 changes: 16 additions & 3 deletions AI_ASSIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,25 @@

## Prompt

<!-- The prompt you gave an LLM, or write: I did not use an LLM. -->
I asked an LLM to explain how to pass an `environment` parameter from `main.bicep` to a storage module, how to use that parameter as an Azure resource tag, and how to declare a second nested blob container under the same storage account.

## Model output

<!-- What it returned (short summary is fine). -->
The model explained that the `environment` parameter should be declared in `main.bicep`, passed through the module `params` block, and declared again in `modules/storage.bicep`.

It also suggested using the parameter in the storage account tags and adding `curated` as a second child container under the existing default blob service.

## What I changed or verified

<!-- What you checked with what-if / the portal / the docs before deploying. -->
I reviewed the suggested structure against the assignment instructions and the existing starter files.

I verified that:

- the original module structure was preserved;
- the `environment` value is passed correctly into the module;
- the storage account receives the `Environment` tag;
- both `raw` and `curated` are child resources of the default blob service;
- the existing `@secure()` parameter remains in place;
- no real passwords, credentials, keys, or connection strings are committed.

I then ran the local assignment tests and used Azure CLI commands myself to perform the deployment and `what-if` checks. I also verified the storage account and both containers in the Azure portal.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Week 14 Assignment: Infrastructure as Code (Bicep)

**Student:** Halyna Romanyshyn

Extend a Chapter 4–complete Bicep starter (storage account + nested `raw`
container) with an environment tag and a second `curated` container, then
deploy, preview with `what-if`, confirm in the portal, and write it up.
Expand Down
5 changes: 3 additions & 2 deletions WRITEUP.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Write-up

<!-- Half a page for a teammate: what you deployed, naming/parameter/module
decisions, and why code beats portal clicks. -->
I extended the existing Bicep starter instead of rebuilding it from an empty file. The main template now has an `environment` parameter with the values `dev` and `prod`. This value is passed to the storage module and becomes the `Environment` tag on the storage account. The same Bicep files can therefore describe different environments without copying the infrastructure code.

The storage module still creates the original nested `raw` container and now also creates a second nested container named `curated`. The `raw` container can hold data as it first arrives, while `curated` can hold data that has been cleaned or prepared for further use. Both containers use the default blob service and `parent:` so Azure understands their relationship to the storage account.
122 changes: 120 additions & 2 deletions docs/deploy_succeeded.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,120 @@
<!-- Paste the az deployment group create JSON/text output here.
It must show provisioningState: Succeeded. -->
{
"id": "/subscriptions/1120c89d-2a5f-4a15-a582-2ea34f0bb5c3/resourceGroups/rg-hyf-students/providers/Microsoft.Resources/deployments/week14-halyna-dev",
"location": null,
"name": "week14-halyna-dev",
"properties": {
"correlationId": "3cbb08d5-96bc-46e1-912a-5c4285c2bc05",
"debugSetting": null,
"dependencies": [],
"diagnostics": null,
"duration": "PT8.9628026S",
"error": null,
"extensions": [],
"mode": "Incremental",
"onErrorDeployment": null,
"outputResources": [
{
"apiVersion": null,
"extension": null,
"id": "/subscriptions/1120c89d-2a5f-4a15-a582-2ea34f0bb5c3/resourceGroups/rg-hyf-students/providers/Microsoft.Storage/storageAccounts/sthyfhalyna",
"identifiers": null,
"resourceGroup": "rg-hyf-students",
"resourceType": "Microsoft.Storage/storageAccounts"
},
{
"apiVersion": null,
"extension": null,
"id": "/subscriptions/1120c89d-2a5f-4a15-a582-2ea34f0bb5c3/resourceGroups/rg-hyf-students/providers/Microsoft.Storage/storageAccounts/sthyfhalyna/blobServices/default",
"identifiers": null,
"resourceGroup": "rg-hyf-students",
"resourceType": "Microsoft.Storage/storageAccounts/blobServices"
},
{
"apiVersion": null,
"extension": null,
"id": "/subscriptions/1120c89d-2a5f-4a15-a582-2ea34f0bb5c3/resourceGroups/rg-hyf-students/providers/Microsoft.Storage/storageAccounts/sthyfhalyna/blobServices/default/containers/curated",
"identifiers": null,
"resourceGroup": "rg-hyf-students",
"resourceType": "Microsoft.Storage/storageAccounts/blobServices/containers"
},
{
"apiVersion": null,
"extension": null,
"id": "/subscriptions/1120c89d-2a5f-4a15-a582-2ea34f0bb5c3/resourceGroups/rg-hyf-students/providers/Microsoft.Storage/storageAccounts/sthyfhalyna/blobServices/default/containers/raw",
"identifiers": null,
"resourceGroup": "rg-hyf-students",
"resourceType": "Microsoft.Storage/storageAccounts/blobServices/containers"
}
],
"outputs": {
"curatedContainerName": {
"type": "String",
"value": "curated"
},
"rawContainerName": {
"type": "String",
"value": "raw"
},
"storageId": {
"type": "String",
"value": "/subscriptions/1120c89d-2a5f-4a15-a582-2ea34f0bb5c3/resourceGroups/rg-hyf-students/providers/Microsoft.Storage/storageAccounts/sthyfhalyna"
}
},
"parameters": {
"containerName": {
"type": "String",
"value": "raw"
},
"dbAdminPassword": {
"type": "SecureString"
},
"environment": {
"type": "String",
"value": "dev"
},
"location": {
"type": "String",
"value": "westeurope"
},
"storageName": {
"type": "String",
"value": "sthyfhalyna"
}
},
"parametersLink": null,
"providers": [
{
"id": null,
"namespace": "Microsoft.Resources",
"providerAuthorizationConsentState": null,
"registrationPolicy": null,
"registrationState": null,
"resourceTypes": [
{
"aliases": null,
"apiProfiles": null,
"apiVersions": null,
"capabilities": null,
"defaultApiVersion": null,
"locationMappings": null,
"locations": [
null
],
"properties": null,
"resourceType": "deployments",
"zoneMappings": null
}
]
}
],
"provisioningState": "Succeeded",
"templateHash": "14701220362417228026",
"templateLink": null,
"timestamp": "2026-08-03T21:21:50.625432+00:00",
"validatedResources": null,
"validationLevel": null
},
"resourceGroup": "rg-hyf-students",
"tags": null,
"type": "Microsoft.Resources/deployments"
}
13 changes: 8 additions & 5 deletions docs/portal_confirm.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Portal confirmation

<!-- Two or three sentences: resource names you saw in $CLASS_RG, and that the
Deployments blade showed Succeeded. Do not paste secrets. -->
I confirmed storage account `sthyfhalyna` in resource group `rg-hyf-students`. Under Data storage → Containers, both `raw` and `curated` were present. The Deployments page showed the `week14-halyna-dev` deployment with status Succeeded.

<!-- Task 3 step 4: after you capture the evidence above, tear down and record it here,
e.g. `Teardown: deleted sthyf<yourname> (and both containers) on 2026-08-14.`
If your role blocked the delete, say so and name who you asked. -->
Screenshots:

- `screenshots/storage_account_confirm.png`
- `screenshots/containers_raw_curated_confirm.png`
- `screenshots/deployment_succeeded_confirm.png`

Teardown: deleted `sthyfhalyna` and its nested containers on 2026-08-04.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/storage_account_confirm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 40 additions & 1 deletion docs/what_if.txt
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
<!-- Paste the az deployment group what-if output here. -->
Note: The result may contain false positive predictions (noise).
You can help us improve the accuracy of the result by opening an issue here: https://aka.ms/WhatIfIssues

Resource and property changes are indicated with these symbols:
- Delete
~ Modify
* Ignore

The deployment will update the following scope:

Scope: /subscriptions/1120c89d-2a5f-4a15-a582-2ea34f0bb5c3/resourceGroups/rg-hyf-students

~ Microsoft.Storage/storageAccounts/sthyfhalyna [2023-01-01]
~ tags.environment: "dev" => "prod"

~ Microsoft.Storage/storageAccounts/sthyfhalyna/blobServices/default [2023-01-01]
- properties:

deleteRetentionPolicy.allowPermanentDelete: false
deleteRetentionPolicy.enabled: false


~ Microsoft.Storage/storageAccounts/sthyfhalyna/blobServices/default/containers/curated [2023-01-01]
- properties.defaultEncryptionScope: "$account-encryption-key"
- properties.denyEncryptionScopeOverride: false

~ Microsoft.Storage/storageAccounts/sthyfhalyna/blobServices/default/containers/raw [2023-01-01]
- properties.defaultEncryptionScope: "$account-encryption-key"
- properties.denyEncryptionScopeOverride: false

* Microsoft.Storage/storageAccounts/sthyfbader
* Microsoft.Storage/storageAccounts/sthyfbaraah
* Microsoft.Storage/storageAccounts/sthyfhannah
* Microsoft.Storage/storageAccounts/sthyfimper0802
* Microsoft.Storage/storageAccounts/sthyflasseb
* Microsoft.Storage/storageAccounts/sthyfmohammedalfakih
* Microsoft.Storage/storageAccounts/sthyfpavel
* Microsoft.Storage/storageAccounts/sthyfw14lab

Resource changes: 4 to modify, 8 to ignore.
9 changes: 9 additions & 0 deletions main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ param location string = resourceGroup().location
param storageName string
param containerName string = 'raw'

@allowed([
'dev'
'prod'
])
param environment string = 'dev'

// Dummy unused secret for hygiene practice — pass at deploy time, never commit the value
@secure()
param dbAdminPassword string
Expand All @@ -22,7 +28,10 @@ module storage 'modules/storage.bicep' = {
location: location
storageName: storageName
containerName: containerName
environment: environment
}
}

output storageId string = storage.outputs.storageId
output rawContainerName string = storage.outputs.rawContainerName
output curatedContainerName string = storage.outputs.curatedContainerName
23 changes: 21 additions & 2 deletions modules/storage.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@
param location string
param storageName string
param containerName string = 'raw'
param environment string

resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageName
location: location
sku: { name: 'Standard_LRS' }

tags: {
environment: environment
}

sku: {
name: 'Standard_LRS'
}

kind: 'StorageV2'
}

Expand All @@ -18,12 +27,22 @@ resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2023-01-01'
name: 'default'
}

resource container 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
resource rawcontainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
parent: blobService
name: containerName
properties: {
publicAccess: 'None'
}
}

resource curatedcontainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
parent: blobService
name: 'curated'
properties: {
publicAccess: 'None'
}
}

output storageId string = storage.id
output rawContainerName string = rawcontainer.name
output curatedContainerName string = curatedcontainer.name
Loading