Skip to content

Commit 14e7632

Browse files
authored
feat: add portainer_deploy and portainer_check resources + update resources docs
feat: add portainer_deploy and portainer_check resources + update resources docs - Added new resource `portainer_deploy` for automated stack/service updates - Added new resource `portainer_check` for validation of deployed containers - Updated README and resource documentation - Improved examples for full CI/CD automation flow
1 parent 8504a6a commit 14e7632

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1935
-158
lines changed

.github/workflows/daily-e2e-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ jobs:
7575
7676
- name: 🧪 Run Terraform E2E tests
7777
run: |
78-
APPLY_ONLY_DIRS=("stack_standalone_string" "webhook" "container_exec" "backup" "auth" "open_amt" "kubernetes_role" "kubernetes_delete_object" "endpoint_snapshot" "endpoint_settings" "kubernetes_namespace")
78+
APPLY_ONLY_DIRS=("deployment" "stack_standalone_string" "webhook" "container_exec" "backup" "auth" "open_amt" "kubernetes_role" "kubernetes_delete_object" "endpoint_snapshot" "endpoint_settings" "kubernetes_namespace")
7979
FULL_CYCLE_DIRS=("edge_string" "edge_file" "edge_repository" "kubernetes_application" "kubernetes_clusterrole" "kubernetes_clusterrolebinding" "kubernetes_configmaps" "kubernetes_cronjob" "kubernetes_helm" "kubernetes_ingress" "kubernetes_ingresscontrollers" "kubernetes_job" "kubernetes_namespace_ingresscontrollers" "kubernetes_namespace_system" "kubernetes_role" "kubernetes_rolebinding" "kubernetes_secret" "kubernetes_service" "kubernetes_serviceaccounts" "kubernetes_storage" "kubernetes_volume"
8080
"custom_template_string" "custom_template_file" "custom_template_repository" "docker_image" "docker_network" "docker_plugin" "docker_volume" "stack_standalone_string" "stack_standalone_file" "stack_standalone_repository" "endpoint_group" "tag" "user-team-teammembership" "registry")
8181

.github/workflows/pr-e2e-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
8484
- name: 🧪 Run Terraform E2E tests
8585
run: |
86-
APPLY_ONLY_DIRS=("stack_standalone_string" "webhook" "container_exec" "backup" "auth" "open_amt" "kubernetes_role" "kubernetes_delete_object" "endpoint_snapshot" "endpoint_settings" "kubernetes_namespace")
86+
APPLY_ONLY_DIRS=("deployment" "stack_standalone_string" "webhook" "container_exec" "backup" "auth" "open_amt" "kubernetes_role" "kubernetes_delete_object" "endpoint_snapshot" "endpoint_settings" "kubernetes_namespace")
8787
FULL_CYCLE_DIRS=("edge_string" "edge_file" "edge_repository" "kubernetes_application" "kubernetes_clusterrole" "kubernetes_clusterrolebinding" "kubernetes_configmaps" "kubernetes_cronjob" "kubernetes_helm" "kubernetes_ingress" "kubernetes_ingresscontrollers" "kubernetes_job" "kubernetes_namespace_ingresscontrollers" "kubernetes_namespace_system" "kubernetes_role" "kubernetes_rolebinding" "kubernetes_secret" "kubernetes_service" "kubernetes_serviceaccounts" "kubernetes_storage" "kubernetes_volume"
8888
"custom_template_string" "custom_template_file" "custom_template_repository" "docker_image" "docker_network" "docker_plugin" "docker_volume" "stack_standalone_string" "stack_standalone_file" "stack_standalone_repository" "endpoint_group" "tag" "user-team-teammembership" "registry")
8989

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ See our [examples](./docs/resources/) per resources in docs.
144144
| `portainer_stack` | [stack.md](docs/resources/stack.md) | [example](examples/stack/) || ✅ / ✅ ||
145145
| `portainer_custom_template` | [custom_template.md](docs/resources/custom_template.md) | [example](examples/custom_template/) || ✅ / ✅ ||
146146
| `portainer_container_exec` | [container_exec.md](docs/resources/container_exec.md) | [example](examples/container_exec/) || ❌ / ❌ ||
147+
| `portainer_deploy` | [deploy.md](docs/resources/deploy.md) | [example](examples/deployment/) || ❌ / ❌ ||
148+
| `portainer_check` | [check.md](docs/resources/check.md) | [example](examples/deployment/) || ❌ / ❌ ||
147149
| `portainer_docker_network` | [docker_network.md](docs/resources/docker_network.md) | [example](examples/docker_network/) || ✅ / ❌ ||
148150
| `portainer_docker_plugin` | [docker_plugin.md](docs/resources/docker_plugin.md) | [example](examples/docker_plugin/) || ✅ / ❌ ||
149151
| `portainer_docker_image` | [docker_image.md](docs/resources/docker_image.md) | [example](examples/docker_image/) || ❌ / ❌ ||

