Skip to content

synology-community/terraform-provider-synology

Repository files navigation

Terraform Synology Provider - Developer Guide

GitHub release License Go Report Card

A Terraform provider for managing Synology NAS servers through the Synology DSM API. Built with Terraform Plugin Framework and the go-synology API client.

For usage documentation, see the Terraform Registry documentation or browse examples/.

Features

  • Core Management: Package installation, package feeds, task scheduler, events
  • Container Management: Docker Compose projects with full service configuration
  • File Station: File operations and cloud-init ISO generation
  • Virtualization: Virtual machine lifecycle management
  • Generic API: Direct access to any Synology DSM API endpoint

Architecture

graph TB
    A[Terraform Provider] --> B[Plugin Framework]
    A --> C[go-synology Client]
    
    B --> B1[Resources]
    B --> B2[Data Sources]
    B --> B3[Functions]
    
    C --> C1[Core API]
    C --> C2[Docker API]
    C --> C3[FileStation API]
    C --> C4[Virtualization API]
    
    C1 --> D[Synology DSM]
    C2 --> D
    C3 --> D
    C4 --> D
    
    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style D fill:#fff3e0
Loading

Quick Start

For Users

See the Provider Documentation for usage examples and configuration.

Quick Example:

terraform {
  required_providers {
    synology = {
      source  = "synology-community/synology"
      version = "~> 1.0"
    }
  }
}

provider "synology" {
  host     = "your-synology.local:5001"
  user     = "admin"
  password = var.synology_password
}

resource "synology_container_project" "app" {
  name = "my-app"
  
  services = {
    web = {
      image = "nginx:latest"
      ports = [{ target = 80, published = "8080" }]
    }
  }
}

For Developers

Prerequisites

Building

# Clone the repository
git clone https://github.com/synology-community/terraform-provider-synology.git
cd terraform-provider-synology

# Build the provider
go build .

# Install locally for testing
make install

Running Tests

Unit Tests:

go test ./synology/...

Acceptance Tests:

The provider uses testcontainers-go to run acceptance tests against a virtualized Synology DSM instance. This avoids the need to test against real infrastructure.

# Run all acceptance tests
TF_ACC=1 go test ./synology/provider/... -v -timeout 30m

# Run specific test
TF_ACC=1 go test ./synology/provider/... -v -run TestAccResource_ContainerProject

# Show DSM container output
TF_ACC=1 DSM_STDOUT=1 go test ./synology/provider/... -v

How Acceptance Tests Work:

  1. Test runner starts a Docker Compose stack with a virtual DSM instance (using vdsm/virtual-dsm)
  2. Container runs in software emulation mode (TCG) - no KVM required, works on all platforms
  3. Tests wait for DSM API to become available (2-5 minutes on first run)
  4. Tests execute against the virtual DSM
  5. Container is cleaned up automatically

Cross-Platform Compatibility:

  • ✅ macOS (Intel and Apple Silicon)
  • ✅ Linux (with or without KVM)
  • ✅ Windows (with Docker Desktop)

Troubleshooting Tests:

# Increase timeout for slow machines
TF_ACC=1 go test ./synology/provider/... -v -timeout 60m

# Check Docker logs
docker logs dsm-test

# Clean up test volumes
docker volume prune

Performance Notes:

  • First test run downloads ~2GB DSM image
  • DSM initialization takes 2-5 minutes on first start
  • Subsequent runs are faster (cached state)
  • TCG emulation is slower than KVM but works everywhere

Development

Project Structure

terraform-provider-synology/
├── synology/
│   ├── provider/              # Provider implementation
│   │   ├── provider.go        # Main provider
│   │   ├── container/         # Container resources
│   │   ├── core/              # Core system resources
│   │   ├── filestation/       # File Station resources
│   │   └── virtualization/    # VM resources
│   ├── models/                # Data models
│   ├── util/                  # Shared utilities
│   └── acctest/               # Acceptance test helpers
├── examples/                  # Usage examples
├── docs/                      # Generated documentation
├── docker-compose.yaml        # Test infrastructure
└── .github/
    └── instructions/          # Copilot development guides

