This commit is contained in:
Bernie White 2021-10-26 00:22:18 +10:00 коммит произвёл GitHub
Родитель 654e19f997
Коммит e261de8f91
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
26 изменённых файлов: 1959 добавлений и 39 удалений

2
.github/CODEOWNERS поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
# https://help.github.com/articles/about-codeowners/
* @azure/psrule-rules-azure

10
.github/PULL_REQUEST_TEMPLATE.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
## PR Summary
<!-- summarize your PR between here and the checklist -->
## PR Checklist
- [ ] PR has a meaningful title
- [ ] Summarized changes
- [ ] Change is not breaking
- [ ] This PR is ready to merge and is not **Work in Progress**

15
.github/dependabot.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,15 @@
#
# Dependabot configuration
#
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'daily'

39
.github/workflows/azure-analyze.yaml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,39 @@
#
# Analyze repository with PSRule for Azure
#
# Note:
# This workflow is designed to run in templated repositories.
# For PSRule for Azure documentation see:
# https://aka.ms/ps-rule-azure
# For action details see:
# https://aka.ms/ps-rule-action
name: Analyze Azure resources
# Run for main or PRs against main
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
jobs:
analyze:
name: Analyze repository
runs-on: ubuntu-latest
if: github.repository != 'Azure/PSRule.Rules.Azure-quickstart'
steps:
- name: Checkout
uses: actions/checkout@v2.3.5
- name: Run PSRule analysis
uses: Microsoft/ps-rule@v1.9.0
with:
modules: 'PSRule.Rules.Azure'

38
.github/workflows/ms-analyze.yaml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,38 @@
#
# Analyze repository with PSRule
#
# Note:
# This workflow is designed to run only in Azure/PSRule.Rules.Azure-quickstart.
# You can safely deleted this file if you have templated this repository to your GitHub organization.
# For PSRule documentation see:
# https://aka.ms/ps-rule
# For action details see:
# https://aka.ms/ps-rule-action
name: Analyze repository
# Run for main or PRs against main
on:
pull_request:
branches:
- main
workflow_dispatch:
jobs:
analyze:
name: Analyze repository
runs-on: ubuntu-latest
if: github.repository == 'Azure/PSRule.Rules.Azure-quickstart'
steps:
- name: Checkout
uses: actions/checkout@v2.3.5
- name: Run PSRule analysis
uses: Microsoft/ps-rule@main
with:
modules: PSRule.Rules.MSFT.OSS
prerelease: true

4
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,4 @@
reports/
out/
.vs/

67
.markdownlint.json Normal file
Просмотреть файл

@ -0,0 +1,67 @@
{
"default": true,
"header-increment": true,
"first-header-h1": {
"level": 1
},
"header-style": {
"style": "atx"
},
"ul-style": {
"style": "dash"
},
"list-indent": true,
"ul-start-left": true,
"ul-indent": {
"indent": 2
},
"no-trailing-spaces": true,
"no-hard-tabs": true,
"no-reversed-links": true,
"no-multiple-blanks": true,
"line-length": {
"line_length": 100,
"code_blocks": false,
"tables": false,
"headers": true
},
"commands-show-output": true,
"no-missing-space-atx": true,
"no-multiple-space-atx": true,
"no-missing-space-closed-atx": true,
"no-multiple-space-closed-atx": true,
"blanks-around-headers": true,
"header-start-left": true,
"no-duplicate-header": true,
"single-h1": true,
"no-trailing-punctuation": {
"punctuation": ".,;:!"
},
"no-multiple-space-blockquote": true,
"no-blanks-blockquote": true,
"ol-prefix": {
"style": "one_or_ordered"
},
"list-marker-space": true,
"blanks-around-fences": true,
"blanks-around-lists": true,
"no-bare-urls": true,
"hr-style": {
"style": "---"
},
"no-emphasis-as-header": true,
"no-space-in-emphasis": true,
"no-space-in-code": true,
"no-space-in-links": true,
"fenced-code-language": false,
"first-line-h1": false,
"no-empty-links": true,
"proper-names": {
"names": [
"PowerShell",
"JavaScript"
],
"code_blocks": false
},
"no-alt-text": true
}

12
.ps-rule/Org.Rule.ps1 Normal file
Просмотреть файл

@ -0,0 +1,12 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Note:
# This script demonstrates using PowerShell based rules.
# Synopsis: Policy exemptions must be approved by the security team and stored within deployments/contoso/landing-zones/subscription-1/policy/.
Rule 'Org.CodeOwners' -Type 'Microsoft.Authorization/policyExemptions' {
$Assert.WithinPath($PSRule.Source['Parameter'], 'File', @(
'deployments/contoso/landing-zones/subscription-1/policy/'
));
}

33
.ps-rule/Org.Rule.yaml Normal file
Просмотреть файл

@ -0,0 +1,33 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Note:
# This files demonstrates using PowerShell based rules.
---
# Synopsis: Azure resource must have an valid env tag set.
apiVersion: github.com/microsoft/PSRule/v1
kind: Rule
metadata:
name: Org.Azure.Tags
spec:
with:
- 'Org.Azure.Resources'
condition:
allOf:
- in:
- 'prod'
- 'test'
- 'dev'
field: 'tags.env'
---
# Synopsis: Select all Azure resources.
apiVersion: github.com/microsoft/PSRule/v1
kind: Selector
metadata:
name: Org.Azure.Resources
spec:
if:
field: type
match: Microsoft\.\w+\/.+

7
.vscode/extensions.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,7 @@
{
"recommendations": [
"bewhite.psrule-vscode-preview",
"msazurermtools.azurerm-vscode-tools",
"ms-azuretools.vscode-bicep"
]
}

19
.vscode/tasks.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,19 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "PSRule",
"problemMatcher": [
"$PSRule"
],
"label": "PSRule: Run analysis",
"presentation": {
"focus": false,
"panel": "dedicated",
"clear": true
}
}
]
}

68
CONTRIBUTING.md Normal file
Просмотреть файл

@ -0,0 +1,68 @@
# Contributing to PSRule for Azure
Welcome, and thank you for your interest in contributing to PSRule!
There are many ways in which you can contribute, beyond writing code.
The goal of this document is to provide a high-level overview of how you can get involved.
- [Reporting issues](#reporting-issues)
- Improve documentation
- Fix bugs or add features
## Contributor License Agreement (CLA)
This project welcomes contributions and suggestions. Most contributions require you to
agree to a Contributor License Agreement (CLA) declaring that you have the right to,
and actually do, grant us the rights to use your contribution. For details, visit
https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need
to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Reporting issues
Have you identified a reproducible problem?
Have a feature request?
We want to hear about it!
Here's how you can make reporting your issue as effective as possible.
### Look for an existing issue
Before you create a new issue, please do a search in [open issues][issues] to see if the issue or feature request has already been filed.
If you find your issue already exists,
make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments).
Use a reaction in place of a "+1" comment:
* 👍 - upvote
### Intro to Git and GitHub
When contributing to documentation or code changes, you'll need to have a GitHub account and a basic understanding of Git.
Check out the links below to get started.
- Make sure you have a [GitHub account][github-signup].
- GitHub Help:
- [Git and GitHub learning resources][learn-git].
- [GitHub Flow Guide][github-flow].
- [Fork a repo][github-fork].
- [About Pull Requests][github-pr].
## Thank You!
Your contributions to open source, large or small, make great projects like this possible.
Thank you for taking the time to contribute.
[learn-git]: https://help.github.com/en/articles/git-and-github-learning-resources
[github-flow]: https://guides.github.com/introduction/flow/
[github-signup]: https://github.com/signup/free
[github-fork]: https://help.github.com/en/github/getting-started-with-github/fork-a-repo
[github-pr]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests
[github-pr-create]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork

Просмотреть файл