docs/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ $ export PORTAINER_SKIP_SSL_VERIFY=true
8686
| `portainer_cloud_credentials` | ![Done](https://img.shields.io/badge/status-done-brightgreen) |
8787
| `portainer_cloud_provider_provision` | ![Done](https://img.shields.io/badge/status-done-brightgreen) |
8888
| `portainer_compose_convert` | ![Done](https://img.shields.io/badge/status-done-brightgreen) |
89+
| `portainer_deploy` | ![Done](https://img.shields.io/badge/status-done-brightgreen) |
90+
| `portainer_check` | ![Done](https://img.shields.io/badge/status-done-brightgreen) |
8991
| `portainer_container_exec` | ![Done](https://img.shields.io/badge/status-done-brightgreen) |
9092
| `portainer_custom_template` | ![Done](https://img.shields.io/badge/status-done-brightgreen) |
9193
| `portainer_docker_config` | ![Done](https://img.shields.io/badge/status-done-brightgreen) |

docs/resources/auth.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The `portainer_auth` resource allows you to authenticate to the Portainer API us
55
It returns a JWT token that can be used for other API calls or debug purposes.
66

77
## Example Usage
8-
### Create Backup
8+
99
```hcl
1010
resource "portainer_auth" "login" {
1111
username = "admin"
@@ -18,6 +18,7 @@ output "jwt_token" {
1818
}
1919
```
2020
> ✅ Note: This resource does not persist anything in Portainer. It only returns a JWT token that can be used in subsequent API calls.
21+
- [Example on GitHub](https://github.com/portainer/terraform-provider-portainer/tree/main/examples/auth)
2122

2223
## Lifecycle & Behavior
2324
- This resource authenticates via the /auth API endpoint using username/password.

docs/resources/backup.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ The `portainer_backup` resource allows you to trigger a backup of your Portainer
66
The backup is encrypted using the password.
77

88
## Example Usage
9-
### Create Backup
10-
119
```hcl
12-
resource "portainer_backup" "your-backup" {
10+
resource "portainer_backup" "backup" {
1311
password = "your-backup-password"
14-
output_path = "your-backup-path-for-tar-gz-file"
12+
output_path = "backup.tar.gz"
1513
}
1614
```
15+
- [Example on GitHub](https://github.com/portainer/terraform-provider-portainer/tree/main/examples/backup)
1716

1817
## Lifecycle & Behavior
1918
This resource performs a one-time backup when applied. It does not manage state and will always re-trigger on each terraform apply.

docs/resources/backup_s3.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44
The `portainer_backup_s3` resource allows you to back up your Portainer instance to an AWS S3 bucket or compatible storage system.
55
> ⚠️ Note: This resource performs a one-time backup upload on every terraform apply. It is not stateful and will always re-trigger.
66
7+
> Currently working only for Portainer BE edition
8+
79
## Example Usage
8-
### Create Backup
910

1011
```hcl
11-
resource "portainer_backup" "your-backup" {
12-
password = "your-backup-password"
13-
output_path = "your-backup-path-for-tar-gz-file"
12+
resource "portainer_backup_s3" "s3_backup" {
13+
access_key_id = "s3_access_key"
14+
secret_access_key = "s3_secret_key"
15+
bucket_name = "s3_bucket"
16+
region = "s3_region"
17+
s3_compatible_host = "s3_endpoint"
18+
password = "backup_password"
19+
cron_rule = var.backup_cron_rule # optional
1420
}
1521
```
22+
- [Example on GitHub](https://github.com/portainer/terraform-provider-portainer/tree/main/examples/backup_s3)
1623

1724
## Lifecycle & Behavior
1825
This resource does not track state — it performs a one-time backup to the specified S3 bucket every time terraform apply runs.

docs/resources/chat.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## Overview
44
The `portainer_chat` resource allows you to send a query to Portainer’s integrated OpenAI assistant (if enabled). It supports providing context and environment-specific prompts, and retrieves an AI-generated YAML or message.
55

6+
> Currently working only for Portainer BE edition
7+
68
---
79

810
## 📘 Example Usage
@@ -46,7 +48,7 @@ Note: The resource ID is synthetic (`chat-{environment_id}`) and not persisted r
4648
| `context` | string | ✅ yes | Context of the query (e.g. `environment_aware`) |
4749
| `environment_id` | number | ✅ yes | ID of the Portainer environment |
4850
| `message` | string | ✅ yes | The natural language prompt to send to OpenAI |
49-
| `model` | string | 🚫 no | The OpenAI model to use (e.g. `gpt-3.5-turbo`, `gpt-4`) |
51+
| `model` | string | 🚫 optional | The OpenAI model to use (e.g. `gpt-3.5-turbo`, `gpt-4`) |
5052

5153
---
5254

docs/resources/check.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# **Resource Documentation: `portainer_check`**
2+
3+
# portainer_check
4+
5+
The `portainer_check` resource validates that one or more containers (in standalone mode) or services (in swarm mode) are running with the **expected image revision (tag)** and **desired runtime state** in a Portainer-managed environment.
6+
7+
> You can use it in both **Docker Standalone** and **Docker Swarm** deployments.
8+
> It’s especially useful for CI/CD pipelines to verify that a deployment or update has completed successfully before proceeding to the next step.
9+
10+
---
11+
12+
## 🚀 Example Usage
13+
- [Example on GitHub](https://github.com/portainer/terraform-provider-portainer/tree/main/examples/deployment)
14+
15+
### ✅ Check service status in Docker Swarm
16+
17+
```hcl
18+
resource "portainer_check" "swarm_check" {
19+
endpoint_id = 1
20+
stack_name = "my-swarm-stack"
21+
services_list = "web,api"
22+
revision = "1.29"
23+
desired_state = "running"
24+
max_retries = 3
25+
wait = 10
26+
wait_between_checks = 5
27+
}
28+
```
29+
30+
### ✅ Check container status in Docker Standalone
31+
32+
```hcl
33+
resource "portainer_check" "standalone_check" {
34+
endpoint_id = 1
35+
stack_name = "nginx"
36+
services_list = "web"
37+
revision = "1.29"
38+
desired_state = "running"
39+
wait = 10
40+
max_retries = 3
41+
wait_between_checks = 5
42+
}
43+
```
44+
45+
---
46+
47+
## ⚙️ Lifecycle & Behavior
48+
49+
This resource is **stateless** — it performs runtime verification during `terraform apply` (or `tofu apply` for OpenTofu) and does **not** persist state in Portainer.
50+
51+
When executed:
52+
53+
1. It waits for the optional `wait` period before starting.
54+
2. It determines whether the target environment is **Swarm** or **Standalone**.
55+
3. It checks the matching services or containers for:
56+
57+
* Correct **image tag** (`revision`)
58+
* Correct **state** (e.g., `running`)
59+
4. If all targets match → ✅ success.
60+
Otherwise → ❌ fails after `max_retries`.
61+
62+
> 💡 **Pro Tip:** Combine `portainer_check` after a `portainer_deploy` or `portainer_container_exec` to ensure deployment integrity.
63+
64+
---
65+
66+
## 📥 Arguments Reference
67+
68+
| Name | Type | Required | Description |
69+
| --------------------- | ------ | --------------------------------- | ------------------------------------------------------------------------------------- |
70+
| `endpoint_id` | int | ✅ yes | ID of the Portainer environment (endpoint) where the stack or containers are located. |
71+
| `stack_name` | string | ✅ yes | Name of the stack to which the containers or services belong. |
72+
| `revision` | string | ✅ yes | Expected image tag (e.g., `"1.29"`) that should be currently running. |
73+
| `services_list` | string | ✅ yes | Comma-separated list of service names (without stack prefix). Example: `"web,api"`. |
74+
| `desired_state` | string | 🚫 optional (default `"running"`) | Desired container/service state. Usually `"running"`. |
75+
| `wait` | int | 🚫 optional (default `30`) | Seconds to wait before performing the first check (useful after deploy). |
76+
| `wait_between_checks` | int | 🚫 optional (default `30`) | Delay (in seconds) between each retry attempt. |
77+
| `max_retries` | int | 🚫 optional (default `3`) | Number of retry attempts before failing the check. |
78+
79+
---
80+
81+
## 📤 Attributes Reference
82+
83+
| Name | Description |
84+
| -------- | --------------------------------------------------------------------------------------------------------------- |
85+
| `id` | Auto-generated ID of the check execution (stateless). |
86+
| `output` | The complete textual output of the verification process, including matched containers, retries, and debug info. |
87+
88+
---
89+
90+
## 🧩 Example with Outputs
91+
92+
```hcl
93+
output "check_result" {
94+
value = portainer_check.standalone_check.output
95+
}
96+
```
97+
98+
This will show you a detailed report like:
99+
100+
```
101+
Docker Standalone detected — using container check logic.
102+
DEBUG: checking container="nginx-web-1" (image="nginx:1.29", state="running")
103+
Container "nginx-web-1" OK — revision "1.29", state "running"
104+
```
105+
106+
---
107+
108+
## 🧠 Summary
109+
110+
| Feature | Description |
111+
| ----------- | -------------------------------------------------------------------- |
112+
| Mode | Works in **Standalone** and **Swarm** environments |
113+
| Purpose | Ensures containers/services run with the correct image tag and state |
114+
| Behavior | Stateless verification (no Portainer state change) |
115+
| Typical Use | Post-deployment validation in CI/CD pipelines |

docs/resources/cloud_credentials.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
# portainer_cloud_credentials
44
The `portainer_cloud_credentials` resource allows you to provision cloud credentials in Portainer for use with providers like AWS, DigitalOcean, Civo, etc.
55

6+
> Currently working only for Portainer BE edition
7+
68
## Example Usage
9+
- [Example on GitHub](https://github.com/portainer/terraform-provider-portainer/tree/main/examples/cloud_credentials)
10+
711
```hcl
812
resource "portainer_cloud_credentials" "example" {
913
name = "example-aws-creds"
@@ -39,7 +43,7 @@ terraform apply
3943
| **Name** | **Type** | **Required** | **Description** |
4044
|---------------|----------|--------------|----------------------------------------------------------------------------|
4145
| `name` | string | ✅ yes | Human-readable name for the cloud credentials |
42-
| `provider` | string | ✅ yes | Provider name (`aws`, `digitalocean`, `civo`, `gcp`, etc.) |
46+
| `cloud_provider`| string | ✅ yes | Provider name (`aws`, `digitalocean`, `civo`, `gcp`, etc.) |
4347
| `credentials` | string | ✅ yes | JSON-encoded credentials payload (use `jsonencode({ ... })`) |
4448

4549
## Attributes Reference

0 commit comments

Comments
 (0)