Adding a New Resource

  1. Create the resource file in the appropriate package (e.g., synology/provider/core/my_resource.go)

  2. Implement the resource interface:

package core

import (
    "context"
    "github.com/hashicorp/terraform-plugin-framework/resource"
    "github.com/hashicorp/terraform-plugin-framework/resource/schema"
)

type MyResource struct {
    client core.Api
}

func NewMyResource() resource.Resource {
    return &MyResource{}
}

func (r *MyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
    resp.TypeName = buildName(req.ProviderTypeName, "my_resource")
}

func (r *MyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        MarkdownDescription: "Resource description with examples...",
        Attributes: map[string]schema.Attribute{
            "id": schema.StringAttribute{
                Computed: true,
            },
            // Add your attributes...
        },
    }
}

// Implement Create, Read, Update, Delete, Configure methods...
  1. Register the resource in synology/provider/provider.go:
func (p *synologyProvider) Resources(ctx context.Context) []func() resource.Resource {
    return []func() resource.Resource{
        // ... existing resources
        core.NewMyResource,
    }
}
  1. Add tests in synology/provider/core/my_resource_test.go

  2. Add examples in examples/resources/synology_my_resource/

  3. Generate documentation:

go generate ./...

Code Style

  • Follow the style guide
  • Use gofmt for formatting
  • Run linters: golangci-lint run
  • Write acceptance tests for all resources

Testing Guidelines

See testing guide for detailed testing patterns.

Key Testing Principles:

  • All resources must have acceptance tests
  • Use testcontainers for infrastructure
  • Mock external dependencies in unit tests
  • Test both success and failure paths
  • Verify state after operations

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Make your changes following the code style
  4. Add tests for new functionality
  5. Run tests: TF_ACC=1 go test ./synology/provider/... -v
  6. Commit with conventional commits (feat:, fix:, docs:, etc.)
  7. Push and create a pull request

Commit Message Format

<type>(<scope>): <description>

[optional body]

[optional footer]

Types: feat, fix, docs, style, refactor, test, chore

Examples:

feat(container): add network_mode support to project resource
fix(virtualization): handle missing storage_id gracefully
docs(readme): update testing instructions
test(core): add acceptance tests for package resource

Documentation

For Users

For Developers

API Reference Links

Required Permissions

Container Manager

  • Member of Administrators group (Container Manager has no RBAC)
  • Read/Write access on target shares
  • Applications granted:
    • DSM
    • File Station

Virtual Machine Manager

  • Virtual Machine Manager permissions
  • Storage access permissions

Troubleshooting

Provider Issues

Authentication failures:

  • Verify host, username, and password are correct
  • Check if 2FA is enabled (provide otp_secret if using TOTP)
  • Ensure account has necessary permissions for the operations

Connection errors:

  • Verify DSM is accessible at the configured host
  • Check SSL certificate validation (skip_cert_check = true for self-signed certs)
  • Confirm firewall rules allow connections on the specified port

Test Issues

Tests timeout:

  • Increase timeout: -timeout 60m
  • Check Docker has sufficient resources (CPU/RAM)
  • Verify Docker is running: docker ps

Container fails to start:

  • Check Docker logs: docker logs dsm-test
  • Ensure sufficient disk space available
  • Remove old volumes: docker volume prune

API connection failures:

  • Wait longer for DSM initialization (can take 5+ minutes)
  • Check if container is healthy: docker ps (should show "healthy")
  • Verify container networking: docker exec dsm-test curl localhost:5000

Release Process

  1. Update CHANGELOG.md with changes
  2. Create release branch: git checkout -b release/v1.x.x
  3. Update version in relevant files
  4. Tag release: git tag v1.x.x
  5. Push tag: git push origin v1.x.x
  6. GitHub Actions will build and publish to Terraform Registry

License

Mozilla Public License 2.0 - see LICENSE for details.

Support

Acknowledgments


Made with ❤️ by the Synology Community

About

Terraform provider to manage DSM APIs on Synology NAS

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages