Skip to content

Commit

Permalink
Fixes #11: Cloud Function for automatic folder inclusion
Browse files Browse the repository at this point in the history
#11
#14

Added example with cloud function that automatically runs TF when
project is created/moved/deleted.
  • Loading branch information
nick4fake authored and morgante committed Sep 20, 2019
1 parent b723254 commit dc50277
Show file tree
Hide file tree
Showing 20 changed files with 1,117 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@ examples/simple_example_access_level/terraform.tfvars
terraform.tfvars

credentials.json

examples/automatic_folder.zip

node_modules
yarn.lock
6 changes: 0 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ version:
docker_run:
docker run --rm -it \
-e PROJECT_ID \
-e BUCKET_NAME \
-e SERVICE_ACCOUNT_JSON \
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
Expand All @@ -101,7 +100,6 @@ docker_run:
docker_create:
docker run --rm -it \
-e PROJECT_ID \
-e BUCKET_NAME \
-e SERVICE_ACCOUNT_JSON \
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
Expand All @@ -113,7 +111,6 @@ docker_create:
docker_converge:
docker run --rm -it \
-e PROJECT_ID \
-e BUCKET_NAME \
-e SERVICE_ACCOUNT_JSON \
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
Expand All @@ -125,7 +122,6 @@ docker_converge:
docker_verify:
docker run --rm -it \
-e PROJECT_ID \
-e BUCKET_NAME \
-e SERVICE_ACCOUNT_JSON \
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
Expand All @@ -137,7 +133,6 @@ docker_verify:
docker_destroy:
docker run --rm -it \
-e PROJECT_ID \
-e BUCKET_NAME \
-e SERVICE_ACCOUNT_JSON \
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
Expand All @@ -149,7 +144,6 @@ docker_destroy:
test_integration_docker:
docker run --rm -it \
-e PROJECT_ID \
-e BUCKET_NAME \
-e SERVICE_ACCOUNT_JSON \
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
Expand Down
4 changes: 4 additions & 0 deletions examples/automatic_folder/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/provider.tf
/.terraform
tfplan
local.tfvars
52 changes: 52 additions & 0 deletions examples/automatic_folder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Automatic folder securing Example

This example illustrates how to use the `vpc-service-controls` module to configure an org policy, an access level and a regular perimeter with projects inside a folder.

# Requirements

1. Make sure you've gone through the root [Requirement Section](../../README.md#requirements) on any project in your organization.
2. Updated `provider.tf.dist` with remote state configs. Copy `provider.tf.dist` to `provider.tf` changing variables for local running
3. Create `local.tfvars` file with required inputs, like this:
````hcl-terraform
project_id = "YOUR_PROJECT"
parent_id = "ORG_ID"
folder_id = "FOLDER_ID"
policy_name = "automatic_folder"
members = ["user:[email protected]"]
region = "us-east1"
restricted_services = ["storage.googleapis.com"]
````
4. Please note, that whole example folder is uploaded as Cloud Function root. Don't store credentials in it!
5. Add Cloud Function's SA to organization (Access Context Manager Admin), project IAM (Owner and Storage Object Admin) and watched folder (Logs Configuration Writer)
6. You might need to apply TF changes twice due to ACM race condition



<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| folder\_id | Folder ID to watch for projects. | string | n/a | yes |
| members | An allowed list of members \(users, service accounts\). The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user \(logged in/not logged in, etc.\). Formats: user:\{emailid\}, serviceAccount:\{emailid\} | list(string) | n/a | yes |
| parent\_id | The parent of this AccessPolicy in the Cloud Resource Hierarchy. As of now, only organization are accepted as parent \(ID\). | string | n/a | yes |
| perimeter\_name | Name of perimeter. | string | `"regular_perimeter"` | no |
| policy\_name | The policy's name. | string | n/a | yes |
| project\_id | The ID of the project to which resources will be applied. | string | n/a | yes |
| region | The region in which resources will be applied. | string | n/a | yes |
| restricted\_services | List of services to restrict. | list(string) | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| policy\_name | Name of the parent policy |
| protected\_project\_ids | Project ids of the projects INSIDE the regular service perimeter |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

To provision this example, run the following from within this directory:
- `terraform init` to get the plugins
- `terraform plan` to see the infrastructure plan
- `terraform apply` to apply the infrastructure build
- `terraform destroy` to destroy the built infrastructure
109 changes: 109 additions & 0 deletions examples/automatic_folder/function.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package function

//noinspection GoUnusedImport,GoInvalidPackageImport
import (
"github.com/otiai10/copy"
"github.com/hashicorp/terraform"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
)

func copy_terraform_code(dirSource string, dirTarget string) (err error) {
var objects []os.FileInfo
if objects, err = ioutil.ReadDir(dirSource); err != nil {
return err
}

for _, obj := range objects {
name := obj.Name()

switch name {
case ".":
case "..":
case "credentials.json":
case ".terraform":
continue;
case "provider.tf.dist":
name = "provider.tf"
}

if err = copy.Copy(path.Join(dirSource, name), path.Join(dirTarget, name)); err != nil {
return err
}
}

return nil
}

func init_folder(dirSource string) (dirTarget string, err error) {
if dirTarget, err = ioutil.TempDir("/tmp", "project"); err != nil {
log.Panic(err)
}

if err = copy_terraform_code(dirSource, dirTarget); err != nil {
log.Panic(err)
}

return dirTarget, err
}

func run_terraform(arg ...string) (err error) {
cmd := exec.Command("terraform", "init")
if err := cmd.Run(); err != nil {
log.Fatal(err)
}

log.Print(cmd.CombinedOutput())

return nil
}

func handler() (err error) {
var dirSource string
if dirSource, err = os.Getwd(); err != nil {
log.Panic(err)
}

var dirTarget string
if dirTarget, err = init_folder(dirSource); err != nil {
log.Panic(err)
}

defer func() {
err2 := os.RemoveAll(dirTarget)
if (err2 != nil) {
if (err == nil) {
log.Panic(err2)
}
log.Print(err2)
}
}()

var args []string
const TF_PLAN = "tfplan"

args = []string{"init", "-no-color", "-lock-timeout=300s"}
if err = run_terraform(args...); err != nil {
log.Panic(err)
}

args = []string{"plan", "-no-color", "-lock-timeout=300s", "-var-file=local.tfvars", "-out", TF_PLAN}
if err = run_terraform(args...); err != nil {
log.Panic(err)
}

args = []string{"plan", "-no-color", "-lock-timeout=300s", "-auto-approve", "-out", TF_PLAN}
if err = run_terraform(args...); err != nil {
log.Panic(err)
}

args = []string{"output", "-json"}
if err = run_terraform(args...); err != nil {
log.Panic(err)
}

return nil
}
12 changes: 12 additions & 0 deletions examples/automatic_folder/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module function

require github.com/otiai10/copy v1.0.1

replace git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999

require (
github.com/hashicorp/terraform v0.12.8
github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776 // indirect
)

go 1.13
Loading

0 comments on commit dc50277

Please sign in to comment.