Skip to content

Commit

Permalink
misc updates to readme, added PR template, added small ci/cd doc (#1245)
Browse files Browse the repository at this point in the history
* misc updates to readme, added PR template, cleaned up tutorial, added cicd doc

* small tweaks

* addressed comments

* comment was in the wrong spot
  • Loading branch information
alex-frankel committed Jan 5, 2021
1 parent 7b1da15 commit 4f4639f
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 12 deletions.
20 changes: 20 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,20 @@
# Contributing a Pull Request

If you haven't already, read the full [contribution guide](../CONTRIBUTING.md). The guide may have changed since the last time you read it, so please double-check. Once you are done and ready to submit your PR, run through the relevant checklist below.

## Contributing to documentation

* [ ] The contribution does not exist in any of the docs in either the root of the [docs](../docs) directory or the [specs](../docs/spec)

## Contributing an example

* [ ] I have checked that there is not an equivalent example already submitted
* [ ] I have resolved all warnings and errors shown by the Bicep VS Code extension
* [ ] I have checked that all tests are passing by running `dotnet test`
* [ ] I have consistent casing for all of my identifiers and am using camelCasing unless I have a justification to use another casing style

## Contributing a feature

* [ ] I have opened a new issue for the proposal, or commented on an existing one, and ensured that the bicep maintainers are good with the design of the feature being implemented
* [ ] I have included "Fixes #{issue_number}" in the PR description, so GitHub can link to the issue and close it when the PR is merged
* [ ] I have appropriate test coverage of my new feature
5 changes: 4 additions & 1 deletion CONTRIBUTING.md
Expand Up @@ -65,7 +65,7 @@ If you'd like to start contributing to Bicep, you can search for issues tagged a
* Ensure that an issue has been created to track the feature enhancement or bug that is being fixed.
* In the PR description, make sure you've included "Fixes #{issue_number}" e.g. "Fixes #242" so that GitHub knows to link it to an issue.
* To avoid multiple contributors working on the same issue, please add a comment to the issue to let us know you plan to work on it.
* If a significant amount of design is required, please include a proposal in the issue and wait for approval before working on code. If there's anything you're not sure about, please feel free to discuss this in the issue. We'd much rather all be on the same page at the start, so that there's less chance that drastic changes will be needed when your pull request is reveiwed.
* If a significant amount of design is required, please include a proposal in the issue and wait for approval before working on code. If there's anything you're not sure about, please feel free to discuss this in the issue. We'd much rather all be on the same page at the start, so that there's less chance that drastic changes will be needed when your pull request is reviewed.
* We report on code coverage; please ensure any new code you add is sufficiently covered by tests.

### Example Files
Expand All @@ -82,6 +82,9 @@ If you'd like to contribute example `.bicep` files that showcase abilities of th
1. All `.bicep` files have been formatted with the default Bicep auto-formatter.

See [Running the tests](#running-the-tests) if you'd like to test locally before submitting a PR, and [Updating test baselines](#updating-test-baselines) for information on how to automatically update your example `.json` and `.bicep` files to match the format expected by the tests.
* If you have any test failures that are the result of compiler warnings, you may need to do either of the following:
1. If a resource type or api version is missing, you will get a type warning. To pass the test, you will need to add that type to the list of missing types in [ExampleTests.cs](https://github.com/Azure/bicep/blob/main/src/Bicep.Core.Samples/ExamplesTests.cs#L95).
1. If you have a false positive error or warning for a known resource type -- for example, if a property is missing an enum value -- you will need to suppress the warning using the `any()` function. You can read more about the any() function [here](./docs/the-any-function.md).
* While everything will *not necessarily be applicable*, read through the Azure QuickStart Templates [Best Practices Guide](https://github.com/Azure/azure-quickstart-templates/blob/master/1-CONTRIBUTION-GUIDE/best-practices.md#best-practices) and follow it where appropriate (i.e. [parameter guidance](https://github.com/Azure/azure-quickstart-templates/blob/master/1-CONTRIBUTION-GUIDE/best-practices.md#parameters), [resource property order](https://github.com/Azure/azure-quickstart-templates/blob/master/1-CONTRIBUTION-GUIDE/best-practices.md#sort-order-of-properties), etc.)

**Note:** If you have never submitted a Pull Request or used git before, reading through the [Git tutorial](https://github.com/Azure/azure-quickstart-templates/blob/master/1-CONTRIBUTION-GUIDE/git-tutorial.md) in the azure-quickstart-template repo is a good place to start.
Expand Down
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -65,6 +65,8 @@ az deployment group create -f ./main.json -g my-rg
* Automatic dependency management in certain scenarios. Bicep will automatically add `dependsOn` in the compiled ARM Template if the symbolic name is used in another resource declaration.
* Richer validation and intellisense than what is available in the ARM Tools VS Code extension. For example, in bicep we have intellisense on GET properties (`output sample string = resource.properties.*`)

For more detail on taking advantage of new bicep constructs that replace an equivalent from ARM Templates, you can read the [moving from ARM => Bicep](./docs/arm2bicep.md) doc.

## Known limitations

* No support for the `copy` property ([#185](https://github.com/Azure/bicep/issues/185)).
Expand Down Expand Up @@ -104,6 +106,11 @@ Note that while we want to make it easy to transition to Bicep, we will continue
* [@BicepLang](https://twitter.com/BicepLang)
* [ARM Template Reference](https://docs.microsoft.com/azure/templates/)

## Community Bicep projects

* [Bicep GitHub Action](https://github.com/marketplace/actions/bicep-build)
* [Bicep Language Service support in Neovim](https://github.com/Azure/bicep/issues/1141#issuecomment-749372637)

## Alternatives

Because we are now treating the ARM Template as an IL, we expect and encourage other implementations of IL (ARM Template) generation. We'll keep a running list of alternatives for creating ARM templates that may better fit your use case.
Expand Down
8 changes: 4 additions & 4 deletions docs/arm2bicep.md
@@ -1,6 +1,6 @@
# ARM Template syntax and the native Bicep equivalent

In Bicep, we have tried to make some common syntax in ARM templates that is quite verbose and change it to a terser equivalent. This doc is a simple table to look at all of the changes in one place.
In Bicep, we have tried to make some common syntax that in ARM templates is quite verbose and change it to a terser equivalent. This doc is a simple table to look at all of the changes in one place.

Scenario | ARM Template | Bicep
--- | --- | ---
Expand All @@ -12,10 +12,10 @@ Get a property (`resourceProperty`) from a created resource (assumes `resource`
Conditionally declare a property value | `if(parameters('isMonday'), 'valueIfTrue', 'valueIfFalse')` | `isMonday ? 'valueIfTrue' : 'valueIfFalse'` ([spec](https://github.com/Azure/bicep/blob/main/docs/spec/expressions.md#ternary-operator))
Separate a solution into multiple files | Use [linked templates](https://docs.microsoft.com/azure/azure-resource-manager/templates/linked-templates#linked-template) | Use [modules](https://github.com/Azure/bicep/blob/main/docs/spec/modules.md)
Set the target scope of the deployment to a subscription | `"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#"` | `targetScope = 'subscription'` ([spec](https://github.com/Azure/bicep/blob/main/docs/spec/resource-scopes.md#declaring-the-target-scopes))
Set a dependency between two resources | `"dependsOn": ["[resourceId('Microsoft.Storage/storageAccounts', 'parameters('storageAcountName'))]"`] | Either dependsOn not needed because of [auto-dependency management](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#implicit-dependency) or manually set dependsOn with `dependsOn: [ stg ]` ([spec](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#resource-dependencies))
Set a dependency between two resources | `"dependsOn": ["[resourceId('Microsoft.Storage/storageAccounts', 'parameters('storageAccountName'))]"`] | Either dependsOn not needed because of [auto-dependency management](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#implicit-dependency) or manually set dependsOn with `dependsOn: [ stg ]` ([spec](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#resource-dependencies))

## Incorporating new syntax into best practices

* Avoid the `reference()` and `resourceId()` functions like the plague. Anytime the resource you are referencing is declared in the same bicep project, you can pull the equivalent information from the resource identifier in bicep (i.e. `stg.id` or `stg.properties.primaryEndpoints.blob`). This also creates an [**implicit dependency**](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#implicit-dependency) between resources, which means you can eliminate your usage of the `dependsOn` property. All of this results in cleaner, more maintainable code.
* Avoid the `reference()` and `resourceId()` functions unless absolutely necessary. Anytime the resource you are referencing is declared in the same bicep project, you can pull the equivalent information from the resource identifier in bicep (i.e. `stg.id` or `stg.properties.primaryEndpoints.blob`). This also creates an [**implicit dependency**](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#implicit-dependency) between resources, which means you can eliminate your usage of the `dependsOn` property. All of this results in cleaner, more maintainable code.
* Use consistent casing for identifiers. When in doubt, use [camel case](https://en.wikipedia.org/wiki/Camel_case) (e.g. `param myCamelCasedParameter string`)
* If you are going to add a `description` to a parameter, ensure the parameter is in fact descriptive. If you have a `location` parameter, having a description of "the resource's location" is not particularly helpful and results in your code being noisier. Sometimes a `//` comment is more appropriate.
* If you are going to add a `description` to a parameter, ensure the parameter is in fact descriptive. For example, if you have a `location` parameter, having a description of "the resource's location" is not particularly helpful and results in noisy code. Sometimes a `//` comment is more appropriate.
73 changes: 73 additions & 0 deletions docs/cicd-with-bicep.md
@@ -0,0 +1,73 @@
# Adding bicep to a CI/CD pipeline

As your bicep practice matures, you will want to check-in your bicep code into source control and kick off a pipeline or workflow, which would do the following:

1. Build your bicep file into an ARM Template
1. Deploy the generated ARM template

In order to do this, we need to make sure the bicep CLI is installed on the build agent. For now, bicep is not preinstalled on any build agents or tasks provided by Microsoft, but installing it manually as part of the pipeline is straightforward.

The following example is designed to be run in GitHub actions workflow and uses Azure CLI, but could be easily adapted to run in a Azure DevOps Pipeline. It assumes the following prerequisite:

* The bicep file you want to transpile and deploy is called `main.bicep` and exists in the root of the repo
* You are deploying the transpiled ARM Template to a resource group. Deploying to another scope like a subscription requires a different CLI command.

```yaml

name: bicep build and deploy

on: push

jobs:
bicep-build-and-deploy:
name: bicep build and deploy
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Install the latest release of the bicep CLI
- name: Install bicep CLI
run: |
curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64
chmod +x ./bicep
sudo mv ./bicep /usr/local/bin/bicep
bicep --help
# Transpile bicep file into ARM template
- name: Build ARM Template from bicep file
run: |
bicep build ./main.bicep
# Stop here if you only want to do "CI" which just generates the
# build artifact (ARM Template JSON)

# Login to Azure
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

# Emit template what-if to show what template will do
- name: Run what-if
uses: azure/CLI@v1
with:
inlineScript: |
az account show
az deployment group what-if -f ./main.json -p ./parameters.json -g my-rg
# You may want a human approval in between the what-if step
# and the deploy step to evaluate output before deployment

# Deploy template
- name: Deploy template
uses: azure/CLI@v1
with:
inlineScript: |
az account show
az deployment group create -f ./main.json -g my-rg
```

Instead of installing the bicep CLI manually, you may instead want to use the [community-maintained github action](https://github.com/marketplace/actions/bicep-build) from [@justinyoo](https://github.com/justinyoo) that can run `bicep build` on your behalf.
4 changes: 4 additions & 0 deletions docs/the-any-function.md
Expand Up @@ -68,3 +68,7 @@ resource wpAci 'microsoft.containerInstance/containerGroups@2019-12-01' = {
You can see in the live code in [the playground](https://aka.ms/bicepdemo#eJyNVFtv2jAUfs+v8JvhgSTQbV0jbRodW1epa7MGdQ/TVBnHgKXENr5A0cR/n53gEIJQmzzEOT7fxUfHRyCJSqA0l2hBxhhzw/Q9KokNScoW4BMwjK4MyarfniSKG4nJjeRG9PohzfuBqCmoJsfAU9Jgn1tus1WRIqU2XOYe8C8AQBFsJEmAloYEO59ecIw05exA3bXhM4Ig8FtgI8aYAlhSLLnicx1izjSijMhbpjRimERNpOJRX0bx8GowHA3iIbQizhCzrhMAnU9hmdWggdA9CbRZXj5pVjYoJBdEakpUUlEB0GBt5E8VAfsd93SlYLNzylQ/tLTlbUOSd+HVAAmElwS28gSXuiXZFW5ENMe8sHzTryns7lqKBHyMj8K71t/f1pqwNZWclYTpJyQpmhXkVfn96X8/PE7Sx29Z9jy5fv7xkE27RtaoMC5xOLoMY/sOk4uL+AM86+ttSuk4y1ygq1b341Otedy1UQTwErEFyYFeUgXmkpcAVvZs83wGsIU9b69dtjUvTEl+usvyarlKl5UivbQnidZIRpvNJlrqsuieoNtVc1q80Y6/SJ2mcxt2Hih9ErcNLkwCENv2YBy+h/2uZ1Jyub1lN9dN0mUnqe3lsPar+lt7pGKc51XPNy5O2rxt73x7n7S2l/PF0FvhSpiaWUGxR+ZMuYl2h2bEcvrhFxzwXE1r3B1l5sXBdm6icaOF0RXg+6/J/WGkVeMqPFz1sDlhOF/l7D8GbIVb), the warnings go away.

`any()` works on any assigned value in bicep. You can see a more complex use of `any()` in the `nested-vms-in-virtual-network` example on [line 31](https://github.com/Azure/bicep/blob/main/docs/examples/301/nested-vms-in-virtual-network/nic.bicep#L31) of `nic.bicep` in which the use of `any()` wraps the entire ternary expression as an argument.

For more complex uses of the `any()` function, you can look at some of the below examples:
* [Child resources that require a specific names](https://github.com/Azure/bicep/blob/main/docs/examples/201/api-management-create-all-resources/main.bicep#L246)
* [A resource property is not defined in the resource's type, even though it exists](https://github.com/Azure/bicep/blob/main/docs/examples/201/log-analytics-with-solutions-and-diagnostics/main.bicep#L26)
20 changes: 14 additions & 6 deletions docs/tutorial/05-creating-modules.md
Expand Up @@ -169,20 +169,28 @@ Since the `targetScope` has been changed, notice that the `$schema` property in
Modules are a powerful way to separate your bicep files into logical units and abstract away complex resource declarations.

## Using if condition with bicep Modules
Modules also support the if condition (introduced in v0.2.212). The linked ARM template produced by `bicep build` will insert a condition at the deployment level for everything in the module. To take advantage of this the module declaration needs to follow the if condition syntax:
````

Modules also support the `if` keyword to conditionally deploy the module. Let's add a new `param` called `deployStorage` and use it conditionally deploy the storage account module:

```
param deployStorage bool = true
module stg './storage.bicep' = if (deployStorage) {
name: 'storageDeploy'
}
````
In this example if the parameter of `deployStorage` is set to `false` then everything in the module will be skipped at deployment. If `deployStorage` is set to `true` the module will be deployed. The ARM template created by running `bicep build` will look like:
````
```

In this example if the parameter of `deployStorage` is set to `false` then everything in the module will be skipped at deployment. If `deployStorage` is set to `true` then the module will be deployed.

The linked ARM template produced by `bicep build` will add the `condition` property to the entire nested deployment resource, which is what represents the compiled module. It will look like the following:

```
{
"condition": "[parameters('deployStorage')]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-10-01",
.....
````
```

Thus combining modules with the usage of the if() condition allows for customizing deployed components based on criteria and/or parameters.

Expand Down
2 changes: 2 additions & 0 deletions docs/tutorial/complete-bicep-files/05.bicep
@@ -1,5 +1,7 @@
targetScope = 'subscription'

param deployStorage bool = true

module stg './storage.bicep' = {
name: 'storageDeploy'
scope: resourceGroup('brittle-hollow') // this will target another resource group in the same subscription
Expand Down
8 changes: 7 additions & 1 deletion docs/tutorial/complete-bicep-files/05.json
@@ -1,6 +1,12 @@
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"deployStorage": {
"type": "bool",
"defaultValue": true
}
},
"functions": [],
"variables": {
"objectId": "cf024e4c-f790-45eb-a992-5218c39bde1a",
Expand Down Expand Up @@ -93,7 +99,7 @@
"outputs": {
"storageName": {
"type": "string",
"value": "[reference(resourceId('Microsoft.Resources/deployments', 'stg'), '2019-10-01').outputs.computedStorageName.value]"
"value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, 'brittle-hollow'), 'Microsoft.Resources/deployments', 'storageDeploy'), '2019-10-01').outputs.computedStorageName.value]"
}
}
}

0 comments on commit 4f4639f

Please sign in to comment.