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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Build and Test
on:
push:
pull_request:
repository_dispatch:
types: build-on-release

jobs:
build:
name: Build
runs-on: ubuntu-latest
if: github.event_name != 'repository_dispatch' || github.event.client_payload.prerelease == 'false'
env:
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
AZURE_REGION: ${{ secrets.ARM_REGION }}

steps:
- name: Tag for Repository Dispatch event
if: github.event_name == 'repository_dispatch'
run: |
tag_name="${{ github.event.client_payload.tag }}"
version_number="$(echo "$tag_name" | sed 's/v//')"
count="$(echo "$version_number" | awk -F"." '{print NF-1}')"
if [[ $count -eq 2 ]]; then
version_number="$(echo "$version_number" | sed 's/$/.0/')"
fi
if [[ "$(echo "$version_number" | awk -F"." '{print NF-1}')" -ne 3 ]]; then
echo "The tag '$tag_name' is invalid" 1>&2
exit 1
fi
echo "::set-env name=TAG_NAME::$version_number"

- name: Setup Go 1.13
uses: actions/setup-go@v1
with:
go-version: 1.13.5
id: go

- name: Setup Terraform environment
uses: marocchino/setup-terraform@v1.0.1
with:
# The terraform version to download (if necessary) and use. Example: 0.12.13
version: 0.12.13

- name: Check out code into the Go module directory
uses: actions/checkout@v1
with:
submodules: true

- name: Get dependencies
run: |
cd ./test
go mod download

- name: Build
run: |
cd ./test
go test -v -timeout 40m yugabyte_test.go

147 changes: 113 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,61 @@
# terraform-azure-yugabyte
A Terraform module to deploy and run YugabyteDB on Microsoft Azure Cloud.

