Skip to content
Merged
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ For example for the following directory structure:
β”‚ β”œβ”€β”€ prod-account
β”‚ β”‚ └── terragrunt.hcl
β”‚ └── aws.hcl
β”œβ”€β”€ .env
└── root.hcl
```

Expand All @@ -82,6 +83,15 @@ velez --terragrunt plan aws/dev-account
```


## Configuration

Velez expects following environment variables to be set:
* `VELEZ_USE_S3_BACKEND` - set to `true` if you use AWS S3 backend for storing Terraform state. Acts as set to `true` by default.
* `VELEZ_USE_DYNAMODB_LOCKS` - set to `true` if you use AWS DynamoDB for locking Terraform state. Acts as set to `true` by default.

For your convenience, you can set these variables in a `.env` file in the project directory and use the `dotenv` to load them.


## Features

- Supporting following services/tools and operations on them:
Expand Down
138 changes: 69 additions & 69 deletions terragrunt_ops.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
import os
import subprocess

import boto3

from pick import pick

menu_plan = "πŸ“‹ Plan"
menu_apply = "βœ… Apply"
menu_import = "πŸ“Ž Import"
menu_destroy = "πŸ’£ Destroy"
menu_state = "πŸ“¦ State operations"
menu_module = "πŸ“¦ Module operations"
menu_taint = "🚫 Taint"
menu_untaint = "♻️ Untaint"
menu_unlock = "πŸ”“ Unlock"
menu_output = "πŸ“€ Output"
menu_init = "πŸš€ Initialize"
menu_validate = "β˜‘οΈ Validate"
menu_refresh = "πŸ”„ Refresh"
state_list = "πŸ“„ List"
state_move = "πŸ“¦ Move"
state_rm = "πŸ—‘οΈ Remove"
state_show = "πŸ” Show"
state_pull = "‡️ Pull"
state_push = "‴ Push"
module_move = "↔️ Move module"
module_destroy_backend = "⌫ Destroy backend"
module_destroy = "πŸ—‘οΈ Destroy module"


def list_folders_to_ignore():
return ['.terragrunt-cache', '.terraform-plugin-cache']


class TerragruntOperations:
menu_plan = "πŸ“‹ Plan"
menu_apply = "βœ… Apply"
menu_import = "πŸ“Ž Import"
menu_destroy = "πŸ’£ Destroy"
menu_state = "πŸ“¦ State operations"
menu_module = "πŸ“¦ Module operations"
menu_taint = "🚫 Taint"
menu_untaint = "♻️ Untaint"
menu_unlock = "πŸ”“ Unlock"
menu_output = "πŸ“€ Output"
menu_init = "πŸš€ Initialize"
menu_validate = "β˜‘οΈ Validate"
menu_refresh = "πŸ”„ Refresh"
state_list = "πŸ“„ List"
state_move = "πŸ“¦ Move"
state_rm = "πŸ—‘οΈ Remove"
state_show = "πŸ” Show"
state_pull = "‡️ Pull"
state_push = "‴ Push"
module_move = "↔️ Move module"
module_destroy_backend = "⌫ Destroy backend"
module_destroy = "πŸ—‘οΈ Destroy module"


def __init__(self, velez):
self.velez = velez

Expand Down Expand Up @@ -95,19 +94,20 @@ def folder_menu(self, current_dir=None):

def action_menu(self, module):
options = [
menu_plan,
menu_apply,
menu_import,
menu_destroy,
menu_state,
menu_taint,
menu_untaint,
menu_unlock,
menu_output,
menu_init,
menu_validate,
menu_refresh
] + [self.velez.menu_back, self.velez.menu_exit]
self.menu_plan,
self.menu_apply,
self.menu_import,
self.menu_destroy,
self.menu_state,
self.menu_module if self.velez.use_s3_backend and self.velez.use_dynamodb_locks else None,
self.menu_taint,
self.menu_untaint,
self.menu_unlock,
self.menu_output,
self.menu_init,
self.menu_validate,
self.menu_refresh
] + [self.velez.menu_back, self.velez.menu_exit]
title = f"Choose an action. Current Module: {os.path.relpath(module, self.velez.base_dir)}:"
option, index = pick(options, title)

