Azure bicep Storage Account loop blobs error - azure

I have this script to loop over an array of storage account and create them with some default configurations.
param storageAccounts array = [
'storage2312'
'storage2we1'
]
resource storage_Accounts 'Microsoft.Storage/storageAccounts#2021-04-01' = [ for storageName in storageAccounts :{
name: storageName
location: 'westeurope'
sku: {
name: 'Standard_RAGRS'
}
kind: 'StorageV2'
properties: {
allowCrossTenantReplication: true
minimumTlsVersion: 'TLS1_2'
allowBlobPublicAccess: false
allowSharedKeyAccess: true
networkAcls: {
bypass: 'AzureServices'
virtualNetworkRules: []
ipRules: []
defaultAction: 'Allow'
}
supportsHttpsTrafficOnly: true
encryption: {
services: {
file: {
keyType: 'Account'
enabled: true
}
blob: {
keyType: 'Account'
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
accessTier: 'Hot'
}
}]
resource storage_Accounts_name_default 'Microsoft.Storage/storageAccounts/blobServices#2021-04-01' = [ for (storageName, i) in storageAccounts :{
parent: storage_Accounts[i]
name: storageName
properties: {
changeFeed: {
enabled: false
}
restorePolicy: {
enabled: false
}
containerDeleteRetentionPolicy: {
enabled: true
days: 7
}
cors: {
corsRules: []
}
deleteRetentionPolicy: {
enabled: true
days: 30
}
isVersioningEnabled: true
}
}]
The scripts works just fine and the storage accounts get created but the script at the end throws the following error:
{"status":"Failed","error":{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"NotFound","message":"{\r\n \"error\": {\r\n \"code\": \"HttpResourceNotFound\",\r\n \"message\": \"The request url resourcegroups/storageAccounts/providers/Microsoft.Storage/storageAccounts/storage2we1/blobServices/storage2we1?api-version=2021-04-01 is not found.\"\r\n }\r\n}"},{"code":"NotFound","message":"{\r\n \"error\": {\r\n \"code\": \"HttpResourceNotFound\",\r\n \"message\": \"The request url /resourcegroups/storageAccounts/providers/Microsoft.Storage/storageAccounts/storage2312/blobServices/storage2312?api-version=2021-04-01 is not found.\"\r\n }\r\n}"}]}}
When create a storage account manually, I have as a default container the $logs but when I run the script, and the storage account get created, under container I don't have anything, which I presume that the error is due to that.
With bicep do I have to declare the default container?
Any help and explanation would be most welcome.
thank you so much

Based on the sample provided here, please change the following line of code (in your 2nd snippet where you're configuring blob service) from:
name: storageName
to
name: 'default'
So effectively, your bicep template would be something like:
param storageAccounts array = [
'storage2'
]
resource storage_Accounts 'Microsoft.Storage/storageAccounts#2021-04-01' = [ for storageName in storageAccounts :{
name: storageName
location: 'westeurope'
sku: {
name: 'Standard_RAGRS'
tier: 'Standard'
}
kind: 'StorageV2'
properties: {
allowCrossTenantReplication: true
minimumTlsVersion: 'TLS1_2'
allowBlobPublicAccess: false
allowSharedKeyAccess: true
networkAcls: {
bypass: 'AzureServices'
virtualNetworkRules: []
ipRules: []
defaultAction: 'Allow'
}
supportsHttpsTrafficOnly: true
encryption: {
services: {
file: {
keyType: 'Account'
enabled: true
}
blob: {
keyType: 'Account'
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
accessTier: 'Hot'
}
}]
resource storage_Accounts_name_default 'Microsoft.Storage/storageAccounts/blobServices#2021-04-01' = [ for (storageName, i) in storageAccounts :{
parent: storage_Accounts[i]
name: 'default'
properties: {
changeFeed: {
enabled: false
}
restorePolicy: {
enabled: false
}
containerDeleteRetentionPolicy: {
enabled: true
days: 7
}
cors: {
corsRules: []
}
deleteRetentionPolicy: {
enabled: true
days: 30
}
isVersioningEnabled: true
}
}]

Here is alternative solution with more generics
Definition of the containers to create
var containerNames = [
'web'
'blob'
'test'
]
Next we need definiton of the storage account
resource storageAccount 'Microsoft.Storage/storageAccounts#2022-09-01' = {
name: replace(storageName, '-', '')
location: location
kind:'StorageV2'
sku:{
name: skuName
}
properties: {
minimumTlsVersion:'TLS1_2'
accessTier: 'Cool'
allowBlobPublicAccess: true
networkAcls:{
bypass:'AzureServices'
defaultAction:'Allow'
virtualNetworkRules:[]
}
supportsHttpsTrafficOnly: true
}
}
then we need to define the containers using composition
resource newContainers 'Microsoft.Storage/storageAccounts/blobServices/containers#2022-09-01' = [for containerName in containerNames:{
name:'${storageAccount.name}/default/${containerName}'
dependsOn: [storageAccount]
properties:{
publicAccess:'None'
}
}]
Couple things to note:
this solution is not sanitized for invalid input
names are case sensitive for storage account
make sure you test the code

Related

Azure App Service Bicep template with deployment slot

Here is my bicep template to deploy App service. Need help to add a slot with name: 'staging' (settings to be cloned from parent)
resource appServicePlan 'Microsoft.Web/serverfarms#2020-06-01' = {
name: appServicePlanName
location: location
properties: {
reserved: true
}
sku: {
name: sku
}
kind: 'linux'
}
resource appService 'Microsoft.Web/sites#2020-06-01' = {
name: webAppName
location: location
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: linuxFxVersion
}
}
}
You are looking for the Microsoft.Web sites/slots resource. Here a minimal example:
resource stagingSlot 'Microsoft.Web/sites/slots#2021-02-01' = {
name: 'staging'
parent: yourparent
location: location
kind: 'app'
properties: {
serverFarmId: appService.id
}
}

Create a resource ONLY IF that does not exist

I have the following bicep file to create an Azure Function App with a staging slot:
module functionAppTemplate 'functionApp.bicep' = {
name: 'functionAppTemplate'
params: {
name: '${functionAppName}'
kind: functionAppKind
location: location
servicePlanName: servicePlanName
secretSettings: union(appSettings, productionSettings)
}
dependsOn: [
servicePlanTemplate
]
}
module functionAppSlotTemplate 'functionAppSlot.bicep' = {
name: 'functionAppSlotTemplate'
params: {
name: '${functionAppName}/staging'
kind: functionAppKind
location: location
servicePlanName: servicePlanName
secretSettings: union(appSettings, stagingSettings)
}
dependsOn: [
functionAppTemplate
]
}
functionApp.bicep
resource functionApp 'Microsoft.Web/sites#2018-02-01' = {
name: name
location: location
kind: kind
properties: {
serverFarmId: resourceId('Microsoft.Web/serverfarms', servicePlanName)
clientAffinityEnabled: false
httpsOnly: true
siteConfig: {
use32BitWorkerProcess : false
appSettings: secretSettings
}
}
identity: {
type: 'SystemAssigned'
}
}
functionAppSlot.bicep
resource functionAppSlot 'Microsoft.Web/sites/slots#2018-11-01' = {
name: name
kind: kind
location: location
properties: {
clientAffinityEnabled: true
enabled: true
httpsOnly: true
serverFarmId: resourceId('Microsoft.Web/serverfarms', servicePlanName)
siteConfig: {
use32BitWorkerProcess : false
appSettings: secretSettings
}
}
identity: {
type: 'SystemAssigned'
}
}
Is there a way to run functionApp.bicep and create Function App resource ONLY IF that resource doesn't exist?

How to make my cloud run service public (Allow unauthenticated invocations) using googleapi node.js?

My script deploys a cloud run service, but after several hours of search i can't find the option to make the service public available.
const auth = new google.auth.GoogleAuth({
keyFile: 'path/to/keyfile.json',
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
});
const authClient = await auth.getClient();
const run = google.run({
version: 'v1',
auth: authClient,
rootUrl: 'https://europe-west6-run.googleapis.com/'
});
const response = await run.namespaces.services.create({
parent: 'namespaces/pace21',
requestBody: {
metadata: {
name: 'my-new-service',
namespace: 'myProject',
annotations: {
'run.googleapis.com/ingress': 'all',
},
},
kind: 'Service',
apiVersion: 'serving.knative.dev/v1',
spec: {
template: {
spec: {
containers: [
{
image: 'europe-west6-docker.pkg.dev/path/to/image',
}
]
}
},
traffic: [{ percent: 100, latestRevision: true }]
}
}
}, {})
I can see an option in the package but I don't know how to apply it.
Thanks #JohnHanley.
The second request to change the policy of the new service is the answer I was searching for. For completion the node script:
const policy_response = await run.projects.locations.services.setIamPolicy({
resource: `projects/${project_id}/locations/europe-west6/services/${service_name}`,
requestBody: {
policy: {
bindings: [
{
role: 'roles/run.invoker',
members: [
'allUsers',
],
},
],
},
},
});

Setup #semantic-release for considering 'refactor' commits in the CHANGELOG

Using #semantic-release I'd like to consider refactor changes for both, triggering a new release and write down in the CHANGELOG.md file.
So far, I've included refactor commits at "#semantic-release/commit-analyzer" so they are triggering a patch release:
[
"#semantic-release/commit-analyzer",
{
"preset": "angular",
"releaseRules": [
{
"type": "refactor",
"release": "patch"
}
]
}
],
But those commit msgs aren't included in the CHANGELOG file, how can I setup "#semantic-release/release-notes-generator" plugin for including refactor commits? I find related doc confusing and lack of examples
generated CHANGELOG example
## [0.6.4](.../compare/v0.6.3...v0.6.4) (date)
## [0.6.3](.../compare/v0.6.2...v0.6.3) (date)
desired CHANGELOG
## [0.6.4](.../compare/v0.6.3...v0.6.4) (date)
[[>>INCLUDE HERE COMMIT MSG + LINK<<]]
## [0.6.3](.../compare/v0.6.2...v0.6.3) (date)
If anyone finds this useful: we need to config "#semantic-release/release-notes-generator" for considering other keywords besides feat and fix including these dicts:
{
"type": "refactor",
"section": "title to be used in changelog.md",
"hidden": false
}
For copy-pasting, this setup is gathering both refactor, chore and perf into ## Internal section (note i needed to write explicitly default values, I guess this is because it's overriding the config)
[
"#semantic-release/release-notes-generator",
{
"preset": "conventionalCommits",
"parserOpts": {
"noteKeywords": [
"BREAKING CHANGE",
"BREAKING CHANGES",
"BREAKING"
]
},
"presetConfig": {
"types": [
{
"type": "feat",
"section": "Features"
},
{
"type": "fix",
"section": "Bug Fixes"
},
{
"type": "chore",
"section": "Internal",
"hidden": false
},
{
"type": "refactor",
"section": "Internal",
"hidden": false
},
{
"type": "perf",
"section": "Internal",
"hidden": false
}
]
}
}
]
The above answer is correct, but I feel its a bit incomplete. Even after adding the above commit types, the release will not be triggered on all the commit types. If you wish to trigger the release on all or selected commit types (ex. refactor, docs ci etc.) you can use the configuration as below:
// release.config.js
module.exports = {
plugins: [
[
'#semantic-release/commit-analyzer',
{
preset: 'conventionalCommits',
releaseRules: [
{ type: 'revert', scope: '*', release: 'patch' },
{ type: 'docs', scope: '*', release: 'patch' },
{ type: 'style', scope: '*', release: 'patch' },
{ type: 'chore', scope: '*', release: 'patch' },
{ type: 'refactor', scope: '*', release: 'patch' },
{ type: 'test', scope: '*', release: 'patch' },
{ type: 'build', scope: '*', release: 'patch' },
{ type: 'ci', scope: '*', release: 'patch' },
{ type: 'improvement', scope: '*', release: 'patch' },
],
},
],
[
'#semantic-release/release-notes-generator',
{
preset: 'conventionalCommits',
presetConfig: {
types: [
{ type: 'feat', section: 'Features' },
{ type: 'fix', section: 'Bug Fixes' },
{ type: 'perf', section: 'Performance Improvements' },
{ type: 'revert', section: 'Reverts' },
{ type: 'docs', section: 'Documentation', hidden: false },
{ type: 'style', section: 'Styles', hidden: false },
{ type: 'chore', section: 'Miscellaneous Chores', hidden: false },
{ type: 'refactor', section: 'Code Refactors', hidden: false },
{ type: 'test', section: 'Tests', hidden: false },
{ type: 'build', section: 'Build System', hidden: false },
{ type: 'ci', section: 'CI/CD', hidden: false },
{ type: 'improvement', section: 'Improvements', hidden: false },
],
},
},
],
['#semantic-release/github'],
[
'#semantic-release/npm',
{
npmPublish: false,
},
],
'#semantic-release/changelog',
'#semantic-release/git',
],
branch: 'master',
};
Working of the above config:
#semantic-release/commit-analyzer will trigger the release for feat, fix & BREAKING CHANGE as usual. I've only added the rest of the types that are ignored by default. Needless to say that they will be considered as patches and will only bump the patch number from semantic versioning in your tags, release notes, changelog & package.json file.
#semantic-release/release-notes-generator will just make sure that the commits are grouped correctly based on the type and will display my custom headings defined with the section key.
Hope this helps someone in future!

fs.writeFileSync - write JSON to file always writes a empty object

i create a json-object and want to write this down to a json-file, but the object is always empty (?)
fs.writeFileSync(__dirname + '/myNewFile.json', JSON.stringify(myObjects));
the content of the written file is now []
fs.writeFileSync(__dirname + '/myNewFile.json', JSON.stringify({bla: myObjects}));
the content of the file is now {"bla":[]}
I doublecheck myObjects and it is not empty.. it is a array with some objects in it.
why is that? what am I doing wrong?
EDIT:
this is the content of myObjects:
[ struct: { id: 'struct',
name: 'Struktur',
icon: 'fa fa-bullseye',
properties: [] },
mp: { id: 'mp',
name: 'Messpunkt',
icon: 'fa fa-circle',
properties: [] },
'356899e5-d8b0-41aa-b7cd-de2135c5a3db': { id: '356899e5-d8b0-41aa-b7cd-de2135c5a3db',
name: 'Untermessung',
icon: 'fa fa-tachometer',
properties: [] },
'8d824cfd-584f-40e9-b9fa-78d7fedcc727': { id: '8d824cfd-584f-40e9-b9fa-78d7fedcc727',
name: 'Kommune',
icon: 'fa fa-thumb-tack',
properties: [] },
'2609b2ac-77aa-42f2-af22-d49fcfc6f0f0': { id: '2609b2ac-77aa-42f2-af22-d49fcfc6f0f0',
name: 'Bereiche',
icon: 'fa fa-circle',
properties: [] },
'a4ac2e52-da95-412f-b431-499f2eff64da': { id: 'a4ac2e52-da95-412f-b431-499f2eff64da',
name: 'Gebäude',
icon: 'fa fa-industry',
properties: [ [Object], [Object] ] } ]

Resources