Skip to content

Commit

Permalink
Merge pull request #10 from TerraHubCorp/dev
Browse files Browse the repository at this point in the history
Transform HCL into TerraHub config with template
  • Loading branch information
eistrati authored Mar 3, 2019
2 parents 9247ee0 + 954e404 commit 72e54ae
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 265 deletions.
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Local .terraform directories
# Local hidden directories
**/.terraform/*
**/.backup/*

# .tfstate files
**/*.tf*
# Local .tfstate files
*.tfstate
*.tfstate.*

# Zipped google function
google_function/demo.*
28 changes: 12 additions & 16 deletions .terrahub.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
## project config
project:
name: demo-terraform-automation-google
code: f2754a99
include: ['.']
exclude: ['**/.terraform/*', '**/node_modules/*']

## template config
code: 7b3c5d2c
include:
- .
exclude:
- '**/.terraform/**'
- '**/node_modules/**'
- '**/.git/**'
terraform:
varFile:
- default.tfvars
version: 0.11.11
template:
provider:
google: {}
locals:
google_project_id: project-123456789012
google_region: us-central1
google_org_id: 123456789012
google_service_account_name: demo-team
google_project_id: terrahub-123456
google_billing_account: 123456-ABCDEF-ZYXWVU
google_location_id: us-central