Expand All @@ -117,7 +117,7 @@ def action_menu(self, module):
exit()

# Plan
elif option == menu_plan:
elif option == self.menu_plan:
resource = input("Enter the target to plan (e.g., module.resource; will run the whole module if empty): ")
if resource:
self.execute_terragrunt(module, ['plan', '-target', resource])
Expand All @@ -127,7 +127,7 @@ def action_menu(self, module):
self.action_menu(module)

# Apply
elif option == menu_apply:
elif option == self.menu_apply:
resource = input("Enter the target to apply (e.g., module.resource; will run the whole module if empty): ")
if resource:
self.execute_terragrunt(module, ['apply', '-target', resource])
Expand All @@ -137,15 +137,15 @@ def action_menu(self, module):
self.action_menu(module)

# Import
elif option == menu_import:
elif option == self.menu_import:
resource = input("Enter the address of the resource to import (e.g., aws_instance.example): ")
resource_id = input("Enter the resource ID to import (e.g., i-12345678): ")
if resource and resource_id:
self.execute_terragrunt(module, ['import', resource, resource_id])
self.action_menu(module)

# Destroy
elif option == menu_destroy:
elif option == self.menu_destroy:
resource = input(
"Enter the target to destroy (e.g., module.resource; will run the whole module if empty): ")
if resource:
Expand All @@ -156,14 +156,14 @@ def action_menu(self, module):
self.action_menu(module)

# State operations
elif option == menu_state:
elif option == self.menu_state:
state_options = [
state_list,
state_move,
state_rm,
state_show,
state_pull,
state_push,
self.state_list,
self.state_move,
self.state_rm,
self.state_show,
self.state_pull,
self.state_push,
self.velez.menu_back,
self.velez.menu_exit
]
Expand All @@ -173,37 +173,37 @@ def action_menu(self, module):
self.action_menu(module)
elif state_option == self.velez.menu_exit:
exit()
elif state_option == state_list:
elif state_option == self.state_list:
resource = input("Enter the address of the resource to list (e.g., module.example): ")
self.execute_terragrunt(module, ['state', 'list', resource])
self.action_menu(module)
elif state_option == state_move:
elif state_option == self.state_move:
source = input("Enter the source address of the resource to move (e.g., aws_instance.example): ")
destination = input(
"Enter the destination address of the resource to move (e.g., aws_instance.example): ")
self.execute_terragrunt(module, ['state', 'mv', source, destination])
self.action_menu(module)
elif state_option == state_rm:
elif state_option == self.state_rm:
resource = input("Enter the address of the resource to remove (e.g., aws_instance.example): ")
self.execute_terragrunt(module, ['state', 'rm', resource])
self.action_menu(module)
elif state_option == state_show:
elif state_option == self.state_show:
resource = input("Enter the address of the resource to show (e.g., aws_instance.example): ")
self.execute_terragrunt(module, ['state', 'show', resource])
self.action_menu(module)
elif state_option == state_pull:
elif state_option == self.state_pull:
self.execute_terragrunt(module, ['state', 'pull'])
self.action_menu(module)
elif state_option == state_push:
elif state_option == self.state_push:
self.execute_terragrunt(module, ['state', 'push'])
self.action_menu(module)

# Module operations
elif option == menu_module:
elif option == self.menu_module:
module_options = [
module_move,
module_destroy,
module_destroy_backend,
self.module_move if self.velez.use_s3_backend and self.velez.use_dynamodb_locks else None,
self.module_destroy if self.velez.use_s3_backend and self.velez.use_dynamodb_locks else None,
self.module_destroy_backend if self.velez.use_s3_backend and self.velez.use_dynamodb_locks else None,
self.velez.menu_back,
self.velez.menu_exit
]
Expand All @@ -215,7 +215,7 @@ def action_menu(self, module):
exit()

