diff --git a/README.md b/README.md index 0126b43..4be0d6a 100644 --- a/README.md +++ b/README.md @@ -63,9 +63,9 @@ brew install optum/tap/runiac Download the pre-compiled binaries from the [releases](https://github.com/Optum/runiac/releases) page and copy to the desired location. -## Tutorial +## Getting Started -For more detailed examples of runiac, be sure to check out the [examples](examples/) directory! +For more detailed examples of runiac, be sure to check out the [starters on github!](https://github.com/topics/runiac-starter) ## Using runiac diff --git a/cmd/cli/cmd/new_test.go b/cmd/cli/cmd/new_test.go new file mode 100644 index 0000000..4543751 --- /dev/null +++ b/cmd/cli/cmd/new_test.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNew(t *testing.T) { + tests := map[string]string{ + "foobar": "foobar", + "foo()bar": "foo__bar", + "!234 Test": "_234_Test", + "!@#$%^&*()": "__________", + "trailing space ": "trailing_space", + "\nwhite space\n\t": "white_space", + "domain\\user": "domain_user", + } + + for in, expected := range tests { + result := sanitizeMachineName(in) + + require.Equal(t, expected, result, "sanitizeMachineName(\"%s\") = \"%s\"; want \"%s\"", in, result, expected) + } +} diff --git a/examples/arm-azure-hello-world/README.md b/examples/arm-azure-hello-world/README.md deleted file mode 100644 index 3331b54..0000000 --- a/examples/arm-azure-hello-world/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# ARM Template Basic runiac Examples for Azure - -This example will provide a simple starting point for working with runiac and deploying resources into -a Microsoft Azure subscription using ARM templates. - -The following steps assume you are running on a Linux or macOS system, but the process will most likely be similar on Windows. - -## Requirements - -See the top-level README for information on obtaining these items: - -- An Azure subscription - -## Running - -If you did not clone this repository, you can have runiac scaffold a copy of this example by running: - -```bash -runiac new --url github.com/optum/runiac//examples/arm-azure-hello-world -``` - -Assuming you've set up your subscription and login credentials, you can execute runiac using the following command: - -```bash -runiac -a --dry-run -``` - -This will run runiac without commiting any infrastructure changes. You can view the output to see if it aligns with expectations. The example -creates a [resource group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group), and a storage -account using ARM templates. You can add more resources within the `step1_default` directory. - -To deploy infrastructure changes, you can run the following command instead: - -```bash -runiac -a -e -``` - -Review the output to validate that your infrastructure changes have been deployed. - -Finally, You can clean up any resources that were created by running runiac with the `--self-destroy` flag: - -```bash -runiac -a -e --self-destroy -``` - -## Important Notes - -This example assumes you are using your own login credentials to deploy infrastructure. In a real world situation, you most likely will -want to use a [service principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals), especially -if you intend to use runiac in a CI/CD pipeline. - -In the context of an Azure YAML pipeline, you can obtain these values by setting the `addSpnToEnvironment` input to `true` on the -[AzureCLI@2](https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-cli?view=azure-devops) task. diff --git a/examples/arm-azure-hello-world/entrypoint.sh b/examples/arm-azure-hello-world/entrypoint.sh deleted file mode 100755 index 2cfef28..0000000 --- a/examples/arm-azure-hello-world/entrypoint.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -if az account get-access-token ; then - echo "already logged in..." -else - az login; -fi - -runiac diff --git a/examples/arm-azure-hello-world/runiac.yml b/examples/arm-azure-hello-world/runiac.yml deleted file mode 100644 index 2ac409e..0000000 --- a/examples/arm-azure-hello-world/runiac.yml +++ /dev/null @@ -1,4 +0,0 @@ -project: azure-hello-world -primary_region: southcentralus -regional_regions: centralus -runner: arm \ No newline at end of file diff --git a/examples/arm-azure-hello-world/step1_default/main.json b/examples/arm-azure-hello-world/step1_default/main.json deleted file mode 100644 index a215fa1..0000000 --- a/examples/arm-azure-hello-world/step1_default/main.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "rgName": { - "type": "string", - "defaultValue": "rg-arm" - }, - "rgLocation": { - "type": "string", - "defaultValue": "southcentralus" - }, - "storagePrefix": { - "type": "string", - "maxLength": 11, - "defaultValue": "st" - } - }, - "variables": { - "storageName": "[concat(parameters('storagePrefix'), uniqueString(subscription().id, parameters('rgName')))]" - }, - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "apiVersion": "2020-06-01", - "name": "[parameters('rgName')]", - "location": "[parameters('rgLocation')]", - "properties": {} - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2020-06-01", - "name": "storageDeployment", - "resourceGroup": "[parameters('rgName')]", - "dependsOn": [ - "[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": {}, - "variables": {}, - "resources": [ - { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2019-06-01", - "name": "[variables('storageName')]", - "location": "[parameters('rgLocation')]", - "sku": { - "name": "Standard_LRS" - }, - "kind": "StorageV2" - } - ], - "outputs": {} - } - } - } - ], - "outputs": {} - } \ No newline at end of file diff --git a/examples/terraform-azure-hello-world/README.md b/examples/terraform-azure-hello-world-multi-region/README.md similarity index 93% rename from examples/terraform-azure-hello-world/README.md rename to examples/terraform-azure-hello-world-multi-region/README.md index 67a8485..4e6e8c9 100644 --- a/examples/terraform-azure-hello-world/README.md +++ b/examples/terraform-azure-hello-world-multi-region/README.md @@ -22,15 +22,10 @@ The following steps assume you are running on a Linux or macOS system, but the p See the top-level README for information on obtaining these items: - An Azure subscription +- Docker ## Running -If you did not clone this repository, you can have runiac scaffold a copy of this example by running: - -```bash -runiac new --url github.com/optum/runiac//examples/terraform-azure-hello-world -``` - Assuming you've set up your subscription and login credentials, you can execute runiac using the following command: ```bash diff --git a/examples/terraform-azure-hello-world/entrypoint.sh b/examples/terraform-azure-hello-world-multi-region/entrypoint.sh similarity index 100% rename from examples/terraform-azure-hello-world/entrypoint.sh rename to examples/terraform-azure-hello-world-multi-region/entrypoint.sh diff --git a/examples/terraform-azure-hello-world/runiac.yml b/examples/terraform-azure-hello-world-multi-region/runiac.yml similarity index 52% rename from examples/terraform-azure-hello-world/runiac.yml rename to examples/terraform-azure-hello-world-multi-region/runiac.yml index 4593267..b883725 100644 --- a/examples/terraform-azure-hello-world/runiac.yml +++ b/examples/terraform-azure-hello-world-multi-region/runiac.yml @@ -1,4 +1,4 @@ project: azure-hello-world primary_region: centralus -regional_regions: centralus +regional_regions: centralus,eastus,westus,uksouth,southeastasia runner: terraform diff --git a/examples/terraform-azure-hello-world/step1_default/backend.tf b/examples/terraform-azure-hello-world-multi-region/step1_default/backend.tf similarity index 100% rename from examples/terraform-azure-hello-world/step1_default/backend.tf rename to examples/terraform-azure-hello-world-multi-region/step1_default/backend.tf diff --git a/examples/terraform-azure-hello-world-multi-region/step1_default/main.tf b/examples/terraform-azure-hello-world-multi-region/step1_default/main.tf new file mode 100644 index 0000000..c1bad5a --- /dev/null +++ b/examples/terraform-azure-hello-world-multi-region/step1_default/main.tf @@ -0,0 +1,4 @@ +resource azurerm_resource_group hub { + name = "${local.namespace-}rg-runiac-hub-${var.runiac_region}" + location = var.runiac_region +} \ No newline at end of file diff --git a/examples/terraform-azure-hello-world/step1_default/providers.tf b/examples/terraform-azure-hello-world-multi-region/step1_default/providers.tf similarity index 100% rename from examples/terraform-azure-hello-world/step1_default/providers.tf rename to examples/terraform-azure-hello-world-multi-region/step1_default/providers.tf diff --git a/examples/terraform-gcp-hello-world/step1_default/backend.tf b/examples/terraform-azure-hello-world-multi-region/step1_default/regional/backend.tf similarity index 57% rename from examples/terraform-gcp-hello-world/step1_default/backend.tf rename to examples/terraform-azure-hello-world-multi-region/step1_default/regional/backend.tf index dada2be..0ae1a48 100644 --- a/examples/terraform-gcp-hello-world/step1_default/backend.tf +++ b/examples/terraform-azure-hello-world-multi-region/step1_default/regional/backend.tf @@ -1,6 +1,6 @@ terraform { backend "local" { - path = "default.tfstate" + path = "azure/${var.runiac_step}/terraform.tfstate" workspace_dir = "/runiac/tfstate" } } diff --git a/examples/terraform-azure-hello-world-multi-region/step1_default/regional/main.tf b/examples/terraform-azure-hello-world-multi-region/step1_default/regional/main.tf new file mode 100644 index 0000000..54fe00e --- /dev/null +++ b/examples/terraform-azure-hello-world-multi-region/step1_default/regional/main.tf @@ -0,0 +1,4 @@ +resource "azurerm_resource_group" "spoke" { + name = "${local.namespace-}rg-runiac-spoke-${var.runiac_region}" + location = var.runiac_region +} diff --git a/examples/terraform-azure-hello-world-multi-region/step1_default/regional/providers.tf b/examples/terraform-azure-hello-world-multi-region/step1_default/regional/providers.tf new file mode 100644 index 0000000..8805d92 --- /dev/null +++ b/examples/terraform-azure-hello-world-multi-region/step1_default/regional/providers.tf @@ -0,0 +1,14 @@ +# Configure the Azure Provider +provider "azurerm" { + subscription_id = var.runiac_account_id + features {} +} + +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 2.58.0" + } + } +} \ No newline at end of file diff --git a/examples/terraform-azure-hello-world-multi-region/step1_default/regional/variables.tf b/examples/terraform-azure-hello-world-multi-region/step1_default/regional/variables.tf new file mode 100644 index 0000000..9e326aa --- /dev/null +++ b/examples/terraform-azure-hello-world-multi-region/step1_default/regional/variables.tf @@ -0,0 +1,27 @@ +locals { + namespace- = var.runiac_namespace == "" ? "" : "${var.runiac_namespace}-" +} + +variable "runiac_account_id" { + type = string +} + +variable "runiac_region" { + type = string +} + +variable "runiac_environment" { + type = string +} + +variable "runiac_namespace" { + type = string +} + +variable "runiac_step" { + type = string +} + +variable "runiac_primary_region" { + type = string +} \ No newline at end of file diff --git a/examples/terraform-azure-hello-world/step1_default/variables.tf b/examples/terraform-azure-hello-world-multi-region/step1_default/variables.tf similarity index 85% rename from examples/terraform-azure-hello-world/step1_default/variables.tf rename to examples/terraform-azure-hello-world-multi-region/step1_default/variables.tf index b362f65..d50a5b1 100644 --- a/examples/terraform-azure-hello-world/step1_default/variables.tf +++ b/examples/terraform-azure-hello-world-multi-region/step1_default/variables.tf @@ -22,7 +22,7 @@ variable runiac_step { type = string } -variable resource_group { +variable runiac_step { type = string - default = "rg-runiac-sample" } + diff --git a/examples/terraform-azure-hello-world-multi-region/t-rec.gif b/examples/terraform-azure-hello-world-multi-region/t-rec.gif new file mode 100644 index 0000000..7ee9f82 Binary files /dev/null and b/examples/terraform-azure-hello-world-multi-region/t-rec.gif differ diff --git a/examples/terraform-azure-hello-world/step1_default/main.tf b/examples/terraform-azure-hello-world/step1_default/main.tf deleted file mode 100644 index 8faceb9..0000000 --- a/examples/terraform-azure-hello-world/step1_default/main.tf +++ /dev/null @@ -1,4 +0,0 @@ -resource azurerm_resource_group example { - name = "${local.namespace-}${var.resource_group}" - location = var.runiac_region -} \ No newline at end of file diff --git a/examples/terraform-gcp-hello-world/.gitignore b/examples/terraform-gcp-hello-world/.gitignore deleted file mode 100644 index 29992b7..0000000 --- a/examples/terraform-gcp-hello-world/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -credentials.json -state/*.tfstate* \ No newline at end of file diff --git a/examples/terraform-gcp-hello-world/README.md b/examples/terraform-gcp-hello-world/README.md deleted file mode 100644 index 3aad1d9..0000000 --- a/examples/terraform-gcp-hello-world/README.md +++ /dev/null @@ -1,74 +0,0 @@ - - - -**Table of Contents** _generated with [DocToc](https://github.com/thlorenz/doctoc)_ - -- [Hello World runiac Project for Google Cloud Platform](#hello-world-runiac-project-for-google-cloud-platform) - - [Requirements](#requirements) - - [Running](#running) - - [Important Notes](#important-notes) - - - -# Hello World runiac Project for Google Cloud Platform - -This example will provide a starting point for working with runiac and deploying resources into -a Google Cloud Platform project. - -The following steps assume you are running on a Linux or macOS system, but the process will be similar on Windows. - -## Requirements - -See the top-level README for information on obtaining these items: - -- A Google Cloud Platform project - -## Running - -If you did not clone this repository, you can have runiac scaffold a copy of this example by running: - -```bash -runiac new --url github.com/optum/runiac//examples/terraform-gcp-hello-world -``` - -Assuming you've set up your service account credentials, you can execute runiac using the following command: - -```bash -runiac deploy -a -e --dry-run -``` - -This will run runiac without committing any infrastructure changes. You can view the output to see if it aligns with expectations. The example -creates a [GCP Storage bucket](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket) in your project, -you can add more resources under the `step1_default` directory. - -To deploy infrastructure changes, you can run the following command instead: - -```bash -runiac deploy -a -e -``` - -Review the output to validate that your infrastructure changes have been deployed. - -Finally, You can clean up any resources that were created by running Terrscale with the `--self-destroy` flag: - -```bash -runiac deploy -a -e --self-destroy -``` - -## Important Notes - -Be aware that some Google Cloud Platform resources are not deleted immediately. Common examples include [IAM roles](https://cloud.google.com/iam/docs/creating-custom-roles#deleting-custom-role), among others, which remain in the system for a period of time before finally being purged -(ie: soft deletes). The Terraform provider documentation will usually [call this out](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam_custom_role) in a warning. - -This has implications on ephemeral deployments; you cannot create a role with a given name, run runiac with the `--self-destroy` flag -in this example, and rerun runiac immediately afterwards. GCP will detect a conflict when the same role is created again, and as a result, your -deployment will fail. - -For these types of resources, the recommendation is to only deploy them to non-ephemeral environments. You can leverage Terraform's `count` property -and runiac's `namespace` variable to conditionally deploy such resources: - -```hcl-terraform -resource "google_project_iam_custom_role" "my-custom-role" { - count = var.namespace != "" ? 0 : 1 -} -``` diff --git a/examples/terraform-gcp-hello-world/entrypoint.sh b/examples/terraform-gcp-hello-world/entrypoint.sh deleted file mode 100644 index 0eb2eac..0000000 --- a/examples/terraform-gcp-hello-world/entrypoint.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -if gcloud auth application-default print-access-token ; then - echo "already logged in to gcp..." -else - gcloud auth application-default login - gcloud config set project "$RUNIAC_ACCOUNT_ID" -fi - - - -runiac \ No newline at end of file diff --git a/examples/terraform-gcp-hello-world/runiac.yml b/examples/terraform-gcp-hello-world/runiac.yml deleted file mode 100644 index 7536397..0000000 --- a/examples/terraform-gcp-hello-world/runiac.yml +++ /dev/null @@ -1,4 +0,0 @@ -project: gcp-hello-world -primary_region: us-central1 -regional_regions: us-central1 -runner: terraform \ No newline at end of file diff --git a/examples/terraform-gcp-hello-world/step1_default/main.tf b/examples/terraform-gcp-hello-world/step1_default/main.tf deleted file mode 100644 index 234ca7c..0000000 --- a/examples/terraform-gcp-hello-world/step1_default/main.tf +++ /dev/null @@ -1,6 +0,0 @@ -resource google_storage_bucket example { - // namespace is used to enable local ("--local") deployment ring configurations, specific to the executors machine - name = "${local.runiac_namespace-}runiac-example-bucket" - force_destroy = true - uniform_bucket_level_access = true -} diff --git a/examples/terraform-gcp-hello-world/step1_default/providers.tf b/examples/terraform-gcp-hello-world/step1_default/providers.tf deleted file mode 100644 index 5e0fdf4..0000000 --- a/examples/terraform-gcp-hello-world/step1_default/providers.tf +++ /dev/null @@ -1,5 +0,0 @@ -# Configure the Azure Provider -provider "google" { - project = var.runiac_account_id - region = var.runiac_region -} diff --git a/examples/terraform-gcp-hello-world/step1_default/variables.tf b/examples/terraform-gcp-hello-world/step1_default/variables.tf deleted file mode 100644 index 2283dc2..0000000 --- a/examples/terraform-gcp-hello-world/step1_default/variables.tf +++ /dev/null @@ -1,23 +0,0 @@ -locals { - runiac_namespace- = var.runiac_namespace == "" ? "" : "${var.runiac_namespace}-" -} - -variable runiac_account_id { - type = string -} - -variable runiac_namespace { - type = string -} - -variable runiac_region { - type = string -} - -variable runiac_environment { - type = string -} - -variable runiac_step { - type = string -} \ No newline at end of file diff --git a/scripts/build_containers.sh b/scripts/build_containers.sh index 0f14470..66faf5e 100755 --- a/scripts/build_containers.sh +++ b/scripts/build_containers.sh @@ -10,14 +10,14 @@ then push=true fi -rm -rf ./reports -outputVolume=$(docker volume create) +rm -rf ./reports; +outputVolume=$(docker volume create); DOCKER_BUILDKIT=1 docker build -f "build/package/alpine-builder/Dockerfile" -t "runiac:alpine-builder" . || exit 1; -CID=$(docker create -v "$outputVolume":/reports "runiac:alpine-builder") -docker cp "$CID":/reports $(pwd) -touch ./reports/*.xml -docker rm "$CID" -docker volume rm "$outputVolume" +CID=$(docker create -v "$outputVolume":/reports "runiac:alpine-builder"); +docker cp "$CID":/reports $(pwd); +touch ./reports/*.xml; +docker rm "$CID"; +docker volume rm "$outputVolume"; # Build consumer images