## terraform config
terraform:
varFile: ['default.tfvars']
version: 0.11.7
150 changes: 91 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,11 @@ Manual Setup (set values in double quotes and run the following command in termi
```shell
export GOOGLE_CLOUD_PROJECT="" ## e.g. terrahub-123456
export GOOGLE_APPLICATION_CREDENTIALS="" ## e.g. ${HOME}/.config/gcloud/terraform.json
export ORG_ID="" ## e.g. 123456789012
export BILLING_ID="" ## e.g. 123456-ABCDEF-ZYXWVU
export PROJECT_NAME="" ## e.g. TerraHub
export IAM_NAME="" ## e.g. terraform
export IAM_DESC="" ## e.g. terraform service account
```

### Setup ORG_ID Programmatically

Automated Setup (run the following command in terminal):
```shell
export ORG_ID="$(gcloud organizations list --format=json | jq '.[0].name[14:]')"
```

> NOTE: If you don't have JQ CLI, check out this
[installation guide](https://stedolan.github.io/jq/download/)

### Setup BILLING_ID Programmatically

Automated Setup (run the following command in terminal):
Expand All @@ -49,18 +37,15 @@ Run the following command in terminal:
```shell
gcloud projects create ${GOOGLE_CLOUD_PROJECT} \
--name="${PROJECT_NAME}" \
--organization="${ORG_ID}" \
--set-as-default

gcloud config set project ${GOOGLE_CLOUD_PROJECT}
gcloud beta billing projects link ${GOOGLE_CLOUD_PROJECT} \
--billing-account="${BILLING_ID}"

gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable cloudbilling.googleapis.com
gcloud services enable iam.googleapis.com
gcloud services enable compute.googleapis.com

gcloud beta billing projects link ${GOOGLE_CLOUD_PROJECT} \
--billing-account="${BILLING_ID}"
gcloud services enable cloudfunctions.googleapis.com
```

Your output should be similar to the one below:
Expand Down Expand Up @@ -95,23 +80,6 @@ Your output should be similar to the one below:
```
```

## Add IAM Policy Binding to Google Cloud Organization

Run the following command in terminal:
```shell
gcloud organizations add-iam-policy-binding ${ORG_ID} \
--member="serviceAccount:${IAM_NAME}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/resourcemanager.projectCreator"

gcloud organizations add-iam-policy-binding ${ORG_ID} \
--member="serviceAccount:${IAM_NAME}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/billing.user"
```

Your output should be similar to the one below:
```
```

## Create Terraform Configurations Using TerraHub

Run the following commands in terminal:
Expand All @@ -123,80 +91,144 @@ Your output should be similar to the one below:
```
Usage: terrahub [command] [options]
terrahub@0.1.28 (built: 2019-02-08T17:17:41.912Z)
terrahub@0.0.1 (built: 2018-04-07T19:15:39.787Z)
```

> NOTE: If you don't have TerraHub CLI, check out this
[installation guide](https://www.npmjs.com/package/terrahub)

Run the following command in terminal:
```shell
mkdir demo-terraform-google
cd demo-terraform-google
terrahub project -n demo-terraform-google
mkdir demo-terraform-automation-google
cd demo-terraform-automation-google
terrahub project -n demo-terraform-automation-google
```

Your output should be similar to the one below:
```
✅ Project successfully initialized
```

## Create TerraHub Components
## Create TerraHub Components from Templates

Run the following command in terminal:
```shell
terrahub component -t google_project -n project
terrahub component -t google_service_account -n service_account -o ../project
terrahub component -t google_service_account_key -n service_account_key -o ../service_account
terrahub component -t google_project_iam_member -n project_iam_member -o ../project
terrahub component -t google_project_iam_binding -n project_iam_policy_binding_storage_admin -o ../project_iam_member
terrahub component -t google_project_iam_binding -n project_iam_policy_binding_compute_admin -o ../project_iam_member
terrahub component -t google_storage_bucket -n google_storage \
&& terrahub component -t google_cloudfunctions_function -n google_function -o ../google_storage
```

Your output should be similar to the one below:
```
✅ Done
```

## Visualize TerraHub Components
## Update Project Config

Run the following command in terminal:
```shell
terrahub graph
terrahub configure -c terraform.version=0.11.11
terrahub configure -c template.provider.google={}
terrahub configure -c template.locals.google_project_id="${GOOGLE_CLOUD_PROJECT}"
terrahub configure -c template.locals.google_billing_account="${BILLING_ID}"
```

Your output should be similar to the one below:
```
Project: demo-terraform-google
└─ project [path: ./project]
├─ project_iam_member [path: ./project_iam_member]
│ ├─ project_iam_binding_compute_admin [path: ./project_iam_binding_compute_admin]
│ └─ project_iam_binding_storage_admin [path: ./project_iam_binding_storage_admin]
└─ service_account [path: ./service_account]
└─ service_account_key [path: ./service_account_key]
✅ Done
```

## Update Project Config
## Customize TerraHub Component for Storage Bucket

Run the following command in terminal:
```shell
terrahub configure -c template.locals.google_org_id="${ORG_ID}"
terrahub configure -c template.locals.google_billing_account="${BILLING_ID}"
terrahub configure -c template.locals.google_project_id="${GOOGLE_CLOUD_PROJECT}"
terrahub configure -i google_storage -c component.template.terraform.backend.local.path='/tmp/.terrahub/local_backend/google_storage/terraform.tfstate'
terrahub configure -i google_storage -c component.template.resource.google_storage_bucket.google_storage.name='demo_terraform_automation_${local.project["code"]}'
terrahub configure -i google_storage -c component.template.resource.google_storage_bucket.google_storage.location='US'
terrahub configure -i google_storage -c component.template.resource.google_storage_bucket.google_storage.project='${local.google_project_id}'
terrahub configure -i google_storage -c component.template.variable -D -y
```

Your output should be similar to the one below:
```
✅ Done
```

## Customize TerraHub Component for Google Cloud Function

Run the following command in terminal:
```shell
terrahub configure -i google_function -c component.template.terraform.backend.local.path='/tmp/.terrahub/local_backend/google_function/terraform.tfstate'
terrahub configure -i google_function -c component.template.data.terraform_remote_state.storage.backend='local'
terrahub configure -i google_function -c component.template.data.terraform_remote_state.storage.config.path='/tmp/.terrahub/local_backend/google_storage/terraform.tfstate'
terrahub configure -i google_function -c component.template.resource.google_storage_bucket_object.google_storage_object.name='demo.zip'
terrahub configure -i google_function -c component.template.resource.google_storage_bucket_object.google_storage_object.bucket='${data.terraform_remote_state.storage.thub_id}'
terrahub configure -i google_function -c component.template.resource.google_storage_bucket_object.google_storage_object.source='./demo.zip'
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.depends_on[0]='google_storage_bucket_object.google_storage_object'
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.name='demofunction${local.project["code"]}'
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.region='us-central1'
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.runtime='nodejs8'
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.description='My demo function'
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.available_memory_mb=128
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.source_archive_bucket='${data.terraform_remote_state.storage.thub_id}'
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.source_archive_object='${google_storage_bucket_object.google_storage_object.name}'
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.trigger_http=true
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.timeout=60
terrahub configure -i google_function -c component.template.resource.google_cloudfunctions_function.google_function.entry_point='helloGET'
terrahub configure -i google_function -c component.template.variable -D -y
terrahub configure -i google_function -c component.template.output -D -y
terrahub configure -i google_function -c component.template.output.id.value='${google_cloudfunctions_function.google_function.id}'
terrahub configure -i google_function -c component.template.output.trigger_url.value='${google_cloudfunctions_function.google_function.https_trigger_url}'
terrahub configure -i google_function -c build.env.variables.THUB_FUNCTION_ZIP='demo.zip'
terrahub configure -i google_function -c build.env.variables.THUB_BUILD_PATH='..'
terrahub configure -i google_function -c build.env.variables.THUB_FUNCTION_TXT='demo.txt'
terrahub configure -i google_function -c build.env.variables.THUB_BUILD_OK='true'
terrahub configure -i google_function -c build.phases.pre_build.commands[0]='echo "BUILD: Running pre_build step"'
terrahub configure -i google_function -c build.phases.pre_build.commands[1]='if [ ! -e "$THUB_FUNCTION_TXT" ]; then touch "$THUB_FUNCTION_TXT"; fi'
terrahub configure -i google_function -c build.phases.pre_build.finally[0]='echo "BUILD: pre_build step successful"'
terrahub configure -i google_function -c build.phases.build.commands[0]='echo "BUILD: Running build step"'
terrahub configure -i google_function -c build.phases.build.commands[1]='if [ "$(head -n 1 "$THUB_FUNCTION_TXT")" != "$(stat -c %y "${THUB_BUILD_PATH}/index.js")" ]; then zip -j ${THUB_FUNCTION_ZIP} ${THUB_BUILD_PATH}/index.js; fi'
terrahub configure -i google_function -c build.phases.build.commands[2]='if [ "$(head -n 1 "$THUB_FUNCTION_TXT")" != "$(stat -c %y "${THUB_BUILD_PATH}/index.js")" ]; then terrahub configure -i google_function -c component.template.resource.google_storage_bucket_object.google_storage_object.name=$(date +%s).zip; fi'
terrahub configure -i google_function -c build.phases.build.finally[0]='echo "BUILD: build step successful"'
terrahub configure -i google_function -c build.phases.post_build.commands[0]='echo "BUILD: Running post_build step"'
terrahub configure -i google_function -c build.phases.post_build.commands[1]='echo $(stat -c %y "${THUB_BUILD_PATH}/index.js") > "$THUB_FUNCTION_TXT"'
terrahub configure -i google_function -c build.phases.post_build.finally[0]='echo "BUILD: post_build step successful"'
```

Your output should be similar to the one below:
```
✅ Done
```

## Visualize TerraHub Components

Run the following command in terminal:
```shell
terrahub graph
```

Your output should be similar to the one below:
```
Project: demo-terraform-automation-google
└─ google_storage [path: ./google_storage]
└─ google_function [path: ./google_function]
```


## Run TerraHub Automation

Run the following command in terminal:
```shell
terrahub build -i google_function
terrahub run -a -y
```

Your output should be similar to the one below:
```
```

## Run Test Command

Run the following command in terminal:
```
curl https://us-central1-terrahub-123456.cloudfunctions.net/demofunctionxxxxxxxx
```
79 changes: 79 additions & 0 deletions google_function/.terrahub.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
component:
name: google_function
mapping:
- .
dependsOn:
- ../google_storage
template:
resource:
google_cloudfunctions_function:
google_function:
name: 'demofunction${local.project["code"]}'
depends_on:
- google_storage_bucket_object.google_storage_object
region: us-central1
runtime: nodejs8
description: My demo function
available_memory_mb: 128
source_archive_bucket: '${data.terraform_remote_state.storage.thub_id}'
source_archive_object: '${google_storage_bucket_object.google_storage_object.name}'
trigger_http: true
timeout: 60
entry_point: helloGET
google_storage_bucket_object:
google_storage_object:
name: demo.zip
bucket: '${data.terraform_remote_state.storage.thub_id}'
source: ./demo.zip
terraform:
backend:
local:
path: /tmp/.terrahub/local_backend/google_function/terraform.tfstate
data:
terraform_remote_state:
storage:
backend: local
config:
path: /tmp/.terrahub/local_backend/google_storage/terraform.tfstate
output:
id:
value: '${google_cloudfunctions_function.google_function.id}'
trigger_url:
value: '${google_cloudfunctions_function.google_function.https_trigger_url}'
build:
env:
variables:
THUB_FUNCTION_ZIP: demo.zip
THUB_BUILD_PATH: ..
THUB_FUNCTION_TXT: demo.txt
THUB_BUILD_OK: true
phases:
pre_build:
commands:
- 'echo "BUILD: Running pre_build step"'
- 'if [ ! -e "$THUB_FUNCTION_TXT" ]; then touch "$THUB_FUNCTION_TXT"; fi'
finally:
- 'echo "BUILD: pre_build step successful"'
build:
commands:
- 'echo "BUILD: Running build step"'
- >-
if [ "$(head -n 1 "$THUB_FUNCTION_TXT")" != "$(stat -c %y
"${THUB_BUILD_PATH}/index.js")" ]; then zip -j ${THUB_FUNCTION_ZIP}
${THUB_BUILD_PATH}/index.js; fi
- >-
if [ "$(head -n 1 "$THUB_FUNCTION_TXT")" != "$(stat -c %y
"${THUB_BUILD_PATH}/index.js")" ]; then terrahub configure -i
google_function -c
component.template.resource.google_storage_bucket_object.google_storage_object.name=$(date
+%s).zip; fi
finally:
- 'echo "BUILD: build step successful"'
post_build:
commands:
- 'echo "BUILD: Running post_build step"'
- >-
echo $(stat -c %y "${THUB_BUILD_PATH}/index.js") >
"$THUB_FUNCTION_TXT"
finally:
- 'echo "BUILD: post_build step successful"'
26 changes: 26 additions & 0 deletions google_storage/.terrahub.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
component:
name: google_storage
mapping:
- .
template:
resource:
google_storage_bucket:
google_storage:
name: 'demo_terraform_automation_${local.project["code"]}'
location: US
project: '${local.google_project_id}'
output:
id:
value: '${google_storage_bucket.google_storage.id}'
thub_id:
value: '${google_storage_bucket.google_storage.id}'
self_link:
value: '${google_storage_bucket.google_storage.self_link}'
project:
value: '${google_storage_bucket.google_storage.project}'
url:
value: '${google_storage_bucket.google_storage.url}'
terraform:
backend:
local:
path: /tmp/.terrahub/local_backend/google_storage/terraform.tfstate
Loading

0 comments on commit 72e54ae

Please sign in to comment.