@ -1,33 +1,55 @@
# Project
# PSRule for Azure Quick Start
> This repo has been populated by an initial template to help get you started. Please
> make sure to update the content to build a great experience for community-building.
This repository contains a sample template you can use to quickly start using PSRule for Azure.
To learn more about PSRule for Azure, see https://aka.ms/ps-rule-azure.
As the maintainer of this project, please make a few updates:
[![Use this template](https://img.shields.io/static/v1?label=GitHub&message=Use%20this%20template&logo=github&color=007acc)](https://github.com/Azure/PSRule.Rules.Azure-quickstart/generate)
[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/Azure/PSRule.Rules.Azure-quickstart)
- Improving this README.MD file to provide a great experience
- Updating SUPPORT.MD with content about this project's support experience
- Understanding the security reporting process in SECURITY.MD
- Remove this section from the README
## What's included?
This repository includes:
- Starter Azure Resource Manager templates and parameter files.
- Starter Azure Bicep deployments and test files.
- GitHub Actions workflow to check Azure Infrastructure as Code.
## Support
This project uses GitHub Issues to track bugs and feature requests.
Please search the existing issues before filing new issues to avoid duplicates.
- For new issues, file your bug or feature request as a new [issue].
- For help, discussion, and support questions about using this project, join or start a [discussion].
Support for this project/ product is limited to the resources listed above.
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
This project welcomes contributions and suggestions.
If you are ready to contribute, please visit the [contribution guide](CONTRIBUTING.md).
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Maintainers
- [Bernie White](https://github.com/BernieWhite)
- [Armaan Mcleod](https://github.com/ArmaanMcleod)
## License
This project is [licensed under the MIT License](LICENSE).
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
This project may contain trademarks or logos for projects, products, or services.
Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.
[issue]: https://github.com/Azure/PSRule.Rules.Azure-quickstart/issues
[discussion]: https://github.com/Azure/PSRule.Rules.Azure-quickstart/discussions

Просмотреть файл

@ -1,3 +1,5 @@
# Security policy
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
## Security
@ -38,4 +40,4 @@ We prefer all communications to be in English.
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->
<!-- END MICROSOFT SECURITY.MD BLOCK -->

Просмотреть файл

@ -1,25 +1,16 @@
# TODO: The maintainer of this repo has not yet edited this file
**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?
- **No CSS support:** Fill out this template with information about how to file issues and get help.
- **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport).
- **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide.
*Then remove this first heading from this SUPPORT.MD file before publishing your repo.*
# Support
## How to file issues and get help
## How to file issues and get help
This project uses GitHub Issues to track bugs and feature requests. Please search the existing
issues before filing new issues to avoid duplicates. For new issues, file your bug or
feature request as a new Issue.
This project uses GitHub Issues to track bugs and feature requests.
Please search the existing issues before filing new issues to avoid duplicates.
For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
- For new issues, file your bug or feature request as a new [issue].
- For help, discussion, and support questions about using this project, join or start a [discussion].
## Microsoft Support Policy
## Microsoft Support Policy
Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
Support for this project/ product is limited to the resources listed above.
[issue]: https://github.com/Azure/PSRule.Rules.Azure-quickstart/issues
[discussion]: https://github.com/Azure/PSRule.Rules.Azure-quickstart/discussions

Просмотреть файл

@ -0,0 +1,41 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"template": "templates/policy-exemption/v1/template.json"
},
"parameters": {
"exemptionNameSuffix": {
"value": "awesome-app-exemption-001"
},
"assignmentId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyAssignments/SecurityCenterBuiltIn"
},
"resourceGroup": {
"value": "rg-awesome-app-prod-eus-001"
},
"exemptionCategory": {
"value": "Waiver"
},
"description": {
"value": "Allow cognitive services to be public and called directly from mobile workforce. This is a temporary exemption until VPN is implemented."
},
"displayName": {
"value": "001: Temporary public access for Awesome App cognitive services"
},
"requestedBy": {
"value": "Awesome App Team"
},
"approvedBy": {
"value": "Security vTeam"
},
"expiresOnDate": {
"value": "2099-12-28T00:00:00+10:00"
},
"policyDefinitionReferenceIds": {
"value": [
"cognitiveServicesAccountsShouldEnableDataEncryptionWithACustomerManagedKeyMonitoringEffect"
]
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"template": "templates/storage/v2/template.json"
},
"parameters": {
"storageAccountName": {
"value": "st001"
},
"blobSoftDeleteDays": {
"value": 7
},
"sku": {
"value": "Standard_GRS"
},
"tags": {
"value": {
"env": "demo",
"service": "demo"
}
}
}
}

Просмотреть файл

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// Note:
// This Azure Bicep code demonistrates a deployment of one or more modules.
// This file has multiple template errors to show validation.
// An example Storage Account
module storage '../../../../../templates/storage/v2/template.bicep' = {
name: 'storage-deployment'
params: {
storageAccountName: 'st002'
// An env tag is required at a minimum
tags: {
}
}
}
// An example Key Vault
module keyvault '../../../../../templates/keyvault/v2/template.json' = {
name: 'keyvault-deployment'
params: {
// An env tag must be test, dev, or prod
tags: {
env: 'demo'
}
vaultName: 'vault002'
}
}

36
ps-rule.yaml Normal file
Просмотреть файл

@ -0,0 +1,36 @@
#
# PSRule for Azure configuration
#
# Please see the documentation for all configuration options:
# https://aka.ms/ps-rule-azure
binding:
preferTargetInfo: true
targetType:
- type
- resourceType
include:
module:
- PSRule.Rules.Azure
input:
pathIgnore:
- '.vscode/'
- '*.md'
- 'templates/*.bicep'
configuration:
# Enable automatic expansion of Azure parameter files
AZURE_PARAMETER_FILE_EXPANSION: true
# Enable automatic expansion of bicep source files
AZURE_BICEP_FILE_EXPANSION: true
# Suppression ignores rules for a specific Azure resource by name
suppression:
Azure.Storage.UseReplication:
- st002
Azure.Storage.SoftDelete:
- st002

Просмотреть файл

@ -0,0 +1,180 @@
# Key Vault
Create or update a Key Vault.
## Parameters
Parameter name | Required | Description
-------------- | -------- | -----------
vaultName | Yes | The name of the Key Vault.
location | No | The Azure region to deploy to.
accessPolicies | No | The access policies defined for this vault.
useDeployment | No | Determines if Azure can deploy certificates from this Key Vault.
useTemplate | No | Determines if templates can reference secrets from this Key Vault.
useDiskEncryption | No | Determines if this Key Vault can be used for Azure Disk Encryption.
useSoftDelete | No | Determine if soft delete is enabled on this Key Vault.
usePurgeProtection | No | Determine if purge protection is enabled on this Key Vault.
softDeleteDays | No | The number of days to retain soft deleted vaults and vault objects.
useRBAC | No | Determines if access to the objects granted using RBAC. When true, access policies are ignored.
networkAcls | No | The network firewall defined for this vault.
workspaceId | No | The workspace to store audit logs.
tags | Yes | Tags to apply to the resource.
### vaultName
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
The name of the Key Vault.
### location
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The Azure region to deploy to.
- Default value: `[resourceGroup().location]`
### accessPolicies
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The access policies defined for this vault.
### useDeployment
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determines if Azure can deploy certificates from this Key Vault.
- Default value: `True`
### useTemplate
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determines if templates can reference secrets from this Key Vault.
- Default value: `True`
### useDiskEncryption
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determines if this Key Vault can be used for Azure Disk Encryption.
- Default value: `True`
### useSoftDelete
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determine if soft delete is enabled on this Key Vault.
- Default value: `True`
### usePurgeProtection
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determine if purge protection is enabled on this Key Vault.
- Default value: `True`
### softDeleteDays
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The number of days to retain soft deleted vaults and vault objects.
- Default value: `90`
### useRBAC
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determines if access to the objects granted using RBAC. When true, access policies are ignored.
- Default value: `False`
### networkAcls
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The network firewall defined for this vault.
- Default value: `@{defaultAction=Allow; bypass=AzureServices; ipRules=System.Object[]; virtualNetworkRules=System.Object[]}`
### workspaceId
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The workspace to store audit logs.
### tags
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
Tags to apply to the resource.
## Outputs
Name | Type | Description
---- | ---- | -----------
resourceId | string | A unique resource identifier for the Key Vault.
## Snippets
### Parameter file
```json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"template": "templates/keyvault/v2/template.json"
},
"parameters": {
"vaultName": {
"value": "<name>"
},
"accessPolicies": {
"value": [
{
"objectId": "<object_id>",
"tenantId": "<tenant_id>",
"permissions": {
"secrets": [
"Get",
"List",
"Set"
]
}
}
]
},
"softDeleteDays": {
"value": 90
},
"useRBAC": {
"value": false
},
"networkAcls": {
"value": {
"defaultAction": "Allow",
"bypass": "AzureServices",
"ipRules": [],
"virtualNetworkRules": []
}
},
"workspaceId": {
"value": "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.OperationalInsights/workspaces/<workspace_name>"
},
"tags": {
"value": {
"service": "<service_name>",
"env": "prod"
}
}
}
}
```

Просмотреть файл

@ -0,0 +1,192 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "2.0.0.0",
"metadata": {
"name": "Key Vault",
"description": "Create or update a Key Vault."
},
"parameters": {
"vaultName": {
"type": "string",
"metadata": {
"description": "The name of the Key Vault.",
"example": "<name>"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The Azure region to deploy to.",
"strongType": "location",
"example": "eastus",
"ignore": true
}
},
"accessPolicies": {
"type": "array",
"defaultValue": [],
"metadata": {
"description": "The access policies defined for this vault.",
"example": [
{
"objectId": "<object_id>",
"tenantId": "<tenant_id>",
"permissions": {
"secrets": [
"Get",
"List",
"Set"
]
}
}
]
}
},
"useDeployment": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Determines if Azure can deploy certificates from this Key Vault.",
"ignore": true
}
},
"useTemplate": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Determines if templates can reference secrets from this Key Vault.",
"ignore": true
}
},
"useDiskEncryption": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Determines if this Key Vault can be used for Azure Disk Encryption.",
"ignore": true
}
},
"useSoftDelete": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Determine if soft delete is enabled on this Key Vault.",
"ignore": true
}
},
"usePurgeProtection": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Determine if purge protection is enabled on this Key Vault.",
"ignore": true
}
},
"softDeleteDays": {
"type": "int",
"defaultValue": 90,
"minValue": 7,
"maxValue": 90,
"metadata": {
"description": "The number of days to retain soft deleted vaults and vault objects."
}
},
"useRBAC": {
"type": "bool",
"defaultValue": false,
"metadata": {
"description": "Determines if access to the objects granted using RBAC. When true, access policies are ignored."
}
},
"networkAcls": {
"type": "object",
"defaultValue": {
"defaultAction": "Allow",
"bypass": "AzureServices",
"ipRules": [],
"virtualNetworkRules": []
},
"metadata": {
"description": "The network firewall defined for this vault."
}
},
"workspaceId": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "The workspace to store audit logs.",
"strongType": "Microsoft.OperationalInsights/workspaces",
"example": "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.OperationalInsights/workspaces/<workspace_name>"
}
},
"tags": {
"type": "object",
"metadata": {
"description": "Tags to apply to the resource.",
"example": {
"service": "<service_name>",
"env": "prod"
}
}
}
},
"resources": [
{
"comments": "Create or update a Key Vault.",
"type": "Microsoft.KeyVault/vaults",
"name": "[parameters('vaultName')]",
"apiVersion": "2019-09-01",
"location": "[parameters('location')]",
"properties": {
"enabledForDeployment": "[parameters('useDeployment')]",
"enabledForTemplateDeployment": "[parameters('useTemplate')]",
"enabledForDiskEncryption": "[parameters('useDiskEncryption')]",
"accessPolicies": "[parameters('accessPolicies')]",
"tenantId": "[subscription().tenantId]",
"sku": {
"name": "Standard",
"family": "A"
},
"networkAcls": "[parameters('networkAcls')]",
"enableSoftDelete": "[parameters('useSoftDelete')]",
"enablePurgeProtection": "[parameters('usePurgeProtection')]",
"softDeleteRetentionInDays": "[parameters('softDeleteDays')]",
"enableRbacAuthorization": "[parameters('useRBAC')]"
},
"tags": "[parameters('tags')]",
"resources": [
{
"comments": "Forward Key Vault audit events to a Log Analytics workspace.",
"condition": "[not(empty(parameters('workspaceId')))]",
"type": "Microsoft.KeyVault/vaults/providers/diagnosticSettings",
"name": "[concat(parameters('vaultName'), '/Microsoft.Insights/service')]",
"apiVersion": "2016-09-01",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.KeyVault/vaults/', parameters('vaultName'))]"
],
"properties": {
"workspaceId": "[parameters('workspaceId')]",
"logs": [
{
"category": "AuditEvent",
"enabled": true
}
]
}
}
]
}
],
"outputs": {
"resourceId": {
"type": "string",
"value": "[resourceId('Microsoft.KeyVault/vaults', parameters('vaultName'))]",
"metadata": {
"description": "A unique resource identifier for the Key Vault."
}
}
}
}

