Родитель
9e5038e2c3
Коммит
8ed5d83953
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"image": "mcr.microsoft.com/azterraform:latest",
|
||||
|
||||
"runArgs": [
|
||||
"--cap-add=SYS_PTRACE",
|
||||
"--security-opt",
|
||||
"seccomp=unconfined",
|
||||
"--init",
|
||||
"--network=host"
|
||||
],
|
||||
|
||||
"mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
"go.toolsManagement.checkForUpdates": "local",
|
||||
"go.useLanguageServer": true,
|
||||
"go.goroot": "/usr/local/go"
|
||||
},
|
||||
"extensions": [
|
||||
"hashicorp.terraform",
|
||||
"golang.Go"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
name: Bug Report
|
||||
description: If something isn't working as expected.
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to fill out a bug report.
|
||||
|
||||
If you are not running the latest version of this module, please try to reproduce your bug with the latest version before opening an issue.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Greenfield/Brownfield provisioning
|
||||
description: Do you reproduce the bug with a new infrastructure provisioning (greenfield) or you need an existing infrastructure with an existing terraform state (brownfield) to reproduce the bug ?
|
||||
multiple: false
|
||||
options:
|
||||
- greenfield
|
||||
- brownfield
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: terraform
|
||||
attributes:
|
||||
label: Terraform Version
|
||||
description: Which Terraform version are you using?
|
||||
placeholder: Example value, 1.2.8
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: module
|
||||
attributes:
|
||||
label: Module Version
|
||||
description: Which module version are you using?
|
||||
placeholder: Example value, 6.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: azurerm
|
||||
attributes:
|
||||
label: AzureRM Provider Version
|
||||
description: Which AzureRM Provider version are you using?
|
||||
placeholder: Example value, 3.21.1
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: resource
|
||||
attributes:
|
||||
label: Affected Resource(s)/Data Source(s)
|
||||
description: Please list the affected resources and/or data sources.
|
||||
placeholder: azurerm_XXXXX
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Terraform Configuration Files
|
||||
description: |
|
||||
Please provide a minimal Terraform configuration that can reproduce the issue.
|
||||
render: hcl
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: tfvars
|
||||
attributes:
|
||||
label: tfvars variables values
|
||||
description: |
|
||||
Please provide the necessary tfvars variables values to reproduce the issue. Do not share secrets or sensitive information.
|
||||
render: hcl
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: debug
|
||||
attributes:
|
||||
label: Debug Output/Panic Output
|
||||
description: |
|
||||
For long debug logs please provide a link to a GitHub Gist containing the complete debug output. Please do NOT paste the debug output in the issue; just paste a link to the Gist.
|
||||
|
||||
To obtain the debug output, see the [Terraform documentation on debugging](https://www.terraform.io/docs/internals/debugging.html).
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected Behaviour
|
||||
description: What should have happened?
|
||||
- type: textarea
|
||||
id: actual
|
||||
attributes:
|
||||
label: Actual Behaviour
|
||||
description: What actually happened?
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: |
|
||||
Please list the steps required to reproduce the issue, e.g.
|
||||
|
||||
1. `terraform apply`
|
||||
- type: input
|
||||
id: facts
|
||||
attributes:
|
||||
label: Important Factoids
|
||||
description: |
|
||||
Are there anything atypical about your accounts that we should know? For example: Running in a Azure China/Germany/Government?
|
||||
- type: textarea
|
||||
id: references
|
||||
attributes:
|
||||
label: References
|
||||
description: |
|
||||
Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests
|
||||
|
||||
Are there any other GitHub issues (open or closed) or pull requests that should be linked here? Such as vendor documentation?
|
|
@ -0,0 +1,42 @@
|
|||
name: Feature Request
|
||||
description: I have a suggestion (and might want to implement myself)!
|
||||
title: "Support for [thing]"
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the feature you are requesting.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Please leave a helpful description of the feature request here.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: resource
|
||||
attributes:
|
||||
label: New or Affected Resource(s)/Data Source(s)
|
||||
description: Please list the new or affected resources and/or data sources.
|
||||
placeholder: azurerm_XXXXX
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Potential Terraform Configuration
|
||||
description: Please provide an example of what the enhancement could look like on this Terraform module.
|
||||
render: hcl
|
||||
- type: textarea
|
||||
id: references
|
||||
attributes:
|
||||
label: References
|
||||
description: |
|
||||
Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests
|
||||
|
||||
Are there any other GitHub issues (open or closed) or pull requests that should be linked here? Vendor blog posts or documentation? For example:
|
||||
|
||||
* https://azure.microsoft.com/en-us/roadmap/virtual-network-service-endpoint-for-azure-cosmos-db/
|
|
@ -0,0 +1 @@
|
|||
blank_issues_enabled: false
|
|
@ -0,0 +1,6 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/test"
|
||||
schedule:
|
||||
interval: "weekly"
|
|
@ -0,0 +1,13 @@
|
|||
## Describe your changes
|
||||
|
||||
## Issue number
|
||||
|
||||
#000
|
||||
|
||||
## Checklist before requesting a review
|
||||
- [ ] The pr title can be used to describe what this pr did in `CHANGELOG.md` file
|
||||
- [ ] I have executed pre-commit on my machine
|
||||
- [ ] I have passed pr-check on my machine
|
||||
|
||||
Thanks for your cooperation!
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
name: E2E Test
|
||||
on:
|
||||
pull_request:
|
||||
types: [ 'opened', 'synchronize' ]
|
||||
paths:
|
||||
- '.github/**'
|
||||
- '**.go'
|
||||
- '**.tf'
|
||||
- '.github/workflows/**'
|
||||
- '**.md'
|
||||
- '**/go.mod'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
acc-tests:
|
||||
runs-on: [self-hosted, 1ES.Pool=terraform-azurerm-database]
|
||||
environment:
|
||||
name: acctests
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: init
|
||||
run: |
|
||||
docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make generate
|
||||
- name: e2e test
|
||||
run: |
|
||||
sh scripts/ci-e2e.sh
|
||||
- name: upload test version snapshots
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: TestRecord-${{ github.event.number }}
|
||||
retention-days: 60
|
||||
path: |
|
||||
examples/**/TestRecord.md.tmp
|
||||
- name: version-upgrade test
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
sh scripts/ci-version-upgrade.sh
|
|
@ -0,0 +1,15 @@
|
|||
name: 'Comment on PR'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Pre Pull Request Check"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
uses: Azure/tfmod-scaffold/.github/workflows/breaking-change-detect.yaml@main
|
|
@ -0,0 +1,15 @@
|
|||
name: Post Push
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
post-push:
|
||||
if: github.actor != 'github-actions[bot]'
|
||||
uses: Azure/tfmod-scaffold/.github/workflows/post-push.yaml@main
|
|
@ -0,0 +1,19 @@
|
|||
name: Pre Pull Request Check
|
||||
on:
|
||||
pull_request:
|
||||
types: ['opened', 'synchronize']
|
||||
paths:
|
||||
- '.github/**'
|
||||
- '**.go'
|
||||
- '**.tf'
|
||||
- '.github/workflows/**'
|
||||
- '**.md'
|
||||
- '**/go.mod'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
prepr-check:
|
||||
uses: Azure/tfmod-scaffold/.github/workflows/pr-check.yaml@main
|
|
@ -0,0 +1,33 @@
|
|||
name: Weekly E2E Test Check
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
full-e2e-check:
|
||||
runs-on: [self-hosted, 1ES.Pool=terraform-azurerm-database]
|
||||
environment:
|
||||
name: crontests
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: init
|
||||
run: |
|
||||
docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make generate
|
||||
- name: e2e test
|
||||
continue-on-error: true
|
||||
run: |
|
||||
sh scripts/ci-e2e.sh
|
||||
- name: Update
|
||||
run: |
|
||||
sh scripts/ci-update-test-record.sh
|
||||
- name: Commit & Push changes
|
||||
uses: actions-js/push@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
message: 'Update TestVersionSnapshot'
|
||||
branch: ${{ github.event.repository.default_branch }}
|
|
@ -1,13 +1,68 @@
|
|||
# Variable files
|
||||
terraform.tfvars
|
||||
|
||||
### https://raw.github.com/github/gitignore/abad92dac5a4306f72242dae3bca6e277bce3615/Terraform.gitignore
|
||||
|
||||
# Compiled files
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
||||
*.tfvars
|
||||
|
||||
**/.terraform.lock.hcl
|
||||
|
||||
# Terraform directory
|
||||
.terraform/
|
||||
terraform.tfstate.d/
|
||||
logs/
|
||||
|
||||
# Go vendor directory
|
||||
vendor/
|
||||
|
||||
# Module directory
|
||||
.terraform/
|
||||
# Files generated by terratest
|
||||
.test-data/
|
||||
|
||||
# Package version lock files
|
||||
# Terraform log file
|
||||
terraform.log
|
||||
|
||||
### https://raw.github.com/github/gitignore/abad92dac5a4306f72242dae3bca6e277bce3615/Global/Vim.gitignore
|
||||
|
||||
# swap
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
# session
|
||||
Session.vim
|
||||
# temporary
|
||||
.netrwhist
|
||||
*~
|
||||
# auto-generated tag files
|
||||
tags
|
||||
|
||||
# IDE configs
|
||||
.idea
|
||||
|
||||
# Ruby download package lock file.
|
||||
Gemfile.lock
|
||||
|
||||
# Mac folder attribute file
|
||||
.DS_Store
|
||||
|
||||
.terraform.tfstate.lock.info
|
||||
|
||||
# SSH Key
|
||||
private_ssh_key
|
||||
|
||||
# generated readme by the pr-check job
|
||||
|
||||
README-generated.md
|
||||
|
||||
**/override.tf
|
||||
|
||||
.tflint.hcl
|
||||
.tflint_example.hcl
|
||||
|
||||
tfmod-scaffold/
|
||||
scripts
|
||||
test/go.sum
|
||||
|
||||
/TestRecord
|
||||
**/TestRecord.md.tmp
|
31
.travis.yml
31
.travis.yml
|
@ -1,31 +0,0 @@
|
|||
# Build matrix / environment variable are explained on:
|
||||
# http://about.travis-ci.org/docs/user/build-configuration/
|
||||
# This file can be validated on:
|
||||
# http://lint.travis-ci.org/
|
||||
sudo: required
|
||||
|
||||
language: ruby
|
||||
|
||||
rvm:
|
||||
- 2.3
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
env:
|
||||
- TERRAFORM_VERSION=0.11.7 IMAGE_NAME=azure-database-module
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: build
|
||||
if: type = pull_request
|
||||
install: true
|
||||
script:
|
||||
- docker build --build-arg BUILD_TERRAFORM_VERSION=${TERRAFORM_VERSION} -t ${IMAGE_NAME} .
|
||||
- docker run ${IMAGE_NAME} rake build
|
||||
- stage: full
|
||||
if: type = push AND branch = master
|
||||
install: true
|
||||
script:
|
||||
- docker build --build-arg BUILD_TERRAFORM_VERSION=${TERRAFORM_VERSION} --build-arg BUILD_ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID --build-arg BUILD_ARM_CLIENT_ID=$ARM_CLIENT_ID --build-arg BUILD_ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET --build-arg BUILD_ARM_TENANT_ID=$ARM_TENANT_ID -t ${IMAGE_NAME} .
|
||||
- docker run ${IMAGE_NAME} rake full
|
40
Dockerfile
40
Dockerfile
|
@ -1,40 +0,0 @@
|
|||
# Pull the base image with given version.
|
||||
ARG BUILD_TERRAFORM_VERSION=0.11.7
|
||||
FROM microsoft/terraform-test:${BUILD_TERRAFORM_VERSION}
|
||||
|
||||
ARG MODULE_NAME="terraform-azurerm-database"
|
||||
|
||||
# Declare default build configurations for terraform.
|
||||
ARG BUILD_ARM_SUBSCRIPTION_ID=""
|
||||
ARG BUILD_ARM_CLIENT_ID=""
|
||||
ARG BUILD_ARM_CLIENT_SECRET=""
|
||||
ARG BUILD_ARM_TENANT_ID=""
|
||||
ARG BUILD_ARM_TEST_LOCATION="WestEurope"
|
||||
ARG BUILD_ARM_TEST_LOCATION_ALT="WestUS"
|
||||
|
||||
# Set environment variables for terraform runtime.
|
||||
ENV ARM_SUBSCRIPTION_ID=${BUILD_ARM_SUBSCRIPTION_ID}
|
||||
ENV ARM_CLIENT_ID=${BUILD_ARM_CLIENT_ID}
|
||||
ENV ARM_CLIENT_SECRET=${BUILD_ARM_CLIENT_SECRET}
|
||||
ENV ARM_TENANT_ID=${BUILD_ARM_TENANT_ID}
|
||||
ENV ARM_TEST_LOCATION=${BUILD_ARM_TEST_LOCATION}
|
||||
ENV ARM_TEST_LOCATION_ALT=${BUILD_ARM_TEST_LOCATION_ALT}
|
||||
|
||||
RUN mkdir /usr/src/${MODULE_NAME}
|
||||
COPY . /usr/src/${MODULE_NAME}
|
||||
WORKDIR /usr/src/${MODULE_NAME}
|
||||
|
||||
# Set work directory
|
||||
RUN mkdir /go
|
||||
RUN mkdir /go/bin
|
||||
RUN mkdir /go/src
|
||||
RUN mkdir /go/src/${MODULE_NAME}
|
||||
COPY . /go/src/${MODULE_NAME}
|
||||
WORKDIR /go/src/${MODULE_NAME}
|
||||
|
||||
# Install required go packages using dep ensure
|
||||
ENV GOPATH /go
|
||||
ENV PATH /usr/local/go/bin:$GOPATH/bin:$PATH
|
||||
RUN /bin/bash -c "curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh"
|
||||
|
||||
RUN ["bundle", "install", "--gemfile", "./Gemfile"]
|
|
@ -0,0 +1,9 @@
|
|||
SHELL := /bin/bash
|
||||
|
||||
-include $(shell curl -sSL "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/scripts/install.sh" | bash -s > /dev/null ; echo tfmod-scaffold/GNUmakefile)
|
||||
|
||||
init:
|
||||
@sh "$(CURDIR)/scripts/init.sh"
|
||||
|
||||
cleanup:
|
||||
@sh "$(CURDIR)/scripts/cleanup.sh"
|
9
Gemfile
9
Gemfile
|
@ -1,9 +0,0 @@
|
|||
ruby "~> 2.3.0"
|
||||
|
||||
source 'https://rubygems.org/'
|
||||
|
||||
group :test do
|
||||
git 'https://github.com/Azure/terramodtest.git' do
|
||||
gem 'terramodtest', :tag => 'v0.2.0'
|
||||
end
|
||||
end
|
|
@ -1,62 +0,0 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b62a3c5b37db602bf1158e921da1a762315a4c37855fd418a14498aa87a342d5"
|
||||
name = "cloud.google.com/go"
|
||||
packages = ["civil"]
|
||||
pruneopts = "UT"
|
||||
revision = "aad3f485ee528456e0768f20397b4d9dd941e755"
|
||||
version = "v0.25.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:fb4971cce8da66e5060d9f392ab341f4394daa4cbbfb7eb858f14e1ba41d58b9"
|
||||
name = "github.com/denisenkom/go-mssqldb"
|
||||
packages = [
|
||||
".",
|
||||
"internal/cp",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "242fa5aa1b45aeb9fcdfeee88822982e3f548e22"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:517998a1f5034f85bdaf26c29f677f34509e772240e81f1ba9c2ba6eb0636981"
|
||||
name = "github.com/gruntwork-io/terratest"
|
||||
packages = [
|
||||
"modules/collections",
|
||||
"modules/logger",
|
||||
"modules/retry",
|
||||
"modules/shell",
|
||||
"modules/terraform",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a3246fed2e3e40b345e13a745e435b36b17d0c16"
|
||||
version = "v0.9.15"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7d80d5561efbfcfdc3e4720bf5e331d574fd6f1e531b115ecf568aab3e2b656d"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["md4"]
|
||||
pruneopts = "UT"
|
||||
revision = "c126467f60eb25f8f27e5a981f32a87e3965053f"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:76ee51c3f468493aff39dbacc401e8831fbb765104cbf613b89bef01cf4bad70"
|
||||
name = "golang.org/x/net"
|
||||
packages = ["context"]
|
||||
pruneopts = "UT"
|
||||
revision = "c4299a1a0d8524c11563db160fbf9bddbceadb21"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/denisenkom/go-mssqldb",
|
||||
"github.com/gruntwork-io/terratest/modules/retry",
|
||||
"github.com/gruntwork-io/terratest/modules/terraform",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
38
Gopkg.toml
38
Gopkg.toml
|
@ -1,38 +0,0 @@
|
|||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/denisenkom/go-mssqldb"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gruntwork-io/terratest"
|
||||
version = "0.9.15"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
181
README.md
181
README.md
|
@ -1,7 +1,5 @@
|
|||
# terraform-azurerm-database
|
||||
|
||||
[![Build Status](https://travis-ci.org/Azure/terraform-azurerm-database.svg?branch=master)](https://travis-ci.org/Azure/terraform-azurerm-database)
|
||||
|
||||
## Create an Azure SQL Database
|
||||
|
||||
This Terraform module creates a basic Azure SQL Database.
|
||||
|
@ -17,84 +15,89 @@ module "sql-database" {
|
|||
sql_admin_username = "mradministrator"
|
||||
sql_password = "P@ssw0rd12345!"
|
||||
|
||||
tags = {
|
||||
environment = "dev"
|
||||
costcenter = "it"
|
||||
}
|
||||
|
||||
tags = {
|
||||
environment = "dev"
|
||||
costcenter = "it"
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Test
|
||||
## Pre-Commit & Pr-Check & Test
|
||||
|
||||
### Configurations
|
||||
|
||||
- [Configure Terraform for Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/terraform-install-configure)
|
||||
|
||||
We provide 2 ways to build, run, and test the module on a local development machine. [Native (Mac/Linux)](#native-maclinux) or [Docker](#docker).
|
||||
We assumed that you have setup service principal's credentials in your environment variables like below:
|
||||
|
||||
### Native(Mac/Linux)
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- [Ruby **(~> 2.3)**](https://www.ruby-lang.org/en/downloads/)
|
||||
- [Bundler **(~> 1.15)**](https://bundler.io/)
|
||||
- [Terraform **(~> 0.11.7)**](https://www.terraform.io/downloads.html)
|
||||
- [Golang **(~> 1.10.3)**](https://golang.org/dl/)
|
||||
|
||||
#### Environment setup
|
||||
|
||||
We provide simple script to quickly set up module development environment:
|
||||
|
||||
```sh
|
||||
$ curl -sSL https://raw.githubusercontent.com/Azure/terramodtest/master/tool/env_setup.sh | sudo bash
|
||||
```shell
|
||||
export ARM_SUBSCRIPTION_ID="<azure_subscription_id>"
|
||||
export ARM_TENANT_ID="<azure_subscription_tenant_id>"
|
||||
export ARM_CLIENT_ID="<service_principal_appid>"
|
||||
export ARM_CLIENT_SECRET="<service_principal_password>"
|
||||
```
|
||||
|
||||
#### Run test
|
||||
On Windows Powershell:
|
||||
|
||||
Then simply run it in local shell:
|
||||
|
||||
```sh
|
||||
$ cd $GOPATH/src/{directory_name}/
|
||||
$ bundle install
|
||||
$ rake build
|
||||
$ rake e2e
|
||||
```shell
|
||||
$env:ARM_SUBSCRIPTION_ID="<azure_subscription_id>"
|
||||
$env:ARM_TENANT_ID="<azure_subscription_tenant_id>"
|
||||
$env:ARM_CLIENT_ID="<service_principal_appid>"
|
||||
$env:ARM_CLIENT_SECRET="<service_principal_password>"
|
||||
```
|
||||
|
||||
### Docker
|
||||
We provide a docker image to run the pre-commit checks and tests for you: `mcr.microsoft.com/azterraform:latest`
|
||||
|
||||
We provide a Dockerfile to build a new image based `FROM` the `microsoft/terraform-test` Docker hub image which adds additional tools / packages specific for this module (see Custom Image section). Alternatively use only the `microsoft/terraform-test` Docker hub image [by using these instructions](https://github.com/Azure/terraform-test).
|
||||
To run the pre-commit task, we can run the following command:
|
||||
|
||||
```shell
|
||||
$ docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make pre-commit
|
||||
```
|
||||
|
||||
On Windows Powershell:
|
||||
|
||||
```shell
|
||||
$ docker run --rm -v ${pwd}:/src -w /src mcr.microsoft.com/azterraform:latest make pre-commit
|
||||
```
|
||||
|
||||
In pre-commit task, we will:
|
||||
|
||||
1. Run `terraform fmt -recursive` command for your Terraform code.
|
||||
2. Run `terrafmt fmt -f` command for markdown files and go code files to ensure that the Terraform code embedded in these files are well formatted.
|
||||
3. Run `go mod tidy` and `go mod vendor` for test folder to ensure that all the dependencies have been synced.
|
||||
4. Run `gofmt` for all go code files.
|
||||
5. Run `gofumpt` for all go code files.
|
||||
6. Run `terraform-docs` on `README.md` file, then run `markdown-table-formatter` to format markdown tables in `README.md`.
|
||||
|
||||
Then we can run the pr-check task to check whether our code meets our pipeline's requirement(We strongly recommend you run the following command before you commit):
|
||||
|
||||
```shell
|
||||
$ docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make pr-check
|
||||
```
|
||||
|
||||
On Windows Powershell:
|
||||
|
||||
```shell
|
||||
$ docker run --rm -v ${pwd}:/src -w /src mcr.microsoft.com/azterraform:latest make pr-check
|
||||
```
|
||||
|
||||
To run the e2e-test, we can run the following command:
|
||||
|
||||
```text
|
||||
docker run --rm -v $(pwd):/src -w /src -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_CLIENT_ID -e ARM_CLIENT_SECRET mcr.microsoft.com/azterraform:latest make e2e-test
|
||||
```
|
||||
|
||||
On Windows Powershell:
|
||||
|
||||
```text
|
||||
docker run --rm -v ${pwd}:/src -w /src -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_CLIENT_ID -e ARM_CLIENT_SECRET mcr.microsoft.com/azterraform:latest make e2e-test
|
||||
```
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- [Docker](https://www.docker.com/community-edition#/download)
|
||||
|
||||
#### Build the image
|
||||
|
||||
```sh
|
||||
$ docker build --build-arg BUILD_ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID --build-arg BUILD_ARM_CLIENT_ID=$ARM_CLIENT_ID --build-arg BUILD_ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET --build-arg BUILD_ARM_TENANT_ID=$ARM_TENANT_ID -t azure-database-module .
|
||||
```
|
||||
|
||||
#### Run test (Docker)
|
||||
|
||||
This runs the build and unit tests:
|
||||
|
||||
```sh
|
||||
$ docker run --rm azure-database-module /bin/bash -c "bundle install && rake build"
|
||||
```
|
||||
|
||||
This runs the end to end tests:
|
||||
|
||||
```sh
|
||||
$ docker run --rm azure-database-module /bin/bash -c "bundle install && rake e2e"
|
||||
```
|
||||
|
||||
This runs the full tests:
|
||||
|
||||
```sh
|
||||
$ docker run --rm azure-database-module /bin/bash -c "bundle install && rake full"
|
||||
```
|
||||
|
||||
## Authors
|
||||
|
||||
Originally created by [James Earle](http://github.com/JamesEarle)
|
||||
|
@ -102,3 +105,61 @@ Originally created by [James Earle](http://github.com/JamesEarle)
|
|||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
<!-- BEGIN_TF_DOCS -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|---------------------------------------------------------------------------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.2 |
|
||||
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~>3.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|---------------------------------------------------------------|---------|
|
||||
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | ~>3.0 |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|-----------------------------------------------------------------------------------------------------------------------------------|----------|
|
||||
| [azurerm_resource_group.rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
|
||||
| [azurerm_sql_database.db](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/sql_database) | resource |
|
||||
| [azurerm_sql_firewall_rule.fw](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/sql_firewall_rule) | resource |
|
||||
| [azurerm_sql_server.server](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/sql_server) | resource |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|----------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|----------------------------------------------------|:--------:|
|
||||
| <a name="input_collation"></a> [collation](#input\_collation) | The collation for the database. Default is SQL\_Latin1\_General\_CP1\_CI\_AS | `string` | `"SQL_Latin1_General_CP1_CI_AS"` | no |
|
||||
| <a name="input_db_edition"></a> [db\_edition](#input\_db\_edition) | The edition of the database to be created. | `string` | `"Basic"` | no |
|
||||
| <a name="input_db_name"></a> [db\_name](#input\_db\_name) | The name of the database to be created. | `string` | n/a | yes |
|
||||
| <a name="input_end_ip_address"></a> [end\_ip\_address](#input\_end\_ip\_address) | Defines the end IP address used in your database firewall rule. | `string` | `"0.0.0.0"` | no |
|
||||
| <a name="input_location"></a> [location](#input\_location) | The location/region where the database and server are created. Changing this forces a new resource to be created. | `string` | n/a | yes |
|
||||
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Default resource group name that the database will be created in. | `string` | `"myapp-rg"` | no |
|
||||
| <a name="input_server_version"></a> [server\_version](#input\_server\_version) | The version for the database server. Valid values are: 2.0 (for v11 server) and 12.0 (for v12 server). | `string` | `"12.0"` | no |
|
||||
| <a name="input_service_objective_name"></a> [service\_objective\_name](#input\_service\_objective\_name) | The performance level for the database. For the list of acceptable values, see https://docs.microsoft.com/en-gb/azure/sql-database/sql-database-service-tiers. Default is Basic. | `string` | `"Basic"` | no |
|
||||
| <a name="input_sql_admin_username"></a> [sql\_admin\_username](#input\_sql\_admin\_username) | The administrator username of the SQL Server. | `string` | n/a | yes |
|
||||
| <a name="input_sql_password"></a> [sql\_password](#input\_sql\_password) | The administrator password of the SQL Server. | `string` | n/a | yes |
|
||||
| <a name="input_start_ip_address"></a> [start\_ip\_address](#input\_start\_ip\_address) | Defines the start IP address used in your database firewall rule. | `string` | `"0.0.0.0"` | no |
|
||||
| <a name="input_tags"></a> [tags](#input\_tags) | The tags to associate with your network and subnets. | `map(string)` | <pre>{<br> "tag1": "",<br> "tag2": ""<br>}</pre> | no |
|
||||
| <a name="input_tracing_tags_enabled"></a> [tracing\_tags\_enabled](#input\_tracing\_tags\_enabled) | Whether enable tracing tags that generated by BridgeCrew Yor. | `bool` | `false` | no |
|
||||
| <a name="input_tracing_tags_prefix"></a> [tracing\_tags\_prefix](#input\_tracing\_tags\_prefix) | Default prefix for generated tracing tags | `string` | `"avm_"` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|---------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------|
|
||||
| <a name="output_connection_string"></a> [connection\_string](#output\_connection\_string) | Connection string for the Azure SQL Database created. |
|
||||
| <a name="output_database_name"></a> [database\_name](#output\_database\_name) | Database name of the Azure SQL Database created. |
|
||||
| <a name="output_sql_server_fqdn"></a> [sql\_server\_fqdn](#output\_sql\_server\_fqdn) | Fully Qualified Domain Name (FQDN) of the Azure SQL Database created. |
|
||||
| <a name="output_sql_server_location"></a> [sql\_server\_location](#output\_sql\_server\_location) | Location of the Azure SQL Database created. |
|
||||
| <a name="output_sql_server_name"></a> [sql\_server\_name](#output\_sql\_server\_name) | Server name of the Azure SQL Database created. |
|
||||
| <a name="output_sql_server_version"></a> [sql\_server\_version](#output\_sql\_server\_version) | Version the Azure SQL Database created. |
|
||||
<!-- END_TF_DOCS -->
|
||||
|
|
54
Rakefile
54
Rakefile
|
@ -1,54 +0,0 @@
|
|||
# Official gems.
|
||||
require 'colorize'
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
# Git repo gems.
|
||||
require 'bundler/setup'
|
||||
require 'terramodtest'
|
||||
|
||||
namespace :presteps do
|
||||
task :ensure do
|
||||
puts "Using dep ensure to install required go packages.\n"
|
||||
success = system ("dep ensure")
|
||||
if not success
|
||||
raise "ERROR: Dep ensure failed!\n".red
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
namespace :static do
|
||||
task :style do
|
||||
style_tf
|
||||
end
|
||||
task :lint do
|
||||
lint_tf
|
||||
end
|
||||
task :format do
|
||||
format_tf
|
||||
end
|
||||
end
|
||||
|
||||
namespace :integration do
|
||||
task :test do
|
||||
success = system ("go test -v ./test/ -timeout 20m")
|
||||
if not success
|
||||
raise "ERROR: Go test failed!\n".red
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
task :prereqs => [ 'presteps:ensure' ]
|
||||
|
||||
task :validate => [ 'static:style', 'static:lint' ]
|
||||
|
||||
task :format => [ 'static:format' ]
|
||||
|
||||
task :build => [ 'prereqs', 'validate' ]
|
||||
|
||||
task :unit => []
|
||||
|
||||
task :e2e => [ 'prereqs', 'integration:test' ]
|
||||
|
||||
task :default => [ 'build' ]
|
||||
|
||||
task :full => [ 'build', 'unit', 'e2e' ]
|
|
@ -0,0 +1,18 @@
|
|||
resource "random_id" "name" {
|
||||
byte_length = 8
|
||||
}
|
||||
|
||||
resource "random_password" "password" {
|
||||
length = 20
|
||||
}
|
||||
|
||||
module "sql_database" {
|
||||
source = "../.."
|
||||
resource_group_name = "${var.resource_group_name}-${random_id.name.hex}"
|
||||
location = var.location
|
||||
db_name = "${var.db_name}-${random_id.name.hex}"
|
||||
sql_admin_username = var.sql_admin_username
|
||||
sql_password = random_password.password.result
|
||||
start_ip_address = var.start_ip_address
|
||||
end_ip_address = var.end_ip_address
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
output "database_name" {
|
||||
value = module.sql_database.database_name
|
||||
}
|
||||
|
||||
output "sql_server_name" {
|
||||
value = module.sql_database.sql_server_name
|
||||
}
|
||||
|
||||
output "sql_server_fqdn" {
|
||||
value = module.sql_database.sql_server_fqdn
|
||||
}
|
||||
|
||||
output "sql_admin_username" {
|
||||
value = var.sql_admin_username
|
||||
}
|
||||
|
||||
output "sql_password" {
|
||||
sensitive = true
|
||||
value = random_password.password.result
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
terraform {
|
||||
required_version = ">= 1.2"
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "~>3.0"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = ">=3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
|
@ -1,27 +1,29 @@
|
|||
variable "resource_group_name" {
|
||||
type = string
|
||||
default = "mssqlResourceGroup"
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
default = "westus2"
|
||||
type = string
|
||||
default = "westeurope"
|
||||
}
|
||||
|
||||
variable "db_name" {
|
||||
type = string
|
||||
default = "mydatabase"
|
||||
}
|
||||
|
||||
variable "sql_admin_username" {
|
||||
type = string
|
||||
default = "azureuser"
|
||||
}
|
||||
|
||||
variable "sql_password" {
|
||||
default = "P@ssw0rd12345!"
|
||||
}
|
||||
|
||||
variable "start_ip_address" {
|
||||
type = string
|
||||
default = "0.0.0.0"
|
||||
}
|
||||
|
||||
variable "end_ip_address" {
|
||||
type = string
|
||||
default = "255.255.255.255"
|
||||
}
|
55
main.tf
55
main.tf
|
@ -1,41 +1,42 @@
|
|||
# provider "azurerm" {
|
||||
# subscription_id = "REPLACE-WITH-YOUR-SUBSCRIPTION-ID"
|
||||
# client_id = "REPLACE-WITH-YOUR-CLIENT-ID"
|
||||
# client_secret = "REPLACE-WITH-YOUR-CLIENT-SECRET"
|
||||
# tenant_id = "REPLACE-WITH-YOUR-TENANT-ID"
|
||||
# }
|
||||
|
||||
resource "azurerm_resource_group" "rg" {
|
||||
name = "${var.resource_group_name}"
|
||||
location = "${var.location}"
|
||||
location = var.location
|
||||
name = var.resource_group_name
|
||||
tags = var.tags
|
||||
}
|
||||
|
||||
resource "azurerm_sql_database" "db" {
|
||||
name = "${var.db_name}"
|
||||
resource_group_name = "${azurerm_resource_group.rg.name}"
|
||||
location = "${var.location}"
|
||||
edition = "${var.db_edition}"
|
||||
collation = "${var.collation}"
|
||||
server_name = "${azurerm_sql_server.server.name}"
|
||||
location = var.location
|
||||
name = var.db_name
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
server_name = azurerm_sql_server.server.name
|
||||
collation = var.collation
|
||||
create_mode = "Default"
|
||||
requested_service_objective_name = "${var.service_objective_name}"
|
||||
tags = "${var.tags}"
|
||||
edition = var.db_edition
|
||||
requested_service_objective_name = var.service_objective_name
|
||||
tags = var.tags
|
||||
}
|
||||
|
||||
resource "azurerm_sql_server" "server" {
|
||||
#checkov:skip=CKV2_AZURE_7:We don't change tf config for now
|
||||
#checkov:skip=CKV2_AZURE_2:We don't change tf config for now
|
||||
#checkov:skip=CKV_AZURE_24:We don't change tf config for now
|
||||
#checkov:skip=CKV_AZURE_23:We don't change tf config for now
|
||||
#checkov:skip=CKV2_AZURE_6:We don't change tf config for now
|
||||
administrator_login = var.sql_admin_username
|
||||
administrator_login_password = var.sql_password
|
||||
location = var.location
|
||||
name = "${var.db_name}-sqlsvr"
|
||||
resource_group_name = "${azurerm_resource_group.rg.name}"
|
||||
location = "${var.location}"
|
||||
version = "${var.server_version}"
|
||||
administrator_login = "${var.sql_admin_username}"
|
||||
administrator_login_password = "${var.sql_password}"
|
||||
tags = "${var.tags}"
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
version = var.server_version
|
||||
tags = var.tags
|
||||
}
|
||||
|
||||
resource "azurerm_sql_firewall_rule" "fw" {
|
||||
#checkov:skip=CKV_AZURE_11:We don't change tf config for now
|
||||
end_ip_address = var.end_ip_address
|
||||
name = "${var.db_name}-fwrules"
|
||||
resource_group_name = "${azurerm_resource_group.rg.name}"
|
||||
server_name = "${azurerm_sql_server.server.name}"
|
||||
start_ip_address = "${var.start_ip_address}"
|
||||
end_ip_address = "${var.end_ip_address}"
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
server_name = azurerm_sql_server.server.name
|
||||
start_ip_address = var.start_ip_address
|
||||
}
|
||||
|
||||
|
|
41
outputs.tf
41
outputs.tf
|
@ -1,29 +1,30 @@
|
|||
output "connection_string" {
|
||||
description = "Connection string for the Azure SQL Database created."
|
||||
sensitive = true
|
||||
value = "Server=tcp:${azurerm_sql_server.server.fully_qualified_domain_name},1433;Initial Catalog=${azurerm_sql_database.db.name};Persist Security Info=False;User ID=${azurerm_sql_server.server.administrator_login};Password=${azurerm_sql_server.server.administrator_login_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
|
||||
}
|
||||
|
||||
output "database_name" {
|
||||
description = "Database name of the Azure SQL Database created."
|
||||
value = "${azurerm_sql_database.db.name}"
|
||||
}
|
||||
|
||||
output "sql_server_name" {
|
||||
description = "Server name of the Azure SQL Database created."
|
||||
value = "${azurerm_sql_server.server.name}"
|
||||
}
|
||||
|
||||
output "sql_server_location" {
|
||||
description = "Location of the Azure SQL Database created."
|
||||
value = "${azurerm_sql_server.server.location}"
|
||||
}
|
||||
|
||||
output "sql_server_version" {
|
||||
description = "Version the Azure SQL Database created."
|
||||
value = "${azurerm_sql_server.server.version}"
|
||||
value = azurerm_sql_database.db.name
|
||||
}
|
||||
|
||||
output "sql_server_fqdn" {
|
||||
description = "Fully Qualified Domain Name (FQDN) of the Azure SQL Database created."
|
||||
value = "${azurerm_sql_server.server.fully_qualified_domain_name}"
|
||||
value = azurerm_sql_server.server.fully_qualified_domain_name
|
||||
}
|
||||
|
||||
output "connection_string" {
|
||||
description = "Connection string for the Azure SQL Database created."
|
||||
value = "Server=tcp:${azurerm_sql_server.server.fully_qualified_domain_name},1433;Initial Catalog=${azurerm_sql_database.db.name};Persist Security Info=False;User ID=${azurerm_sql_server.server.administrator_login};Password=${azurerm_sql_server.server.administrator_login_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
|
||||
output "sql_server_location" {
|
||||
description = "Location of the Azure SQL Database created."
|
||||
value = azurerm_sql_server.server.location
|
||||
}
|
||||
|
||||
output "sql_server_name" {
|
||||
description = "Server name of the Azure SQL Database created."
|
||||
value = azurerm_sql_server.server.name
|
||||
}
|
||||
|
||||
output "sql_server_version" {
|
||||
description = "Version the Azure SQL Database created."
|
||||
value = azurerm_sql_server.server.version
|
||||
}
|
||||
|
|
|
@ -1,127 +1,129 @@
|
|||
package test
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"testing"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
// Microsoft SQL Database driver
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
// Microsoft SQL Database driver
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
)
|
||||
|
||||
// DBConfig using server name, user name, password and database name
|
||||
type DBConfig struct {
|
||||
server string
|
||||
user string
|
||||
password string
|
||||
database string
|
||||
server string
|
||||
user string
|
||||
password string
|
||||
database string
|
||||
}
|
||||
|
||||
// DBConnection connects to the database using database configuration and database type, i.e. mssql, and then return the database. If there's any error, fail the test.
|
||||
func DBConnection(t *testing.T, dbType string, dbConfig DBConfig) *sql.DB {
|
||||
db, err := DBConnectionE(t, dbType, dbConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return db
|
||||
db, err := DBConnectionE(t, dbType, dbConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
// DBConnectionE connects to the database using database configuration and database type, i.e. mssql. Return the database or an error.
|
||||
func DBConnectionE(t *testing.T, dbType string, dbConfig DBConfig) (*sql.DB, error) {
|
||||
config := fmt.Sprintf("server = %s; user id = %s; password = %s; database = %s", dbConfig.server, dbConfig.user, dbConfig.password, dbConfig.database)
|
||||
db, err := sql.Open(dbType, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
config := fmt.Sprintf("server = %s; user id = %s; password = %s; database = %s", dbConfig.server, dbConfig.user, dbConfig.password, dbConfig.database)
|
||||
db, err := sql.Open(dbType, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// DBExecution executes specific SQL commands, i.e. insertion. If there's any error, fail the test.
|
||||
func DBExecution(t *testing.T, db *sql.DB, command string) {
|
||||
_, err := DBExecutionE(t, db, command)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err := DBExecutionE(t, db, command)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// DBExecutionE executes specific SQL commands, i.e. insertion. Return the result or an error.
|
||||
func DBExecutionE(t *testing.T, db *sql.DB, command string) (sql.Result, error) {
|
||||
result, err := db.Exec(command)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
result, err := db.Exec(command)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DBQuery queries from database, i.e. selection, and then return the result. If there's any error, fail the test.
|
||||
func DBQuery(t *testing.T, db *sql.DB, command string) *sql.Rows {
|
||||
rows, err := DBQueryE(t, db, command)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return rows
|
||||
rows, err := DBQueryE(t, db, command)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DBQueryE queries from database, i.e. selection. Return the result or an error.
|
||||
func DBQueryE(t *testing.T, db *sql.DB, command string) (*sql.Rows, error) {
|
||||
rows, err := db.Query(command)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rows, nil
|
||||
rows, err := db.Query(command)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// DBQueryWithValidation queries from database and validate whether the result is the same as expected text. If there's any error, fail the test.
|
||||
func DBQueryWithValidation(t *testing.T, db *sql.DB, command string, expected string) {
|
||||
err := DBQueryWithValidationE(t, db, command, expected)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err := DBQueryWithValidationE(t, db, command, expected)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// DBQueryWithValidationE queries from database and validate whether the result is the same as expected text. If not, return an error.
|
||||
func DBQueryWithValidationE(t *testing.T, db *sql.DB, command string, expected string) error {
|
||||
return DBQueryWithCustomValidationE(t, db, command, func(rows *sql.Rows) bool {
|
||||
var name string
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if name != expected {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
return DBQueryWithCustomValidationE(t, db, command, func(rows *sql.Rows) bool {
|
||||
var name string
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if name != expected {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
// DBQueryWithCustomValidation queries from database and validate whether the result meets the requirement. If there's any error, fail the test.
|
||||
func DBQueryWithCustomValidation(t *testing.T, db *sql.DB, command string, validateResponse func(*sql.Rows) bool) {
|
||||
err := DBQueryWithCustomValidationE(t, db, command, validateResponse)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err := DBQueryWithCustomValidationE(t, db, command, validateResponse)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// DBQueryWithCustomValidationE queries from database and validate whether the result meets the requirement. If not, return an error.
|
||||
func DBQueryWithCustomValidationE(t *testing.T, db *sql.DB, command string, validateResponse func(*sql.Rows) bool) error {
|
||||
rows, err := DBQueryE(t, db, command)
|
||||
defer rows.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !validateResponse(rows) {
|
||||
return ValidationFunctionFailed{command}
|
||||
}
|
||||
return nil
|
||||
rows, err := DBQueryE(t, db, command)
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !validateResponse(rows) {
|
||||
return ValidationFunctionFailed{command}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidationFunctionFailed is an error that occurs if the validation fails.
|
||||
type ValidationFunctionFailed struct {
|
||||
command string
|
||||
command string
|
||||
}
|
||||
|
||||
func (err ValidationFunctionFailed) Error() string {
|
||||
return fmt.Sprintf("Validation failed for command: %s.", err.command)
|
||||
return fmt.Sprintf("Validation failed for command: %s.", err.command)
|
||||
}
|
|
@ -1,34 +1,31 @@
|
|||
package test
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
test_helper "github.com/Azure/terraform-module-test-helper"
|
||||
"github.com/gruntwork-io/terratest/modules/retry"
|
||||
"github.com/gruntwork-io/terratest/modules/terraform"
|
||||
)
|
||||
|
||||
func TestTerraformDatabase(t *testing.T) {
|
||||
t.Parallel()
|
||||
opt := terraform.Options{}
|
||||
test_helper.RunE2ETest(t, "../../",
|
||||
"examples/basic",
|
||||
opt,
|
||||
assertDbFunctional)
|
||||
}
|
||||
|
||||
terraformOptions := &terraform.Options{
|
||||
// The path to where our Terraform code is located
|
||||
TerraformDir: "./fixture",
|
||||
|
||||
// Variables to pass to our Terraform code using -var options
|
||||
Vars: map[string]interface{}{},
|
||||
}
|
||||
|
||||
// This will init and apply the resources and fail the test if there are any errors
|
||||
terraform.InitAndApply(t, terraformOptions)
|
||||
|
||||
// Setting database configuration, including server name, user name, password and database name
|
||||
func assertDbFunctional(t *testing.T, output test_helper.TerraformOutput) {
|
||||
var dbConfig DBConfig
|
||||
dbConfig.server = terraform.Output(t, terraformOptions, "sql_server_fqdn")
|
||||
dbConfig.user = terraform.Output(t, terraformOptions, "sql_admin_username")
|
||||
dbConfig.password = terraform.Output(t, terraformOptions, "sql_password")
|
||||
dbConfig.database = terraform.Output(t, terraformOptions, "database_name")
|
||||
dbConfig.server = output["sql_server_fqdn"].(string)
|
||||
dbConfig.user = output["sql_admin_username"].(string)
|
||||
dbConfig.password = output["sql_password"].(string)
|
||||
dbConfig.database = output["database_name"].(string)
|
||||
|
||||
// It can take a minute or so for the database to boot up, so retry a few times
|
||||
maxRetries := 15
|
||||
|
@ -36,7 +33,7 @@ func TestTerraformDatabase(t *testing.T) {
|
|||
description := fmt.Sprintf("Executing commands on database %s", dbConfig.server)
|
||||
|
||||
// Verify that we can connect to the database and run SQL commands
|
||||
retry.DoWithRetry(t, description, maxRetries, timeBetweenRetries, func() (string, error) {
|
||||
_, err := retry.DoWithRetryE(t, description, maxRetries, timeBetweenRetries, func() (string, error) {
|
||||
// Connect to specific database, i.e. mssql
|
||||
db, err := DBConnectionE(t, "mssql", dbConfig)
|
||||
if err != nil {
|
||||
|
@ -62,11 +59,11 @@ func TestTerraformDatabase(t *testing.T) {
|
|||
DBExecution(t, db, drop)
|
||||
fmt.Println("Executed SQL commands correctly")
|
||||
|
||||
defer db.Close()
|
||||
defer func() {
|
||||
_ = db.Close()
|
||||
}()
|
||||
|
||||
return "", nil
|
||||
})
|
||||
|
||||
// At the end of the test, clean up any resources that were created
|
||||
terraform.Destroy(t, terraformOptions)
|
||||
assert.NoError(t, err)
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
provider "random" {
|
||||
version = "~> 1.0"
|
||||
}
|
||||
|
||||
resource "random_id" "name" {
|
||||
byte_length = 8
|
||||
}
|
||||
|
||||
module "sql-database" {
|
||||
source = "../../"
|
||||
resource_group_name = "${var.resource_group_name}-${random_id.name.hex}"
|
||||
location = "${var.location}"
|
||||
db_name = "${var.db_name}-${random_id.name.hex}"
|
||||
sql_admin_username = "${var.sql_admin_username}"
|
||||
sql_password = "${var.sql_password}"
|
||||
start_ip_address = "${var.start_ip_address}"
|
||||
end_ip_address = "${var.end_ip_address}"
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
output "database_name" {
|
||||
value = "${module.sql-database.database_name}"
|
||||
}
|
||||
|
||||
output "sql_server_name" {
|
||||
value = "${module.sql-database.sql_server_name}"
|
||||
}
|
||||
|
||||
output "sql_server_fqdn" {
|
||||
value = "${module.sql-database.sql_server_fqdn}"
|
||||
}
|
||||
|
||||
output "sql_admin_username" {
|
||||
value = "${var.sql_admin_username}"
|
||||
}
|
||||
|
||||
output "sql_password" {
|
||||
value = "${var.sql_password}"
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
resource_group_name = "mssqlResourceGroup"
|
||||
location = "westeurope"
|
||||
db_name = "mydatabase"
|
||||
sql_admin_username = "azureuser"
|
||||
sql_password = "P@ssw0rd12345!"
|
||||
start_ip_address = "0.0.0.0"
|
||||
end_ip_address = "255.255.255.255"
|
|
@ -0,0 +1,106 @@
|
|||
module github.com/Azure/terraform-azurerm-database
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/Azure/terraform-module-test-helper v0.13.0
|
||||
github.com/denisenkom/go-mssqldb v0.12.3
|
||||
github.com/gruntwork-io/terratest v0.41.24
|
||||
github.com/stretchr/testify v1.8.2
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.105.0 // indirect
|
||||
cloud.google.com/go/compute v1.12.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.1 // indirect
|
||||
cloud.google.com/go/iam v0.7.0 // indirect
|
||||
cloud.google.com/go/storage v1.27.0 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/ahmetb/go-linq/v3 v3.2.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.122 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
|
||||
github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect
|
||||
github.com/go-logr/logr v0.2.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-github/v42 v42.0.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
|
||||
github.com/googleapis/gnostic v0.4.1 // indirect
|
||||
github.com/gruntwork-io/go-commons v0.8.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-getter v1.7.1 // indirect
|
||||
github.com/hashicorp/go-getter/v2 v2.2.1 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.0 // indirect
|
||||
github.com/hashicorp/go-safetemp v1.0.0 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.16.2 // indirect
|
||||
github.com/hashicorp/terraform-config-inspect v0.0.0-20211115214459-90acf1ca460f // indirect
|
||||
github.com/hashicorp/terraform-json v0.16.0 // indirect
|
||||
github.com/imdario/mergo v0.3.11 // indirect
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.11 // indirect
|
||||
github.com/klauspost/compress v1.15.11 // indirect
|
||||
github.com/lonegunmanb/tfmodredirector v0.1.0 // indirect
|
||||
github.com/magodo/hclgrep v0.0.0-20220303061548-1b2b24c7caf6 // indirect
|
||||
github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 // indirect
|
||||
github.com/minamijoyo/hcledit v0.2.6 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/pquerna/otp v1.2.0 // indirect
|
||||
github.com/r3labs/diff/v3 v3.0.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/tmccombs/hcl2json v0.3.3 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/urfave/cli v1.22.2 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/zclconf/go-cty v1.13.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.1.0 // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/oauth2 v0.7.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/term v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.103.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c // indirect
|
||||
google.golang.org/grpc v1.51.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.20.6 // indirect
|
||||
k8s.io/apimachinery v0.20.6 // indirect
|
||||
k8s.io/client-go v0.20.6 // indirect
|
||||
k8s.io/klog/v2 v2.4.0 // indirect
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
95
variables.tf
95
variables.tf
|
@ -1,60 +1,87 @@
|
|||
variable "resource_group_name" {
|
||||
description = "Default resource group name that the database will be created in."
|
||||
default = "myapp-rg"
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
description = "The location/region where the database and server are created. Changing this forces a new resource to be created."
|
||||
}
|
||||
|
||||
variable "server_version" {
|
||||
description = "The version for the database server. Valid values are: 2.0 (for v11 server) and 12.0 (for v12 server)."
|
||||
default = "12.0"
|
||||
}
|
||||
|
||||
variable "db_name" {
|
||||
type = string
|
||||
description = "The name of the database to be created."
|
||||
}
|
||||
|
||||
variable "db_edition" {
|
||||
description = "The edition of the database to be created."
|
||||
default = "Basic"
|
||||
}
|
||||
|
||||
variable "service_objective_name" {
|
||||
description = "The performance level for the database. For the list of acceptable values, see https://docs.microsoft.com/en-gb/azure/sql-database/sql-database-service-tiers. Default is Basic."
|
||||
default = "Basic"
|
||||
}
|
||||
|
||||
variable "collation" {
|
||||
description = "The collation for the database. Default is SQL_Latin1_General_CP1_CI_AS"
|
||||
default = "SQL_Latin1_General_CP1_CI_AS"
|
||||
variable "location" {
|
||||
type = string
|
||||
description = "The location/region where the database and server are created. Changing this forces a new resource to be created."
|
||||
}
|
||||
|
||||
variable "sql_admin_username" {
|
||||
type = string
|
||||
description = "The administrator username of the SQL Server."
|
||||
}
|
||||
|
||||
variable "sql_password" {
|
||||
type = string
|
||||
description = "The administrator password of the SQL Server."
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "start_ip_address" {
|
||||
description = "Defines the start IP address used in your database firewall rule."
|
||||
default = "0.0.0.0"
|
||||
variable "collation" {
|
||||
type = string
|
||||
default = "SQL_Latin1_General_CP1_CI_AS"
|
||||
description = "The collation for the database. Default is SQL_Latin1_General_CP1_CI_AS"
|
||||
}
|
||||
|
||||
variable "db_edition" {
|
||||
type = string
|
||||
default = "Basic"
|
||||
description = "The edition of the database to be created."
|
||||
}
|
||||
|
||||
variable "end_ip_address" {
|
||||
description = "Defines the end IP address used in your database firewall rule."
|
||||
type = string
|
||||
default = "0.0.0.0"
|
||||
description = "Defines the end IP address used in your database firewall rule."
|
||||
}
|
||||
|
||||
variable "resource_group_name" {
|
||||
type = string
|
||||
default = "myapp-rg"
|
||||
description = "Default resource group name that the database will be created in."
|
||||
}
|
||||
|
||||
variable "server_version" {
|
||||
type = string
|
||||
default = "12.0"
|
||||
description = "The version for the database server. Valid values are: 2.0 (for v11 server) and 12.0 (for v12 server)."
|
||||
}
|
||||
|
||||
variable "service_objective_name" {
|
||||
type = string
|
||||
default = "Basic"
|
||||
description = "The performance level for the database. For the list of acceptable values, see https://docs.microsoft.com/en-gb/azure/sql-database/sql-database-service-tiers. Default is Basic."
|
||||
}
|
||||
|
||||
variable "start_ip_address" {
|
||||
type = string
|
||||
default = "0.0.0.0"
|
||||
description = "Defines the start IP address used in your database firewall rule."
|
||||
}
|
||||
|
||||
variable "tags" {
|
||||
description = "The tags to associate with your network and subnets."
|
||||
type = "map"
|
||||
|
||||
type = map(string)
|
||||
default = {
|
||||
tag1 = ""
|
||||
tag2 = ""
|
||||
}
|
||||
description = "The tags to associate with your network and subnets."
|
||||
}
|
||||
|
||||
# tflint-ignore: terraform_unused_declarations
|
||||
variable "tracing_tags_enabled" {
|
||||
type = bool
|
||||
default = false
|
||||
description = "Whether enable tracing tags that generated by BridgeCrew Yor."
|
||||
nullable = false
|
||||
}
|
||||
|
||||
# tflint-ignore: terraform_unused_declarations
|
||||
variable "tracing_tags_prefix" {
|
||||
type = string
|
||||
default = "avm_"
|
||||
description = "Default prefix for generated tracing tags"
|
||||
nullable = false
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
terraform {
|
||||
required_version = ">= 1.2"
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "~>3.0"
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче