vm
and configuration using Terraform and Ansible, integrated with secure secretmanagement via Vault and SOPS.
This generated module was created with dagger init as a starting point for VM-related
operations. It demonstrates key DevOps tasks such as decrypting secrets, applying
Terraform infrastructure changes, generating dynamic Ansible inventories, and
executing Ansible playbooks to configure VMs. The module is designed to be flexible
and extensible to support your infrastructure automation needs.
The primary function Bake orchestrates this workflow, accepting Terraform directories,
encrypted files, Vault credentials, and Ansible parameters as inputs. It optionally
decrypts SOPS-encrypted configuration files before applying Terraform operations,
then parses Terraform outputs to generate inventory files for Ansible. It supports
multiple inventory types and allows you to specify Ansible playbooks and credentials.
This module can be invoked from the Dagger CLI or programmatically via the SDK,
making it suitable for integrating into CI/CD pipelines, GitOps workflows, or
custom operator/controller logic.
Future enhancements planned include:
- Rendering manifests or configs to branches/PRs for GitOps-style deployments
- Seamless integration with SOPS for secret management and decryption
- Advanced Terraform execution and output parsing features
- Enhanced Ansible inventory generation and execution customization
- VM testing and validation steps post-provisioning
- Automated merge requests/PR handling post-deployment
This documentation serves both as a high-level overview and a detailed guide
to the module’s capabilities and intended use cases.
Installation
dagger install github.com/stuttgart-things/blueprints/vm@v1.65.0Entrypoint
Return Type
Vm Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
func (m *MyModule) Example() *dagger.Vm {
return dag.
Vm()
}@function
def example() -> dagger.Vm:
return (
dag.vm()
)@func()
example(): Vm {
return dag
.vm()
}Types
Vm 🔗
baseImage() 🔗
Return Type
String ! Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
base-imagefunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Vm().
BaseImage(ctx)
}@function
async def example() -> str:
return await (
dag.vm()
.base_image()
)@func()
async example(): Promise<string> {
return dag
.vm()
.baseImage()
}bakeFromGit() 🔗
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| gitRepository | String ! | - | Repository to clone from GitHub |
| gitRef | String | "main" | Ref/Branch to checkout - If not specified, defaults to "main" |
| gitToken | Secret | - | Github token for authentication (private repositories) |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
bake-from-git --git-repository stringfunc (m *MyModule) Example(gitRepository string) *dagger.Directory {
return dag.
Vm().
BakeFromGit(gitRepository)
}@function
def example(git_repository: str) -> dagger.Directory:
return (
dag.vm()
.bake_from_git(git_repository)
)@func()
example(gitRepository: string): Directory {
return dag
.vm()
.bakeFromGit(gitRepository)
}bakeLocal() 🔗
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| terraformDir | Directory ! | - | No description provided |
| operation | String | "apply" | No description provided |
| variables | String | - | e.g., "cpu=4,ram=4096,storage=100" |
| encryptedFile | File | - | No description provided |
| sopsKey | Secret | - | No description provided |
| awsAccessKeyId | Secret | - | No description provided |
| awsSecretAccessKey | Secret | - | No description provided |
| vaultRoleId | Secret | - | No description provided |
| vaultSecretId | Secret | - | No description provided |
| vaultToken | Secret | - | vaultToken |
| vaultUrl | Secret | - | No description provided |
| ansiblePlaybooks | String | - | No description provided |
| ansibleRequirementsFile | File | - | No description provided |
| ansibleUser | Secret | - | No description provided |
| ansiblePassword | Secret | - | No description provided |
| ansibleParameters | String | - | No description provided |
| ansibleInventoryType | String | "default" | No description provided |
| ansibleWaitTimeout | Integer | 30 | No description provided |
| requirementsTemplate | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements.yaml.tmpl" | No description provided |
| requirementsData | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements-data.yaml" | No description provided |
| terraformMaxRetries | Integer | 3 | No description provided |
| terraformRetryDelay | Integer | 10 | No description provided |
| inventoryType | String | "simple" | Inventory type: "simple" (default [all] group) or "cluster" (master/worker groups) |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
bake-local --terraform-dir DIR_PATHfunc (m *MyModule) Example(terraformDir *dagger.Directory) *dagger.Directory {
return dag.
Vm().
BakeLocal(terraformDir)
}@function
def example(terraform_dir: dagger.Directory) -> dagger.Directory:
return (
dag.vm()
.bake_local(terraform_dir)
)@func()
example(terraformDir: Directory): Directory {
return dag
.vm()
.bakeLocal(terraformDir)
}bakeLocalByProfile() 🔗
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| src | Directory ! | - | No description provided |
| profile | File | - | No description provided |
| sopsKey | Secret | - | No description provided |
| awsAccessKeyId | Secret | - | No description provided |
| awsSecretAccessKey | Secret | - | No description provided |
| vaultRoleId | Secret | - | No description provided |
| vaultSecretId | Secret | - | No description provided |
| vaultToken | Secret | - | vaultToken |
| vaultUrl | Secret | - | No description provided |
| ansibleUser | Secret | - | No description provided |
| ansiblePassword | Secret | - | No description provided |
| requirementsTemplate | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements.yaml.tmpl" | No description provided |
| requirementsData | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements-data.yaml" | No description provided |
| inventoryType | String | "simple" | Inventory type: "simple" (default [all] group) or "cluster" (master/worker groups) |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
bake-local-by-profile --src DIR_PATHfunc (m *MyModule) Example(src *dagger.Directory) *dagger.Directory {
return dag.
Vm().
BakeLocalByProfile(src)
}@function
def example(src: dagger.Directory) -> dagger.Directory:
return (
dag.vm()
.bake_local_by_profile(src)
)@func()
example(src: Directory): Directory {
return dag
.vm()
.bakeLocalByProfile(src)
}commitToGit() 🔗
CommitToGit commits a directory of files to a GitHub repository branch.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| sourceDir | Directory ! | - | Directory containing files to commit |
| repository | String ! | - | Repository in "owner/repo" format |
| branchName | String | "main" | Branch name for git operations |
| commitMessage | String | "Add files via Dagger" | Commit message |
| destinationPath | String | "/" | Destination path within the repository |
| gitToken | Secret ! | - | GitHub token for authentication |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
commit-to-git --source-dir DIR_PATH --repository string --git-token env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, sourceDir *dagger.Directory, repository string, gitToken *dagger.Secret) string {
return dag.
Vm().
CommitToGit(ctx, sourceDir, repository, gitToken)
}@function
async def example(source_dir: dagger.Directory, repository: str, git_token: dagger.Secret) -> str:
return await (
dag.vm()
.commit_to_git(source_dir, repository, git_token)
)@func()
async example(sourceDir: Directory, repository: string, gitToken: Secret): Promise<string> {
return dag
.vm()
.commitToGit(sourceDir, repository, gitToken)
}decryptSops() 🔗
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| sopsKey | Secret ! | - | No description provided |
| encryptedFile | File ! | - | No description provided |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
decrypt-sops --sops-key env:MYSECRET --encrypted-file file:pathfunc (m *MyModule) Example(ctx context.Context, sopsKey *dagger.Secret, encryptedFile *dagger.File) string {
return dag.
Vm().
DecryptSops(ctx, sopsKey, encryptedFile)
}@function
async def example(sops_key: dagger.Secret, encrypted_file: dagger.File) -> str:
return await (
dag.vm()
.decrypt_sops(sops_key, encrypted_file)
)@func()
async example(sopsKey: Secret, encryptedFile: File): Promise<string> {
return dag
.vm()
.decryptSops(sopsKey, encryptedFile)
}encryptFile() 🔗
EncryptFile encrypts a plaintext file with SOPS using an AGE public key.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| agePublicKey | Secret ! | - | AGE public key for encryption |
| plaintextFile | File ! | - | Plaintext file to encrypt |
| fileExtension | String | "yaml" | File extension for SOPS encryption (e.g., "yaml", "json") |
| sopsConfig | File | - | SOPS config file (.sops.yaml) |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
encrypt-file --age-public-key env:MYSECRET --plaintext-file file:pathfunc (m *MyModule) Example(ctx context.Context, agePublicKey *dagger.Secret, plaintextFile *dagger.File) string {
return dag.
Vm().
EncryptFile(ctx, agePublicKey, plaintextFile)
}@function
async def example(age_public_key: dagger.Secret, plaintext_file: dagger.File) -> str:
return await (
dag.vm()
.encrypt_file(age_public_key, plaintext_file)
)@func()
async example(agePublicKey: Secret, plaintextFile: File): Promise<string> {
return dag
.vm()
.encryptFile(agePublicKey, plaintextFile)
}executeAnsible() 🔗
Return Type
Boolean !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| src | Directory | - | No description provided |
| playbooks | String ! | - | No description provided |
| requirements | File | - | No description provided |
| inventory | File | - | No description provided |
| hosts | String | - | Comma-separated list of hosts (e.g., "192.168.1.10,192.168.1.11") Used to generate inventory if inventory file is not provided |
| parameters | String | - | No description provided |
| parametersFile | File | - | Path to a YAML file containing parameters (lower priority) |
| vaultAppRoleId | Secret | - | No description provided |
| vaultSecretId | Secret | - | No description provided |
| vaultUrl | Secret | - | No description provided |
| sshUser | Secret | - | No description provided |
| sshPassword | Secret | - | No description provided |
| requirementsTemplate | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements.yaml.tmpl" | No description provided |
| requirementsData | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements-data.yaml" | No description provided |
| inventoryType | String | "simple" | Inventory type: "simple" (default [all] group) or "cluster" (master/worker groups) |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
execute-ansible --playbooks stringfunc (m *MyModule) Example(ctx context.Context, playbooks string) bool {
return dag.
Vm().
ExecuteAnsible(ctxplaybooks)
}@function
async def example(playbooks: str) -> bool:
return await (
dag.vm()
.execute_ansible(playbooks)
)@func()
async example(playbooks: string): Promise<boolean> {
return dag
.vm()
.executeAnsible(playbooks)
}executeAnsibleEncryptAndCommit() 🔗
ExecuteAnsibleEncryptAndCommit runs Ansible playbooks, extracts files from the container, encrypts them with SOPS, and commits the encrypted files to a Git repository.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| src | Directory | - | No description provided |
| playbooks | String ! | - | No description provided |
| exportPaths | String ! | - | Comma-separated list of file paths to export from the Ansible container |
| requirements | File | - | No description provided |
| inventory | File | - | No description provided |
| hosts | String | - | Comma-separated list of hosts (e.g., "192.168.1.10,192.168.1.11") |
| parameters | String | - | No description provided |
| parametersFile | File | - | No description provided |
| vaultAppRoleId | Secret | - | No description provided |
| vaultSecretId | Secret | - | No description provided |
| vaultUrl | Secret | - | No description provided |
| sshUser | Secret | - | No description provided |
| sshPassword | Secret | - | No description provided |
| requirementsTemplate | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements.yaml.tmpl" | No description provided |
| requirementsData | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements-data.yaml" | No description provided |
| inventoryType | String | "simple" | Inventory type: "simple" (default [all] group) or "cluster" (master/worker groups) |
| agePublicKey | Secret ! | - | AGE public key for SOPS encryption |
| sopsFileExtension | String | "yaml" | File extension for SOPS encryption (e.g., "yaml", "json") |
| sopsConfig | File | - | SOPS config file (.sops.yaml) |
| gitRepository | String ! | - | Git repository in "owner/repo" format |
| gitBranch | String | "main" | Git branch name |
| gitCommitMessage | String | "Add encrypted files from Ansible execution" | Git commit message |
| gitDestinationPath | String | "/" | Destination path within the git repository |
| gitToken | Secret ! | - | GitHub token for authentication |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
execute-ansible-encrypt-and-commit --playbooks string --export-paths string --age-public-key env:MYSECRET --git-repository string --git-token env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, playbooks string, exportPaths string, agePublicKey *dagger.Secret, gitRepository string, gitToken *dagger.Secret) string {
return dag.
Vm().
ExecuteAnsibleEncryptAndCommit(ctxplaybooks, exportPaths, agePublicKey, gitRepository, gitToken)
}@function
async def example(playbooks: str, export_paths: str, age_public_key: dagger.Secret, git_repository: str, git_token: dagger.Secret) -> str:
return await (
dag.vm()
.execute_ansible_encrypt_and_commit(playbooks, export_paths, age_public_key, git_repository, git_token)
)@func()
async example(playbooks: string, exportPaths: string, agePublicKey: Secret, gitRepository: string, gitToken: Secret): Promise<string> {
return dag
.vm()
.executeAnsibleEncryptAndCommit(playbooks, exportPaths, agePublicKey, gitRepository, gitToken)
}executeAnsibleWithExport() 🔗
ExecuteAnsibleWithExport runs Ansible playbooks and exports specified files from the container. Same parameters as ExecuteAnsible plus exportPaths (comma-separated file paths to extract).
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| src | Directory | - | No description provided |
| playbooks | String ! | - | No description provided |
| exportPaths | String ! | - | Comma-separated list of file paths to export from the Ansible container |
| requirements | File | - | No description provided |
| inventory | File | - | No description provided |
| hosts | String | - | Comma-separated list of hosts (e.g., "192.168.1.10,192.168.1.11") Used to generate inventory if inventory file is not provided |
| parameters | String | - | No description provided |
| parametersFile | File | - | Path to a YAML file containing parameters (lower priority) |
| vaultAppRoleId | Secret | - | No description provided |
| vaultSecretId | Secret | - | No description provided |
| vaultUrl | Secret | - | No description provided |
| sshUser | Secret | - | No description provided |
| sshPassword | Secret | - | No description provided |
| requirementsTemplate | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements.yaml.tmpl" | No description provided |
| requirementsData | String | "https://raw.githubusercontent.com/stuttgart-things/ansible/refs/heads/main/templates/requirements-data.yaml" | No description provided |
| inventoryType | String | "simple" | Inventory type: "simple" (default [all] group) or "cluster" (master/worker groups) |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
execute-ansible-with-export --playbooks string --export-paths stringfunc (m *MyModule) Example(playbooks string, exportPaths string) *dagger.Directory {
return dag.
Vm().
ExecuteAnsibleWithExport(playbooks, exportPaths)
}@function
def example(playbooks: str, export_paths: str) -> dagger.Directory:
return (
dag.vm()
.execute_ansible_with_export(playbooks, export_paths)
)@func()
example(playbooks: string, exportPaths: string): Directory {
return dag
.vm()
.executeAnsibleWithExport(playbooks, exportPaths)
}executeTerraform() 🔗
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| terraformDir | Directory ! | - | No description provided |
| operation | String | "apply" | No description provided |
| variables | String | - | e.g., "cpu=4,ram=4096,storage=100" |
| awsAccessKeyId | Secret | - | AWS S3/MinIO credentials |
| awsSecretAccessKey | Secret | - | No description provided |
| vaultRoleId | Secret | - | vaultRoleID |
| vaultSecretId | Secret | - | vaultSecretID |
| vaultToken | Secret | - | vaultToken |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
execute-terraform --terraform-dir DIR_PATHfunc (m *MyModule) Example(terraformDir *dagger.Directory) *dagger.Directory {
return dag.
Vm().
ExecuteTerraform(terraformDir)
}@function
def example(terraform_dir: dagger.Directory) -> dagger.Directory:
return (
dag.vm()
.execute_terraform(terraform_dir)
)@func()
example(terraformDir: Directory): Directory {
return dag
.vm()
.executeTerraform(terraformDir)
}outputTerraformRun() 🔗
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| terraformDir | Directory ! | - | No description provided |
| awsAccessKeyId | Secret | - | No description provided |
| awsSecretAccessKey | Secret | - | No description provided |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
output-terraform-run --terraform-dir DIR_PATHfunc (m *MyModule) Example(ctx context.Context, terraformDir *dagger.Directory) string {
return dag.
Vm().
OutputTerraformRun(ctx, terraformDir)
}@function
async def example(terraform_dir: dagger.Directory) -> str:
return await (
dag.vm()
.output_terraform_run(terraform_dir)
)@func()
async example(terraformDir: Directory): Promise<string> {
return dag
.vm()
.outputTerraformRun(terraformDir)
}outputTerraformRunWithCreds() 🔗
OutputTerraformRunWithCreds runs terraform output --json with AWS credentials
for remote S3/MinIO backends. This is now just an alias for OutputTerraformRun.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| terraformDir | Directory ! | - | No description provided |
| awsAccessKeyId | Secret | - | No description provided |
| awsSecretAccessKey | Secret | - | No description provided |
Example
dagger -m github.com/stuttgart-things/blueprints/vm@37f4d5ff02562843d60717596ee9f02c12bce048 call \
output-terraform-run-with-creds --terraform-dir DIR_PATHfunc (m *MyModule) Example(ctx context.Context, terraformDir *dagger.Directory) string {
return dag.
Vm().
OutputTerraformRunWithCreds(ctx, terraformDir)
}@function
async def example(terraform_dir: dagger.Directory) -> str:
return await (
dag.vm()
.output_terraform_run_with_creds(terraform_dir)
)@func()
async example(terraformDir: Directory): Promise<string> {
return dag
.vm()
.outputTerraformRunWithCreds(terraformDir)
}