Просмотреть файл

@ -0,0 +1,128 @@
# Policy Exemption
Create or update an Azure Policy exemption for a Resource Group.
## Parameters
Parameter name | Required | Description
-------------- | -------- | -----------
exemptionNameSuffix | Yes | This value will be added as a suffix to the exemption name.
assignmentId | Yes | The resource identifier to the policy assignment that will be exempt.
resourceGroup | No | The name of the Resource Group where the exemption will be scoped.
exemptionCategory | No | The type of exemption.
description | Yes | A description for the policy exemption.
displayName | Yes | The display name of the policy exemption.
requestedBy | Yes | The team that own the resource that the exemption is being created for.
approvedBy | Yes | The team that approved the exemption.
expiresOnDate | Yes | The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption.
policyDefinitionReferenceIds | Yes | An array of definition references that this resource is exempt from.
### exemptionNameSuffix
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
This value will be added as a suffix to the exemption name.
### assignmentId
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
The resource identifier to the policy assignment that will be exempt.
### resourceGroup
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The name of the Resource Group where the exemption will be scoped.
### exemptionCategory
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The type of exemption.
- Default value: `Waiver`
- Allowed values: `Waiver`, `Mitigated`
### description
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
A description for the policy exemption.
### displayName
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
The display name of the policy exemption.
### requestedBy
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
The team that own the resource that the exemption is being created for.
### approvedBy
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
The team that approved the exemption.
### expiresOnDate
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption.
### policyDefinitionReferenceIds
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
An array of definition references that this resource is exempt from.
## Snippets
### Parameter file
```json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"template": "templates/policy-exemption/v1/template.json"
},
"parameters": {
"exemptionNameSuffix": {
"value": ""
},
"assignmentId": {
"value": ""
},
"resourceGroup": {
"value": "<resource_group_name>"
},
"exemptionCategory": {
"value": "Waiver"
},
"description": {
"value": "<description>"
},
"displayName": {
"value": "<display_name>"
},
"requestedBy": {
"value": "<requested_team>"
},
"approvedBy": {
"value": "<approval_team>"
},
"expiresOnDate": {
"value": "2021-04-28T00:00:00+10:00"
},
"policyDefinitionReferenceIds": {
"value": []
}
}
}
```

Просмотреть файл

@ -0,0 +1,127 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"name": "Policy Exemption",
"description": "Create or update an Azure Policy exemption for a Resource Group."
},
"parameters": {
"exemptionNameSuffix": {
"type": "string",
"metadata": {
"description": "This value will be added as a suffix to the exemption name.",
"example": ""
}
},
"assignmentId": {
"type": "string",
"metadata": {
"description": "The resource identifier to the policy assignment that will be exempt."
}
},
"resourceGroup": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "The name of the Resource Group where the exemption will be scoped.",
"example": "<resource_group_name>"
}
},
"exemptionCategory": {
"type": "string",
"defaultValue": "Waiver",
"allowedValues": [
"Waiver",
"Mitigated"
],
"metadata": {
"description": "The type of exemption."
}
},
"description": {
"type": "string",
"metadata": {
"description": "A description for the policy exemption.",
"example": "<description>"
}
},
"displayName": {
"type": "string",
"metadata": {
"description": "The display name of the policy exemption.",
"example": "<display_name>"
}
},
"requestedBy": {
"type": "string",
"metadata": {
"description": "The team that own the resource that the exemption is being created for.",
"example": "<requested_team>"
}
},
"approvedBy": {
"type": "string",
"metadata": {
"description": "The team that approved the exemption.",
"example": "<approval_team>"
}
},
"expiresOnDate": {
"type": "string",
"metadata": {
"description": "The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption.",
"example": "2021-04-28T00:00:00+10:00"
}
},
"policyDefinitionReferenceIds": {
"type": "array",
"metadata": {
"description": "An array of definition references that this resource is exempt from."
}
}
},
"variables": {
"exemptionName": "[concat(subscription().subscriptionId, '-', parameters('exemptionNameSuffix'))]"
},
"resources": [
{
"comments": "Create or update an Azure Policy exemption for a Resource Group.",
"name": "[variables('exemptionName')]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-10-01",
"subscriptionId": "[subscription().subscriptionId]",
"resourceGroup": "[parameters('resourceGroup')]",
"location": "[if(empty(parameters('resourceGroup')), deployment().location, '')]",
"properties": {
"expressionEvaluationOptions": {
"scope": "outer"
},
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "[variables('exemptionName')]",
"type": "Microsoft.Authorization/policyExemptions",
"apiVersion": "2020-07-01-preview",
"properties": {
"policyAssignmentId": "[parameters('assignmentId')]",
"policyDefinitionReferenceIds": "[parameters('policyDefinitionReferenceIds')]",
"exemptionCategory": "[parameters('exemptionCategory')]",
"expiresOn": "[parameters('expiresOnDate')]",
"displayName": "[parameters('displayName')]",
"description": "[parameters('description')]",
"metadata": {
"requestedBy": "[parameters('requestedBy')]",
"approvedBy": "[parameters('approvedBy')]",
"createdBy": "DevOps deployment"
}
}
}
]
}
}
}
]
}

Просмотреть файл