## Config
* First create a terraform file with provider details
## Configuration
* To insatll terraform and configure it for Azure follow steps given [here](https://docs.microsoft.com/en-gb/azure/virtual-machines/linux/terraform-install-configure)

* Export the required credentials in current shell
```sh
echo "Setting environment variables for Terraform"
export ARM_SUBSCRIPTION_ID="your_subscription_id"
export ARM_CLIENT_ID="your_appId"
export ARM_CLIENT_SECRET="your_password"
export ARM_TENANT_ID="your_tenant_id"
```
provider "azurerm"
{
# Provide your Azure Creadentilals
subscription_id = "AZURE_SUBSCRIPTION_ID"
client_id = "AZURE_CLIENT_ID"
client_secret = "AZURE_CLIENT_SECRET"
tenant_id = "AZURE_TENANT_ID"
}
```
Note :- To insatll terraform and configure it for Azure follow steps given [here](https://docs.microsoft.com/en-gb/azure/virtual-machines/linux/terraform-install-configure)

* Now add the yugabyte terraform module to your file
<!-- The above code snippet is from
https://github.com/MicrosoftDocs/azure-docs/blob/eb381218252a33fb8b63e1163b6a39cd4b1835ef/articles/terraform/terraform-install-configure.md#configure-terraform-environment-variables
which is licensed under the MIT
license. https://github.com/MicrosoftDocs/azure-docs/blob/master/LICENSE-CODE
-->

* Create a new directory along with a terraform file
```sh
$ mkdir yugabytedb-deploy && cd yugabytedb-deploy
$ touch deploy.tf
```
* Open `deploy.tf` in your favorite editor and add following content to
it
```hcl
module "yugabyte-db-cluster" {
source = "github.com/YugaByte/terraform-azure-yugabyte.git"
source = "github.com/yugabyte/terraform-azure-yugabyte.git"

# The name of the cluster to be created.
cluster_name = "test-yugabyte"
# The name of the cluster to be created.
cluster_name = "test-yugabyte"

# key pair.
ssh_private_key = "SSH_PRIVATE_KEY_HERE"
ssh_public_key = "SSH_PUBLIC_KEY_HERE"
ssh_user = "SSH_USER_NAME_HERE"
# key pair.
ssh_private_key = "PATH_TO_SSH_PRIVATE_KEY_FILE"
ssh_public_key = "PATH_TO_SSH_PUBLIC_KEY_FILE"
ssh_user = "SSH_USER_NAME"

# The region name where the nodes should be spawned.
region_name = "YOUR VPC REGION"
# The region name where the nodes should be spawned.
region_name = "YOUR VPC REGION"

# The name of resource group in which all Azure resource will be created.
resource_group = "test-yugabyte"
# The name of resource group in which all Azure resource will be created.
resource_group = "test-yugabyte"

# Replication factor.
replication_factor = "3"
# Replication factor.
replication_factor = "3"

# The number of nodes in the cluster, this cannot be lower than the replication factor.
node_count = "3"
# The number of nodes in the cluster, this cannot be lower than the replication factor.
node_count = "3"
}
```

output "ui" {
value = "${module.yugabyte-db-cluster.ui}"
}

# You can add other outputs from output.tf here
```

## Usage

Expand All @@ -57,20 +71,19 @@ To check what changes are going to happen in the environment run the following
$ terraform plan
```


Now run the following to create the instances and bring up the cluster.

```
$ terraform apply
```

Once the cluster is created, you can go to the URL `http://<node ip or dns name>:7000` to view the UI. You can find the node's ip or dns by running the following:
Once the cluster is created, you can go to the URL `http://<node ip or dns name>:7000` to view the UI. You can find the node's public IP by running the following:

```
$ terraform state show azurerm_virtual_machine.YugaByte-Node[0]
$ terraform state show module.yugabyte-db-cluster.azurerm_public_ip.YugaByte_Public_IP[0]
```

You can access the cluster UI by going to any of the following URLs.
You can access the cluster UI by going to public IP address of any of the instances at port `7000`. The IP address can be viewed by replacing `0` from above command with desired index.

You can check the state of the nodes at any point by running the following command.

Expand All @@ -84,3 +97,69 @@ To destroy what we just created, you can run the following command.
$ terraform destroy
```
`Note:- To make any changes in the created cluster you will need the terraform state files. So don't delete state files of Terraform.`

## Migrating from old versions
### Changes in #6 (terraform 0.12.x and azurerm 2.x)
In order to migrate to the latest revision of this module which uses terraform `0.12.x` and azurerm `2.x`,
* Download [latest version](https://www.terraform.io/downloads.html) of terraform which is >= `0.12`
* Remove the `provider "azurerm" {}` block from your terraform file and set the credentials by following the instructions [here](#configuration).
* Pull the latest code of yugabyte-db-cluster module.
```sh
$ terraform get -update
```
* Get the latets versions of the dependencies.
```sh
$ terraform init
```
* Download the migration script in same directory as of your terraform files.
```sh
$ curl -O -L https://raw.githubusercontent.com/yugabyte/terraform-azure-yugabyte/master/hack/azurerm_1.x_to_2.x.sh
$ chmod +x azurerm_1.x_to_2.x.sh
```
* Run the script as `./azurerm_1.x_to_2.x.sh <number of nodes>`
```console
$ ./azurerm_1.x_to_2.x.sh 3
Importing 'module.yugabyte-db-cluster.azurerm_network_interface_security_group_association.YugaByte-NIC-SG-Association[2]'.
module.yugabyte-db-cluster.azurerm_network_interface_security_group_association.YugaByte-NIC-SG-Association[2]: Importing from ID "<networkInterfaceID>|<networkSecurityGroupId>"...
module.yugabyte-db-cluster.azurerm_network_interface_security_group_association.YugaByte-NIC-SG-Association[2]: Import prepared!
Prepared azurerm_network_interface_security_group_association for import
module.yugabyte-db-cluster.azurerm_network_interface_security_group_association.YugaByte-NIC-SG-Association[2]: Refreshing state... [id=<networkInterfaceID>|<networkSecurityGroupId>]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
```
* Run terraform apply to update the state correctly.
```sh
$ terraform apply
```

## Test

### Environment setup

* To run the terratest manually, install terraform and configure it for azure by following steps [here](https://docs.microsoft.com/en-gb/azure/virtual-machines/linux/terraform-install-configure)

* Review environment variables from [configuration section](Configuration)

* Set `AZURE_REGION` environment variable as well. This region will be used to create all Azure resources

* Clone [this](https://github.com/yugabyte/terraform-azure-yugabyte) repository

* Install [Golang](https://golang.org/) and check out this repo into your `GOPATH`


#### Run test

* Change your working directory to the `test` folder in your checked out directory.

* Then simply run it in the local shell:

```sh
$ go test -v -timeout 40m yugabyte_test.go
```
* Note that go has a default test timeout of 10 minutes. With infrastructure testing, your tests will surpass the 10 minutes very easily. To extend the timeout, you can pass in the -timeout option, which takes a go duration string (e.g 10m for 10 minutes or 1h for 1 hour). In the above command, we use the -timeout option to override to a 40 minute timeout.
* When you hit the timeout, Go automatically exits the test, skipping all cleanup routines. This is problematic for infrastructure testing because it will skip your deferred infrastructure cleanup steps (i.e terraform destroy), leaving behind the infrastructure that was spun up. So it is important to use a longer timeout every time you run the tests. If time out happens before destroying all resources, manual cleanup is required.

53 changes: 53 additions & 0 deletions hack/azurerm_1.x_to_2.x.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash

# This script can be used to migrate from azurerm version 1.x to 2.x.
# To check if you have 1.x, run the following command.
#
# $ terraform version
# Terraform v0.11.14
# + provider.azurerm v1.44.0
# + provider.null v2.1.2
#
# Make sure you update to a terraform version which is >= 0.12.0
#
# Pull the latest code of yugabyte-db-cluster module.
#
# $ terraform get -update
#
# Get the latets versions of the dependencies
#
# $ terraform init
#
# Now put this script in same directory as of your terraform files,
# and execute it
#
# ./azurerm_1.x_to_2.x.sh
#
# Run terraform apply to update the state correctly
#
# $ terraform apply

node_count="${1:-3}"

if [[ -z "$(which jq 2>/dev/null)" ]]; then
echo "jq: command not found. This script depends on jq." 1>&2
exit 1
fi

security_group_id="$(terraform show -json \
| jq -r '.values.root_module.child_modules[0].resources[]
| select(.address == "azurerm_network_security_group.YugaByte-SG")
| .values.id')"

for ((index=0; index < $((node_count)); index++)); do
interface_id="$(terraform show -json \
| jq --arg index "${index}" -r \
'.values.root_module.child_modules[0].resources[]
| select(.address == "azurerm_network_interface.YugaByte-NIC" and .index == ($index|tonumber))
| .values.id')"
resoure_address="module.yugabyte-db-cluster.azurerm_network_interface_security_group_association.YugaByte-NIC-SG-Association[${index}]"
echo "Importing '${resoure_address}'."
terraform import \
"${resoure_address}" \
"${interface_id}|${security_group_id}"
done
Loading