# Move module
elif module_option == module_move:
elif module_option == self.module_move:
destination = input("Enter the destination path (e.g., aws/prod): ")
dynamodb_name = input("Enter the DynamoDB lock table name (e.g., my_table): ")
dynamodb_lockid = input("Enter the DynamoDB LockID (e.g., my-terragrunt/aws/dev/account/terraform.tfstate-md5): ")
Expand Down Expand Up @@ -255,7 +255,7 @@ def action_menu(self, module):
self.action_menu(destination)

# Destroy whole module
elif module_option == module_destroy:
elif module_option == self.module_destroy:
dynamodb_name = input("Enter the DynamoDB lock table name (e.g., my_table): ")
dynamodb_lockid = input("Enter the DynamoDB LockID (e.g., my-terragrunt/aws/dev/account/terraform.tfstate-md5): ")
s3_state = input("Enter the S3 state path (e.g., s3://my-terragrunt/aws/dev/account): ")
Expand Down Expand Up @@ -283,7 +283,7 @@ def action_menu(self, module):
self.action_menu(os.path.dirname(module))

# Destroy backend for the module
elif module_option == module_destroy_backend:
elif module_option == self.module_destroy_backend:
dynamodb_name = input("Enter the DynamoDB lock table name (e.g., my_table): ")
dynamodb_lockid = input("Enter the DynamoDB LockID (e.g., my-terragrunt/aws/dev/account/terraform.tfstate-md5): ")
s3_state = input("Enter the S3 state path (e.g., s3://my-terragrunt/aws/dev/account): ")
Expand All @@ -306,40 +306,40 @@ def action_menu(self, module):
self.action_menu(module)

# Taint
elif option == menu_taint:
elif option == self.menu_taint:
address = input("Enter the address of the resource to taint (e.g., aws_instance.example): ")
self.execute_terragrunt(module, ['taint', address])
self.action_menu(module)

# Untaint
elif option == menu_untaint:
elif option == self.menu_untaint:
address = input("Enter the address of the resource to untaint (e.g., aws_instance.example): ")
self.execute_terragrunt(module, ['untaint', address])
self.action_menu(module)

# Unlock
elif option == menu_unlock:
elif option == self.menu_unlock:
self.execute_terragrunt(module, ['force-unlock'])
self.action_menu(module)

# Output
elif option == menu_output:
elif option == self.menu_output:
variable = input("Enter the output variable to show (e.g., my_output; will show all if empty): ")
self.execute_terragrunt(module, ['output', variable])
self.action_menu(module)

# Initialize
elif option == menu_init:
elif option == self.menu_init:
self.execute_terragrunt(module, ['init'])
self.action_menu(module)

# Validate
elif option == menu_validate:
elif option == self.menu_validate:
self.execute_terragrunt(module, ['validate'])
self.action_menu(module)

# Refresh
elif option == menu_refresh:
elif option == self.menu_refresh:
self.execute_terragrunt(module, ['refresh'])
self.action_menu(module)

Expand Down
5 changes: 4 additions & 1 deletion velez.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
from terragrunt_ops import TerragruntOperations



class Velez:
menu_back = "πŸ”™ Back"
menu_exit = "πŸšͺ Exit"
menu_terragrunt = "🌟 Run Terragrunt"

def __init__(self, base_dir=None):
self.base_dir = base_dir if base_dir else os.getcwd()
self.use_s3_backend = os.getenv('VELEZ_USE_S3_BACKEND', 'true') == 'true'
self.use_dynamodb_locks = os.getenv('VELEZ_USE_DYNAMODB_LOCKS', 'true') == 'true'
self.terragrunt_ops = TerragruntOperations(self)

def main_menu(self):
Expand Down Expand Up @@ -43,7 +46,7 @@ def run(self, terragrunt=False, **kwargs):


def main():
parser = argparse.ArgumentParser(description='Velez CLI')
parser = argparse.ArgumentParser(description='Velez CLI βˆ€')
parser.add_argument('--terragrunt', '-tg', action='store_true', help='Run Terragrunt operations')
parser.add_argument('pos_args', nargs=argparse.REMAINDER, help='Arguments to pass further')

Expand Down