@ -0,0 +1,212 @@
# Storage Account
Create or update a Storage Account.
## Parameters
Parameter name | Required | Description
-------------- | -------- | -----------
storageAccountName | Yes | The name of the Storage Account.
location | No | The Azure region to deploy to.
sku | No | Create the Storage Account as LRS or GRS.
suffixLength | No | Determine how many additional characters are added to the storage account name as a suffix.
containers | No | An array of storage containers to create on the storage account.
lifecycleRules | No | An array of lifecycle management policies for the storage account.
blobSoftDeleteDays | No | The number of days to retain deleted blobs. When set to 0, soft delete is disabled.
containerSoftDeleteDays | No | The number of days to retain deleted containers. When set to 0, soft delete is disabled.
shares | No | An array of file shares to create on the storage account.
useLargeFileShares | No | Determines if large file shares are enabled. This can not be disabled once enabled.
shareSoftDeleteDays | No | The number of days to retain deleted shares. When set to 0, soft delete is disabled.
allowBlobPublicAccess | No | Determines if any containers can be configured with the anonymous access types of blob or container.
keyVaultPrincipalId | No | Set to the objectId of Azure Key Vault to delegated permission for use with Key Managed Storage Accounts.
tags | Yes | Tags to apply to the resource.
### storageAccountName
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
The name of the Storage Account.
### location
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The Azure region to deploy to.
- Default value: `[resourceGroup().location]`
### sku
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Create the Storage Account as LRS or GRS.
- Default value: `Standard_LRS`
- Allowed values: `Standard_LRS`, `Standard_GRS`
### suffixLength
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determine how many additional characters are added to the storage account name as a suffix.
- Default value: `0`
### containers
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
An array of storage containers to create on the storage account.
### lifecycleRules
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
An array of lifecycle management policies for the storage account.
### blobSoftDeleteDays
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The number of days to retain deleted blobs. When set to 0, soft delete is disabled.
- Default value: `0`
### containerSoftDeleteDays
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The number of days to retain deleted containers. When set to 0, soft delete is disabled.
- Default value: `0`
### shares
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
An array of file shares to create on the storage account.
### useLargeFileShares
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determines if large file shares are enabled. This can not be disabled once enabled.
- Default value: `False`
### shareSoftDeleteDays
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
The number of days to retain deleted shares. When set to 0, soft delete is disabled.
- Default value: `0`
### allowBlobPublicAccess
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Determines if any containers can be configured with the anonymous access types of blob or container.
- Default value: `False`
### keyVaultPrincipalId
![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square)
Set to the objectId of Azure Key Vault to delegated permission for use with Key Managed Storage Accounts.
### tags
![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square)
Tags to apply to the resource.
## Outputs
Name | Type | Description
---- | ---- | -----------
resourceId | string | A unique resource identifier for the Storage Account.
## Snippets
### Parameter file
```json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"template": "templates/storage/v2/template.json"
},
"parameters": {
"storageAccountName": {
"value": "<name>"
},
"sku": {
"value": "Standard_LRS"
},
"containers": {
"value": [
{
"name": "logs",
"publicAccess": "None",
"metadata": {}
}
]
},
"lifecycleRules": {
"value": {
"enabled": true,
"name": "<rule_name>",
"type": "Lifecycle",
"definition": {
"actions": {
"baseBlob": {
"delete": {
"daysAfterModificationGreaterThan": 7
}
}
},
"filters": {
"blobTypes": [
"blockBlob"
],
"prefixMatch": [
"logs/"
]
}
}
}
},
"blobSoftDeleteDays": {
"value": 7
},
"containerSoftDeleteDays": {
"value": 7
},
"shares": {
"value": [
{
"name": "<share_name>",
"shareQuota": 5,
"metadata": {}
}
]
},
"shareSoftDeleteDays": {
"value": 7
},
"allowBlobPublicAccess": {
"value": false
},
"tags": {
"value": {
"service": "<service_name>",
"env": "prod"
}
}
}
}
```

Просмотреть файл

@ -0,0 +1,260 @@
// Azure Storage Account
@metadata({
description: 'The name of the Storage Account.'
example: '<name>'
})
param storageAccountName string
@metadata({
description: 'The Azure region to deploy to.'
strongType: 'location'
example: 'EastUS'
ignore: true
})
param location string = resourceGroup().location
@allowed([
'Standard_LRS'
'Standard_GRS'
])
@description('Create the Storage Account as LRS or GRS.')
param sku string = 'Standard_LRS'
@minValue(0)
@maxValue(13)
@metadata({
description: 'Determine how many additional characters are added to the storage account name as a suffix.'
ignore: true
})
param suffixLength int = 0
@metadata({
description: 'An array of storage containers to create on the storage account.'
example: [
{
name: 'logs'
publicAccess: 'None'
metadata: {}
}
]
})
param containers array = []
@metadata({
description: 'An array of lifecycle management policies for the storage account.'
example: {
enabled: true
name: '<rule_name>'
type: 'Lifecycle'
definition: {
actions: {
baseBlob: {
delete: {
daysAfterModificationGreaterThan: 7
}
}
}
filters: {
blobTypes: [
'blockBlob'
]
prefixMatch: [
'logs/'
]
}
}
}
})
param lifecycleRules array = []
@minValue(0)
@maxValue(365)
@metadata({
description: 'The number of days to retain deleted blobs. When set to 0, soft delete is disabled.'
example: 7
})
param blobSoftDeleteDays int = 0
@minValue(0)
@maxValue(365)
@metadata({
description: 'The number of days to retain deleted containers. When set to 0, soft delete is disabled.'
example: 7
})
param containerSoftDeleteDays int = 0
@metadata({
description: 'An array of file shares to create on the storage account.'
example: [
{
name: '<share_name>'
shareQuota: 5
metadata: {}
}
]
})
param shares array = []
@metadata({
description: 'Determines if large file shares are enabled. This can not be disabled once enabled.'
ignore: true
})
param useLargeFileShares bool = false
@minValue(0)
@maxValue(365)
@metadata({
description: 'The number of days to retain deleted shares. When set to 0, soft delete is disabled.'
example: 7
})
param shareSoftDeleteDays int = 0
@description('Determines if any containers can be configured with the anonymous access types of blob or container.')
param allowBlobPublicAccess bool = false
@metadata({
description: 'Set to the objectId of Azure Key Vault to delegated permission for use with Key Managed Storage Accounts.'
ignore: true
})
param keyVaultPrincipalId string = ''
@metadata({
description: 'Tags to apply to the resource.'
example: {
service: '<service_name>'
env: 'prod'
}
})
param tags object
var normalName = concat(storageAccountName, ((suffixLength > 0) ? substring(uniqueString(resourceGroup().id), 0, suffixLength) : ''))
var blobSoftDeleteLookup = {
'true': {
enabled: true
days: blobSoftDeleteDays
}
'false': {
enabled: false
}
}
var containerSoftDeleteLookup = {
'true': {
enabled: true
days: containerSoftDeleteDays
}
'false': null
}
var shareSoftDeleteLookup = {
'true': {
enabled: true
days: shareSoftDeleteDays
}
'false': {
enabled: false
}
}
var largeFileSharesState = (useLargeFileShares ? 'Enabled' : 'Disabled')
var storageAccountKeyOperatorRoleId = resourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')
resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
name: normalName
location: location
sku: {
name: sku
tier: 'Standard'
}
kind: 'StorageV2'
properties: {
networkAcls: {
bypass: 'AzureServices'
virtualNetworkRules: []
ipRules: []
defaultAction: 'Allow'
}
supportsHttpsTrafficOnly: true
encryption: {
services: {
file: {
enabled: true
}
blob: {
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
accessTier: 'Hot'
largeFileSharesState: largeFileSharesState
allowBlobPublicAccess: allowBlobPublicAccess
minimumTlsVersion: 'TLS1_2'
}
tags: tags
}
resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01' = {
parent: storageAccount
name: 'default'
properties: {
cors: {
corsRules: []
}
deleteRetentionPolicy: blobSoftDeleteLookup[string((blobSoftDeleteDays > 0))]
containerDeleteRetentionPolicy: containerSoftDeleteLookup[string((containerSoftDeleteDays > 0))]
}
}
resource fileServices 'Microsoft.Storage/storageAccounts/fileServices@2019-06-01' = {
parent: storageAccount
name: 'default'
properties: {
shareDeleteRetentionPolicy: shareSoftDeleteLookup[string((shareSoftDeleteDays > 0))]
}
}
resource storageAccountContainers 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = [for i in range(0, ((length(containers) == 0) ? 1 : length(containers))): if (!(length(containers) == 0)) {
name: ((length(containers) == 0) ? '${normalName}/default/empty' : '${normalName}/default/${containers[i].name}')
properties: {
metadata: containers[i].metadata
publicAccess: containers[i].publicAccess
}
dependsOn: [
blobServices
storageAccount
]
}]
resource managementPolicies 'Microsoft.Storage/storageAccounts/managementPolicies@2019-06-01' = if (!empty(lifecycleRules)) {
parent: storageAccount
name: 'default'
properties: {
policy: {
rules: lifecycleRules
}
}
}
resource storageAccountShares 'Microsoft.Storage/storageAccounts/fileServices/shares@2019-06-01' = [for i in range(0, ((length(shares) == 0) ? 1 : length(shares))): if (!(length(shares) == 0)) {
name: ((length(shares) == 0) ? '${normalName}/default/empty' : '${normalName}/default/${shares[i].name}')
properties: {
metadata: shares[i].metadata
shareQuota: shares[i].shareQuota
}
dependsOn: [
fileServices
storageAccount
]
}]
resource storageAccountKeyOperatorRole 'Microsoft.Storage/storageAccounts/providers/roleAssignments@2018-09-01-preview' = if (!empty(keyVaultPrincipalId)) {
name: '${normalName}/Microsoft.Authorization/${guid(keyVaultPrincipalId, storageAccountKeyOperatorRoleId)}'
properties: {
roleDefinitionId: storageAccountKeyOperatorRoleId
principalId: keyVaultPrincipalId
scope: storageAccount.id
principalType: 'ServicePrincipal'
}
}
output storageAccountResourceId string = storageAccount.id

Просмотреть файл

@ -0,0 +1,359 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "2.1.1.0",
"metadata": {
"name": "Storage Account",
"description": "Create or update a Storage Account."
},
"parameters": {
"storageAccountName": {
"type": "string",
"metadata": {
"description": "The name of the Storage Account.",
"example": "<name>"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The Azure region to deploy to.",
"strongType": "location",
"example": "EastUS",
"ignore": true
}
},
"sku": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS"
],
"metadata": {
"description": "Create the Storage Account as LRS or GRS."
}
},
"suffixLength": {
"type": "int",
"defaultValue": 0,
"minValue": 0,
"maxValue": 13,
"metadata": {
"description": "Determine how many additional characters are added to the storage account name as a suffix.",
"ignore": true
}
},
"containers": {
"type": "array",
"defaultValue": [
],
"metadata": {
"description": "An array of storage containers to create on the storage account.",
"example": [
{
"name": "logs",
"publicAccess": "None",
"metadata": {}
}
]
}
},
"lifecycleRules": {
"type": "array",
"defaultValue": [
],
"metadata": {
"description": "An array of lifecycle management policies for the storage account.",
"example": {
"enabled": true,
"name": "<rule_name>",
"type": "Lifecycle",
"definition": {
"actions": {
"baseBlob": {
"delete": {
"daysAfterModificationGreaterThan": 7
}
}
},
"filters": {
"blobTypes": [
"blockBlob"
],
"prefixMatch": [
"logs/"
]
}
}
}
}
},
"blobSoftDeleteDays": {
"type": "int",
"defaultValue": 0,
"minValue": 0,
"maxValue": 365,
"metadata": {
"description": "The number of days to retain deleted blobs. When set to 0, soft delete is disabled.",
"example": 7
}
},
"containerSoftDeleteDays": {
"type": "int",
"defaultValue": 0,
"minValue": 0,
"maxValue": 365,
"metadata": {
"description": "The number of days to retain deleted containers. When set to 0, soft delete is disabled.",
"example": 7
}
},
"shares": {
"type": "array",
"defaultValue": [
],
"metadata": {
"description": "An array of file shares to create on the storage account.",
"example": [
{
"name": "<share_name>",
"shareQuota": 5,
"metadata": {}
}
]
}
},
"useLargeFileShares": {
"type": "bool",
"defaultValue": false,
"metadata": {
"description": "Determines if large file shares are enabled. This can not be disabled once enabled.",
"ignore": true
}
},
"shareSoftDeleteDays": {
"type": "int",
"defaultValue": 0,
"minValue": 0,
"maxValue": 365,
"metadata": {
"description": "The number of days to retain deleted shares. When set to 0, soft delete is disabled.",
"example": 7
}
},
"allowBlobPublicAccess": {
"type": "bool",
"defaultValue": false,
"metadata": {
"description": "Determines if any containers can be configured with the anonymous access types of blob or container."
}
},
"keyVaultPrincipalId": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "Set to the objectId of Azure Key Vault to delegated permission for use with Key Managed Storage Accounts.",
"ignore": true
}
},
"tags": {
"type": "object",
"metadata": {
"description": "Tags to apply to the resource.",
"example": {
"service": "<service_name>",
"env": "prod"
}
}
}
},
"variables": {
"storageAccountName": "[concat(parameters('storageAccountName'), if(greater(parameters('suffixLength'), 0), substring(uniqueString(resourceGroup().id), 0, parameters('suffixLength')), ''))]",
"blobSoftDeleteLookup": {
"true": {
"enabled": true,
"days": "[parameters('blobSoftDeleteDays')]"
},
"false": {
"enabled": false
}
},
"containerSoftDeleteLookup": {
"true": {
"enabled": true,
"days": "[parameters('containerSoftDeleteDays')]"
},
"false": null
},
"shareSoftDeleteLookup": {
"true": {
"enabled": true,
"days": "[parameters('shareSoftDeleteDays')]"
},
"false": {
"enabled": false
}
},
"largeFileSharesState": "[if(parameters('useLargeFileShares'), 'Enabled', 'Disabled')]",
"storageAccountKeyOperatorRoleId": "[resourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]"
},
"resources": [
{
"comments": "Storage Account",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('sku')]",
"tier": "Standard"
},
"kind": "StorageV2",
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [
],
"ipRules": [
],
"defaultAction": "Allow"
},
"supportsHttpsTrafficOnly": true,
"encryption": {
"services": {
"file": {
"enabled": true
},
"blob": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"accessTier": "Hot",
"largeFileSharesState": "[variables('largeFileSharesState')]",
"allowBlobPublicAccess": "[parameters('allowBlobPublicAccess')]",
"minimumTlsVersion": "TLS1_2"
},
"tags": "[parameters('tags')]",
"resources": [
{
"comments": "Configure blob storage services",
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-06-01",
"name": "[concat(variables('storageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"sku": {
"name": "[parameters('sku')]"
},
"properties": {
"cors": {
"corsRules": [
]
},
"deleteRetentionPolicy": "[variables('blobSoftDeleteLookup')[string(greater(parameters('blobSoftDeleteDays'), 0))]]",
"containerDeleteRetentionPolicy": "[variables('containerSoftDeleteLookup')[string(greater(parameters('containerSoftDeleteDays'), 0))]]"
}
},
{
"comments": "Configure file storage services",
"type": "Microsoft.Storage/storageAccounts/fileServices",
"apiVersion": "2019-06-01",
"name": "[concat(variables('storageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"sku": {
"name": "[parameters('sku')]"
},
"properties": {
"shareDeleteRetentionPolicy": "[variables('shareSoftDeleteLookup')[string(greater(parameters('shareSoftDeleteDays'), 0))]]"
}
}
]
},
{
"comments": "Create a blob container",
"condition": "[not(equals(length(parameters('containers')), 0))]",
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[if(equals(length(parameters('containers')), 0), concat(variables('storageAccountName'), '/default/empty'), concat(variables('storageAccountName'), '/default/', parameters('containers')[copyIndex('containerIndex')].name))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('storageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"copy": {
"mode": "Parallel",
"count": "[if(equals(length(parameters('containers')), 0), 1, length(parameters('containers')))]",
"name": "containerIndex"
},
"properties": {
"metadata": "[parameters('containers')[copyIndex('containerIndex')].metadata]",
"publicAccess": "[parameters('containers')[copyIndex('containerIndex')].publicAccess]"
}
},
{
"comments": "Create blob lifecycle policy",
"condition": "[not(empty(parameters('lifecycleRules')))]",
"name": "[concat(variables('storageAccountName'), '/default')]",
"type": "Microsoft.Storage/storageAccounts/managementPolicies",
"apiVersion": "2019-06-01",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"policy": {
"rules": "[parameters('lifecycleRules')]"
}
}
},
{
"comments": "Create a share",
"condition": "[not(equals(length(parameters('shares')), 0))]",
"type": "Microsoft.Storage/storageAccounts/fileServices/shares",
"apiVersion": "2019-06-01",
"name": "[if(equals(length(parameters('shares')), 0), concat(variables('storageAccountName'), '/default/empty'), concat(variables('storageAccountName'), '/default/', parameters('shares')[copyIndex('shareIndex')].name))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('storageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"copy": {
"mode": "Parallel",
"count": "[if(equals(length(parameters('shares')), 0), 1, length(parameters('shares')))]",
"name": "shareIndex"
},
"properties": {
"metadata": "[parameters('shares')[copyIndex('shareIndex')].metadata]",
"shareQuota": "[parameters('shares')[copyIndex('shareIndex')].shareQuota]"
}
},
{
"comments": "Delegate Key Vault permission to rotate keys",
"condition": "[not(empty(parameters('keyVaultPrincipalId')))]",
"type": "Microsoft.Storage/storageAccounts/providers/roleAssignments",
"apiVersion": "2018-09-01-preview",
"name": "[concat(variables('storageAccountName'), '/Microsoft.Authorization/', guid(parameters('keyVaultPrincipalId'), variables('storageAccountKeyOperatorRoleId')))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"roleDefinitionId": "[variables('storageAccountKeyOperatorRoleId')]",
"principalId": "[parameters('keyVaultPrincipalId')]",
"scope": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"principalType": "ServicePrincipal"
}
}
],
"outputs": {
"resourceId": {
"type": "string",
"value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"metadata": {
"description": "A unique resource identifier for the Storage Account."
}
}
}
}